aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-25 14:17:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-25 14:17:34 -0500
commit4ba9920e5e9c0e16b5ed24292d45322907bb9035 (patch)
tree7d023baea59ed0886ded1f0b6d1c6385690b88f7 /drivers/net/wireless
parent82c477669a4665eb4e52030792051e0559ee2a36 (diff)
parent8b662fe70c68282f78482dc272df0c4f355e49f5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) BPF debugger and asm tool by Daniel Borkmann. 2) Speed up create/bind in AF_PACKET, also from Daniel Borkmann. 3) Correct reciprocal_divide and update users, from Hannes Frederic Sowa and Daniel Borkmann. 4) Currently we only have a "set" operation for the hw timestamp socket ioctl, add a "get" operation to match. From Ben Hutchings. 5) Add better trace events for debugging driver datapath problems, also from Ben Hutchings. 6) Implement auto corking in TCP, from Eric Dumazet. Basically, if we have a small send and a previous packet is already in the qdisc or device queue, defer until TX completion or we get more data. 7) Allow userspace to manage ipv6 temporary addresses, from Jiri Pirko. 8) Add a qdisc bypass option for AF_PACKET sockets, from Daniel Borkmann. 9) Share IP header compression code between Bluetooth and IEEE802154 layers, from Jukka Rissanen. 10) Fix ipv6 router reachability probing, from Jiri Benc. 11) Allow packets to be captured on macvtap devices, from Vlad Yasevich. 12) Support tunneling in GRO layer, from Jerry Chu. 13) Allow bonding to be configured fully using netlink, from Scott Feldman. 14) Allow AF_PACKET users to obtain the VLAN TPID, just like they can already get the TCI. From Atzm Watanabe. 15) New "Heavy Hitter" qdisc, from Terry Lam. 16) Significantly improve the IPSEC support in pktgen, from Fan Du. 17) Allow ipv4 tunnels to cache routes, just like sockets. From Tom Herbert. 18) Add Proportional Integral Enhanced packet scheduler, from Vijay Subramanian. 19) Allow openvswitch to mmap'd netlink, from Thomas Graf. 20) Key TCP metrics blobs also by source address, not just destination address. From Christoph Paasch. 21) Support 10G in generic phylib. From Andy Fleming. 22) Try to short-circuit GRO flow compares using device provided RX hash, if provided. From Tom Herbert. The wireless and netfilter folks have been busy little bees too. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2064 commits) net/cxgb4: Fix referencing freed adapter ipv6: reallocate addrconf router for ipv6 address when lo device up fib_frontend: fix possible NULL pointer dereference rtnetlink: remove IFLA_BOND_SLAVE definition rtnetlink: remove check for fill_slave_info in rtnl_have_link_slave_info qlcnic: update version to 5.3.55 qlcnic: Enhance logic to calculate msix vectors. qlcnic: Refactor interrupt coalescing code for all adapters. qlcnic: Update poll controller code path qlcnic: Interrupt code cleanup qlcnic: Enhance Tx timeout debugging. qlcnic: Use bool for rx_mac_learn. bonding: fix u64 division rtnetlink: add missing IFLA_BOND_AD_INFO_UNSPEC sfc: Use the correct maximum TX DMA ring size for SFC9100 Add Shradha Shah as the sfc driver maintainer. net/vxlan: Share RX skb de-marking and checksum checks with ovs tulip: cleanup by using ARRAY_SIZE() ip_tunnel: clear IPCB in ip_tunnel_xmit() in case dst_link_failure() is called net/cxgb4: Don't retrieve stats during recovery ...
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/adm8211.c4
-rw-r--r--drivers/net/wireless/airo_cs.c1
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c1
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig7
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c53
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c43
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h34
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c160
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c31
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c40
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c11
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c677
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c791
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h14
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h21
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c408
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h157
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c34
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c11
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c11
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig18
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile14
-rw-r--r--drivers/net/wireless/ath/ath9k/antenna.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h222
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h126
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c385
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c65
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c297
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c106
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h24
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c422
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h128
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h401
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9340_initvals.h392
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h575
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h1559
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h117
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h718
-rw-r--r--drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h540
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h85
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h64
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h572
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h434
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c147
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c632
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h44
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c269
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c89
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c39
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h47
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c608
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h75
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c72
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c67
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c51
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c671
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c134
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c247
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.c543
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.h212
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c272
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c588
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c27
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c1
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c13
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c14
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c1
-rw-r--r--drivers/net/wireless/ath/main.c8
-rw-r--r--drivers/net/wireless/ath/regd.c379
-rw-r--r--drivers/net/wireless/ath/wcn36xx/hal.h2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c3
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c65
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h2
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c13
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h1
-rw-r--r--drivers/net/wireless/atmel.c8
-rw-r--r--drivers/net/wireless/atmel.h4
-rw-r--r--drivers/net/wireless/atmel_cs.c5
-rw-r--r--drivers/net/wireless/atmel_pci.c5
-rw-r--r--drivers/net/wireless/b43/b43.h4
-rw-r--r--drivers/net/wireless/b43/main.c27
-rw-r--r--drivers/net/wireless/b43/xmit.c4
-rw-r--r--drivers/net/wireless/b43legacy/main.c1
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c375
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c737
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c539
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h487
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h44
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c392
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c31
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c36
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c207
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c1596
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h54
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c19
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h61
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h304
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c216
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/nvram.c94
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/nvram.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c52
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c62
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c827
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h39
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h83
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c9
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c194
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c38
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c67
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h1
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h14
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c4
-rw-r--r--drivers/net/wireless/cw1200/fwio.c1
-rw-r--r--drivers/net/wireless/cw1200/main.c2
-rw-r--r--drivers/net/wireless/cw1200/pm.c11
-rw-r--r--drivers/net/wireless/cw1200/scan.c15
-rw-r--r--drivers/net/wireless/cw1200/sta.c5
-rw-r--r--drivers/net/wireless/cw1200/txrx.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c28
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c6
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c5
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c42
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h1
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c12
-rw-r--r--drivers/net/wireless/iwlegacy/3945-debug.c6
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c11
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c1
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c5
-rw-r--r--drivers/net/wireless/iwlegacy/4965-debug.c6
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c8
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c1
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c1
-rw-r--r--drivers/net/wireless/iwlegacy/common.c13
-rw-r--r--drivers/net/wireless/iwlegacy/debug.c10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c18
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.h9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h87
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c57
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c546
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c689
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h69
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c211
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c342
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h63
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c51
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c28
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c400
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power_legacy.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c2192
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h154
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c72
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c291
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/testmode.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c21
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c9
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h65
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c437
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c183
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c172
-rw-r--r--drivers/net/wireless/libertas/README5
-rw-r--r--drivers/net/wireless/libertas/cfg.c7
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c6
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c1213
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h18
-rw-r--r--drivers/net/wireless/mwifiex/11n.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c6
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig4
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c70
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c4
-rw-r--r--drivers/net/wireless/mwifiex/decl.h1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h41
-rw-r--r--drivers/net/wireless/mwifiex/init.c3
-rw-r--r--drivers/net/wireless/mwifiex/main.c11
-rw-r--r--drivers/net/wireless/mwifiex/main.h7
-rw-r--r--drivers/net/wireless/mwifiex/scan.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c80
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c38
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c20
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c46
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c1
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c15
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c39
-rw-r--r--drivers/net/wireless/mwifiex/usb.c58
-rw-r--r--drivers/net/wireless/mwifiex/usb.h12
-rw-r--r--drivers/net/wireless/mwifiex/util.c5
-rw-r--r--drivers/net/wireless/mwl8k.c5
-rw-r--r--drivers/net/wireless/orinoco/hermes.c1
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c1
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c1
-rw-r--r--drivers/net/wireless/p54/eeprom.c1
-rw-r--r--drivers/net/wireless/p54/fwio.c1
-rw-r--r--drivers/net/wireless/p54/led.c1
-rw-r--r--drivers/net/wireless/p54/main.c2
-rw-r--r--drivers/net/wireless/p54/net2280.h3
-rw-r--r--drivers/net/wireless/p54/p54pci.c1
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/p54/txrx.c5
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c3
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h3
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c6
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h3
-rw-r--r--drivers/net/wireless/prism54/isl_oid.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c4
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c5
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h3
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c3
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.h3
-rw-r--r--drivers/net/wireless/prism54/prismcompat.h3
-rw-r--r--drivers/net/wireless/ray_cs.c3
-rw-r--r--drivers/net/wireless/rndis_wlan.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c41
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800mmio.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800mmio.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800soc.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/grf5101.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/max2820.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/sa2400.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c3
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.c1
-rw-r--r--drivers/net/wireless/rtlwifi/base.c8
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c4
-rw-r--r--drivers/net/wireless/rtlwifi/core.c11
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c2
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c4
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c327
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.c9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c29
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c17
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/table.c40
-rw-r--r--drivers/net/wireless/rtlwifi/stats.c14
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c8
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h33
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c258
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.h26
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.c3
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c58
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.h8
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c46
-rw-r--r--drivers/net/wireless/ti/wl1251/event.h7
-rw-r--r--drivers/net/wireless/ti/wl1251/init.c13
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c153
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c2
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.c35
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h6
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c14
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c12
-rw-r--r--drivers/net/wireless/wl3501_cs.c5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c8
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h3
438 files changed, 17809 insertions, 14911 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index cfce83e1f273..f35f93c31b09 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -15,7 +15,6 @@
15 * more details. 15 * more details.
16 */ 16 */
17 17
18#include <linux/init.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/if.h> 19#include <linux/if.h>
21#include <linux/skbuff.h> 20#include <linux/skbuff.h>
@@ -1314,7 +1313,7 @@ static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
1314 if (!(changes & BSS_CHANGED_BSSID)) 1313 if (!(changes & BSS_CHANGED_BSSID))
1315 return; 1314 return;
1316 1315
1317 if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) { 1316 if (!ether_addr_equal(conf->bssid, priv->bssid)) {
1318 adm8211_set_bssid(dev, conf->bssid); 1317 adm8211_set_bssid(dev, conf->bssid);
1319 memcpy(priv->bssid, conf->bssid, ETH_ALEN); 1318 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
1320 } 1319 }
@@ -1866,7 +1865,6 @@ static int adm8211_probe(struct pci_dev *pdev,
1866 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; 1865 dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
1867 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1866 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1868 1867
1869 dev->channel_change_time = 1000;
1870 dev->max_signal = 100; /* FIXME: find better value */ 1868 dev->max_signal = 100; /* FIXME: find better value */
1871 1869
1872 dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ 1870 dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 14128fd265ac..7e9ede6c5798 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -23,7 +23,6 @@
23#ifdef __IN_PCMCIA_PACKAGE__ 23#ifdef __IN_PCMCIA_PACKAGE__
24#include <pcmcia/k_compat.h> 24#include <pcmcia/k_compat.h>
25#endif 25#endif
26#include <linux/init.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/ptrace.h> 28#include <linux/ptrace.h>
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 34c8a33cac06..99b3bfa717d5 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1721,7 +1721,7 @@ static void at76_mac80211_tx(struct ieee80211_hw *hw,
1721 * following workaround is necessary. If the TX frame is an 1721 * following workaround is necessary. If the TX frame is an
1722 * authentication frame extract the bssid and send the CMD_JOIN. */ 1722 * authentication frame extract the bssid and send the CMD_JOIN. */
1723 if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { 1723 if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) {
1724 if (!ether_addr_equal(priv->bssid, mgmt->bssid)) { 1724 if (!ether_addr_equal_64bits(priv->bssid, mgmt->bssid)) {
1725 memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); 1725 memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
1726 ieee80211_queue_work(hw, &priv->work_join_bssid); 1726 ieee80211_queue_work(hw, &priv->work_join_bssid);
1727 dev_kfree_skb_any(skb); 1727 dev_kfree_skb_any(skb);
@@ -2112,7 +2112,6 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
2112 priv->pm_period = 0; 2112 priv->pm_period = 0;
2113 2113
2114 /* unit us */ 2114 /* unit us */
2115 priv->hw->channel_change_time = 100000;
2116 2115
2117 return priv; 2116 return priv;
2118} 2117}
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 280fc3d53a36..8aa20df55e50 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -25,7 +25,6 @@
25 * that and only has minimal functionality. 25 * that and only has minimal functionality.
26 */ 26 */
27#include <linux/compiler.h> 27#include <linux/compiler.h>
28#include <linux/init.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/list.h> 30#include <linux/list.h>
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index e0ba7cd14252..b59cfbe0276b 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -17,6 +17,7 @@
17#ifndef ATH_H 17#ifndef ATH_H
18#define ATH_H 18#define ATH_H
19 19
20#include <linux/etherdevice.h>
20#include <linux/skbuff.h> 21#include <linux/skbuff.h>
21#include <linux/if_ether.h> 22#include <linux/if_ether.h>
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
@@ -165,6 +166,7 @@ struct ath_common {
165struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 166struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
166 u32 len, 167 u32 len,
167 gfp_t gfp_mask); 168 gfp_t gfp_mask);
169bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr);
168 170
169void ath_hw_setbssidmask(struct ath_common *common); 171void ath_hw_setbssidmask(struct ath_common *common);
170void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); 172void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index 82e8088ca9b4..a6f5285235af 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -37,3 +37,10 @@ config ATH10K_TRACING
37 ---help--- 37 ---help---
38 Select this to ath10k use tracing infrastructure. 38 Select this to ath10k use tracing infrastructure.
39 39
40config ATH10K_DFS_CERTIFIED
41 bool "Atheros DFS support for certified platforms"
42 depends on ATH10K && CFG80211_CERTIFICATION_ONUS
43 default n
44 ---help---
45 This option enables DFS support for initiating radiation on
46 ath10k.
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index e46951b8fb92..d44d618b05f9 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -243,6 +243,16 @@ static inline void ath10k_ce_error_intr_enable(struct ath10k *ar,
243 misc_ie_addr | CE_ERROR_MASK); 243 misc_ie_addr | CE_ERROR_MASK);
244} 244}
245 245
246static inline void ath10k_ce_error_intr_disable(struct ath10k *ar,
247 u32 ce_ctrl_addr)
248{
249 u32 misc_ie_addr = ath10k_pci_read32(ar,
250 ce_ctrl_addr + MISC_IE_ADDRESS);
251
252 ath10k_pci_write32(ar, ce_ctrl_addr + MISC_IE_ADDRESS,
253 misc_ie_addr & ~CE_ERROR_MASK);
254}
255
246static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, 256static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
247 u32 ce_ctrl_addr, 257 u32 ce_ctrl_addr,
248 unsigned int mask) 258 unsigned int mask)
@@ -731,7 +741,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
731 741
732void ath10k_ce_per_engine_service_any(struct ath10k *ar) 742void ath10k_ce_per_engine_service_any(struct ath10k *ar)
733{ 743{
734 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
735 int ce_id, ret; 744 int ce_id, ret;
736 u32 intr_summary; 745 u32 intr_summary;
737 746
@@ -741,7 +750,7 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
741 750
742 intr_summary = CE_INTERRUPT_SUMMARY(ar); 751 intr_summary = CE_INTERRUPT_SUMMARY(ar);
743 752
744 for (ce_id = 0; intr_summary && (ce_id < ar_pci->ce_count); ce_id++) { 753 for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) {
745 if (intr_summary & (1 << ce_id)) 754 if (intr_summary & (1 << ce_id))
746 intr_summary &= ~(1 << ce_id); 755 intr_summary &= ~(1 << ce_id);
747 else 756 else
@@ -783,22 +792,25 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
783 ath10k_pci_sleep(ar); 792 ath10k_pci_sleep(ar);
784} 793}
785 794
786void ath10k_ce_disable_interrupts(struct ath10k *ar) 795int ath10k_ce_disable_interrupts(struct ath10k *ar)
787{ 796{
788 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
789 int ce_id, ret; 797 int ce_id, ret;
790 798
791 ret = ath10k_pci_wake(ar); 799 ret = ath10k_pci_wake(ar);
792 if (ret) 800 if (ret)
793 return; 801 return ret;
794 802
795 for (ce_id = 0; ce_id < ar_pci->ce_count; ce_id++) { 803 for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
796 struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; 804 u32 ctrl_addr = ath10k_ce_base_address(ce_id);
797 u32 ctrl_addr = ce_state->ctrl_addr;
798 805
799 ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); 806 ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
807 ath10k_ce_error_intr_disable(ar, ctrl_addr);
808 ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
800 } 809 }
810
801 ath10k_pci_sleep(ar); 811 ath10k_pci_sleep(ar);
812
813 return 0;
802} 814}
803 815
804void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, 816void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
@@ -1047,9 +1059,19 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
1047 const struct ce_attr *attr) 1059 const struct ce_attr *attr)
1048{ 1060{
1049 struct ath10k_ce_pipe *ce_state; 1061 struct ath10k_ce_pipe *ce_state;
1050 u32 ctrl_addr = ath10k_ce_base_address(ce_id);
1051 int ret; 1062 int ret;
1052 1063
1064 /*
1065 * Make sure there's enough CE ringbuffer entries for HTT TX to avoid
1066 * additional TX locking checks.
1067 *
1068 * For the lack of a better place do the check here.
1069 */
1070 BUILD_BUG_ON(TARGET_NUM_MSDU_DESC >
1071 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
1072 BUILD_BUG_ON(TARGET_10X_NUM_MSDU_DESC >
1073 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
1074
1053 ret = ath10k_pci_wake(ar); 1075 ret = ath10k_pci_wake(ar);
1054 if (ret) 1076 if (ret)
1055 return NULL; 1077 return NULL;
@@ -1057,7 +1079,7 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
1057 ce_state = ath10k_ce_init_state(ar, ce_id, attr); 1079 ce_state = ath10k_ce_init_state(ar, ce_id, attr);
1058 if (!ce_state) { 1080 if (!ce_state) {
1059 ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id); 1081 ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
1060 return NULL; 1082 goto out;
1061 } 1083 }
1062 1084
1063 if (attr->src_nentries) { 1085 if (attr->src_nentries) {
@@ -1066,7 +1088,8 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
1066 ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", 1088 ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
1067 ce_id, ret); 1089 ce_id, ret);
1068 ath10k_ce_deinit(ce_state); 1090 ath10k_ce_deinit(ce_state);
1069 return NULL; 1091 ce_state = NULL;
1092 goto out;
1070 } 1093 }
1071 } 1094 }
1072 1095
@@ -1076,15 +1099,13 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
1076 ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", 1099 ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
1077 ce_id, ret); 1100 ce_id, ret);
1078 ath10k_ce_deinit(ce_state); 1101 ath10k_ce_deinit(ce_state);
1079 return NULL; 1102 ce_state = NULL;
1103 goto out;
1080 } 1104 }
1081 } 1105 }
1082 1106
1083 /* Enable CE error interrupts */ 1107out:
1084 ath10k_ce_error_intr_enable(ar, ctrl_addr);
1085
1086 ath10k_pci_sleep(ar); 1108 ath10k_pci_sleep(ar);
1087
1088 return ce_state; 1109 return ce_state;
1089} 1110}
1090 1111
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index 15d45b5b7615..67dbde6a5c74 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -234,7 +234,7 @@ void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state);
234/*==================CE Interrupt Handlers====================*/ 234/*==================CE Interrupt Handlers====================*/
235void ath10k_ce_per_engine_service_any(struct ath10k *ar); 235void ath10k_ce_per_engine_service_any(struct ath10k *ar);
236void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); 236void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
237void ath10k_ce_disable_interrupts(struct ath10k *ar); 237int ath10k_ce_disable_interrupts(struct ath10k *ar);
238 238
239/* ce_attr.flags values */ 239/* ce_attr.flags values */
240/* Use NonSnooping PCIe accesses? */ 240/* Use NonSnooping PCIe accesses? */
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 1129994fb105..3b59af3bddf4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -597,10 +597,8 @@ static int ath10k_init_uart(struct ath10k *ar)
597 return ret; 597 return ret;
598 } 598 }
599 599
600 if (!uart_print) { 600 if (!uart_print)
601 ath10k_info("UART prints disabled\n");
602 return 0; 601 return 0;
603 }
604 602
605 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); 603 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7);
606 if (ret) { 604 if (ret) {
@@ -645,8 +643,8 @@ static int ath10k_init_hw_params(struct ath10k *ar)
645 643
646 ar->hw_params = *hw_params; 644 ar->hw_params = *hw_params;
647 645
648 ath10k_info("Hardware name %s version 0x%x\n", 646 ath10k_dbg(ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
649 ar->hw_params.name, ar->target_version); 647 ar->hw_params.name, ar->target_version);
650 648
651 return 0; 649 return 0;
652} 650}
@@ -664,7 +662,8 @@ static void ath10k_core_restart(struct work_struct *work)
664 ieee80211_restart_hw(ar->hw); 662 ieee80211_restart_hw(ar->hw);
665 break; 663 break;
666 case ATH10K_STATE_OFF: 664 case ATH10K_STATE_OFF:
667 /* this can happen if driver is being unloaded */ 665 /* this can happen if driver is being unloaded
666 * or if the crash happens during FW probing */
668 ath10k_warn("cannot restart a device that hasn't been started\n"); 667 ath10k_warn("cannot restart a device that hasn't been started\n");
669 break; 668 break;
670 case ATH10K_STATE_RESTARTING: 669 case ATH10K_STATE_RESTARTING:
@@ -737,8 +736,6 @@ EXPORT_SYMBOL(ath10k_core_create);
737 736
738void ath10k_core_destroy(struct ath10k *ar) 737void ath10k_core_destroy(struct ath10k *ar)
739{ 738{
740 ath10k_debug_destroy(ar);
741
742 flush_workqueue(ar->workqueue); 739 flush_workqueue(ar->workqueue);
743 destroy_workqueue(ar->workqueue); 740 destroy_workqueue(ar->workqueue);
744 741
@@ -786,21 +783,30 @@ int ath10k_core_start(struct ath10k *ar)
786 goto err; 783 goto err;
787 } 784 }
788 785
789 status = ath10k_htc_wait_target(&ar->htc); 786 status = ath10k_hif_start(ar);
790 if (status) 787 if (status) {
788 ath10k_err("could not start HIF: %d\n", status);
791 goto err_wmi_detach; 789 goto err_wmi_detach;
790 }
791
792 status = ath10k_htc_wait_target(&ar->htc);
793 if (status) {
794 ath10k_err("failed to connect to HTC: %d\n", status);
795 goto err_hif_stop;
796 }
792 797
793 status = ath10k_htt_attach(ar); 798 status = ath10k_htt_attach(ar);
794 if (status) { 799 if (status) {
795 ath10k_err("could not attach htt (%d)\n", status); 800 ath10k_err("could not attach htt (%d)\n", status);
796 goto err_wmi_detach; 801 goto err_hif_stop;
797 } 802 }
798 803
799 status = ath10k_init_connect_htc(ar); 804 status = ath10k_init_connect_htc(ar);
800 if (status) 805 if (status)
801 goto err_htt_detach; 806 goto err_htt_detach;
802 807
803 ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version); 808 ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n",
809 ar->hw->wiphy->fw_version);
804 810
805 status = ath10k_wmi_cmd_init(ar); 811 status = ath10k_wmi_cmd_init(ar);
806 if (status) { 812 if (status) {
@@ -826,12 +832,23 @@ int ath10k_core_start(struct ath10k *ar)
826 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; 832 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
827 INIT_LIST_HEAD(&ar->arvifs); 833 INIT_LIST_HEAD(&ar->arvifs);
828 834
835 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
836 ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n",
837 ar->hw_params.name, ar->target_version,
838 ar->hw->wiphy->fw_version, ar->fw_api,
839 ar->htt.target_version_major,
840 ar->htt.target_version_minor);
841
842 __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
843
829 return 0; 844 return 0;
830 845
831err_disconnect_htc: 846err_disconnect_htc:
832 ath10k_htc_stop(&ar->htc); 847 ath10k_htc_stop(&ar->htc);
833err_htt_detach: 848err_htt_detach:
834 ath10k_htt_detach(&ar->htt); 849 ath10k_htt_detach(&ar->htt);
850err_hif_stop:
851 ath10k_hif_stop(ar);
835err_wmi_detach: 852err_wmi_detach:
836 ath10k_wmi_detach(ar); 853 ath10k_wmi_detach(ar);
837err: 854err:
@@ -985,6 +1002,8 @@ void ath10k_core_unregister(struct ath10k *ar)
985 ath10k_mac_unregister(ar); 1002 ath10k_mac_unregister(ar);
986 1003
987 ath10k_core_free_firmware_files(ar); 1004 ath10k_core_free_firmware_files(ar);
1005
1006 ath10k_debug_destroy(ar);
988} 1007}
989EXPORT_SYMBOL(ath10k_core_unregister); 1008EXPORT_SYMBOL(ath10k_core_unregister);
990 1009
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 0934f7633de3..ade1781c7186 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -30,6 +30,7 @@
30#include "wmi.h" 30#include "wmi.h"
31#include "../ath.h" 31#include "../ath.h"
32#include "../regd.h" 32#include "../regd.h"
33#include "../dfs_pattern_detector.h"
33 34
34#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) 35#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
35#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) 36#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -43,7 +44,7 @@
43/* Antenna noise floor */ 44/* Antenna noise floor */
44#define ATH10K_DEFAULT_NOISE_FLOOR -95 45#define ATH10K_DEFAULT_NOISE_FLOOR -95
45 46
46#define ATH10K_MAX_NUM_MGMT_PENDING 16 47#define ATH10K_MAX_NUM_MGMT_PENDING 128
47 48
48struct ath10k; 49struct ath10k;
49 50
@@ -192,6 +193,14 @@ struct ath10k_target_stats {
192 193
193}; 194};
194 195
196struct ath10k_dfs_stats {
197 u32 phy_errors;
198 u32 pulses_total;
199 u32 pulses_detected;
200 u32 pulses_discarded;
201 u32 radar_detected;
202};
203
195#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */ 204#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */
196 205
197struct ath10k_peer { 206struct ath10k_peer {
@@ -244,6 +253,9 @@ struct ath10k_vif {
244 u8 bssid[ETH_ALEN]; 253 u8 bssid[ETH_ALEN];
245 } ibss; 254 } ibss;
246 } u; 255 } u;
256
257 u8 fixed_rate;
258 u8 fixed_nss;
247}; 259};
248 260
249struct ath10k_vif_iter { 261struct ath10k_vif_iter {
@@ -261,6 +273,10 @@ struct ath10k_debug {
261 273
262 unsigned long htt_stats_mask; 274 unsigned long htt_stats_mask;
263 struct delayed_work htt_stats_dwork; 275 struct delayed_work htt_stats_dwork;
276 struct ath10k_dfs_stats dfs_stats;
277 struct ath_dfs_pool_stats dfs_pool_stats;
278
279 u32 fw_dbglog_mask;
264}; 280};
265 281
266enum ath10k_state { 282enum ath10k_state {
@@ -295,10 +311,19 @@ enum ath10k_fw_features {
295 /* firmware support tx frame management over WMI, otherwise it's HTT */ 311 /* firmware support tx frame management over WMI, otherwise it's HTT */
296 ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2, 312 ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2,
297 313
314 /* Firmware does not support P2P */
315 ATH10K_FW_FEATURE_NO_P2P = 3,
316
298 /* keep last */ 317 /* keep last */
299 ATH10K_FW_FEATURE_COUNT, 318 ATH10K_FW_FEATURE_COUNT,
300}; 319};
301 320
321enum ath10k_dev_flags {
322 /* Indicates that ath10k device is during CAC phase of DFS */
323 ATH10K_CAC_RUNNING,
324 ATH10K_FLAG_FIRST_BOOT_DONE,
325};
326
302struct ath10k { 327struct ath10k {
303 struct ath_common ath_common; 328 struct ath_common ath_common;
304 struct ieee80211_hw *hw; 329 struct ieee80211_hw *hw;
@@ -392,6 +417,8 @@ struct ath10k {
392 bool monitor_enabled; 417 bool monitor_enabled;
393 bool monitor_present; 418 bool monitor_present;
394 unsigned int filter_flags; 419 unsigned int filter_flags;
420 unsigned long dev_flags;
421 u32 dfs_block_radar_events;
395 422
396 struct wmi_pdev_set_wmm_params_arg wmm_params; 423 struct wmi_pdev_set_wmm_params_arg wmm_params;
397 struct completion install_key_done; 424 struct completion install_key_done;
@@ -410,6 +437,9 @@ struct ath10k {
410 struct list_head peers; 437 struct list_head peers;
411 wait_queue_head_t peer_mapping_wq; 438 wait_queue_head_t peer_mapping_wq;
412 439
440 /* number of created peers; protected by data_lock */
441 int num_peers;
442
413 struct work_struct offchan_tx_work; 443 struct work_struct offchan_tx_work;
414 struct sk_buff_head offchan_tx_queue; 444 struct sk_buff_head offchan_tx_queue;
415 struct completion offchan_tx_completed; 445 struct completion offchan_tx_completed;
@@ -428,6 +458,8 @@ struct ath10k {
428 u32 survey_last_cycle_count; 458 u32 survey_last_cycle_count;
429 struct survey_info survey[ATH10K_NUM_CHANS]; 459 struct survey_info survey[ATH10K_NUM_CHANS];
430 460
461 struct dfs_pattern_detector *dfs_detector;
462
431#ifdef CONFIG_ATH10K_DEBUGFS 463#ifdef CONFIG_ATH10K_DEBUGFS
432 struct ath10k_debug debug; 464 struct ath10k_debug debug;
433#endif 465#endif
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 760ff2289e3c..6debd281350a 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -614,6 +614,61 @@ static const struct file_operations fops_htt_stats_mask = {
614 .llseek = default_llseek, 614 .llseek = default_llseek,
615}; 615};
616 616
617static ssize_t ath10k_read_fw_dbglog(struct file *file,
618 char __user *user_buf,
619 size_t count, loff_t *ppos)
620{
621 struct ath10k *ar = file->private_data;
622 unsigned int len;
623 char buf[32];
624
625 len = scnprintf(buf, sizeof(buf), "0x%08x\n",
626 ar->debug.fw_dbglog_mask);
627
628 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
629}
630
631static ssize_t ath10k_write_fw_dbglog(struct file *file,
632 const char __user *user_buf,
633 size_t count, loff_t *ppos)
634{
635 struct ath10k *ar = file->private_data;
636 unsigned long mask;
637 int ret;
638
639 ret = kstrtoul_from_user(user_buf, count, 0, &mask);
640 if (ret)
641 return ret;
642
643 mutex_lock(&ar->conf_mutex);
644
645 ar->debug.fw_dbglog_mask = mask;
646
647 if (ar->state == ATH10K_STATE_ON) {
648 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
649 if (ret) {
650 ath10k_warn("dbglog cfg failed from debugfs: %d\n",
651 ret);
652 goto exit;
653 }
654 }
655
656 ret = count;
657
658exit:
659 mutex_unlock(&ar->conf_mutex);
660
661 return ret;
662}
663
664static const struct file_operations fops_fw_dbglog = {
665 .read = ath10k_read_fw_dbglog,
666 .write = ath10k_write_fw_dbglog,
667 .open = simple_open,
668 .owner = THIS_MODULE,
669 .llseek = default_llseek,
670};
671
617int ath10k_debug_start(struct ath10k *ar) 672int ath10k_debug_start(struct ath10k *ar)
618{ 673{
619 int ret; 674 int ret;
@@ -625,6 +680,14 @@ int ath10k_debug_start(struct ath10k *ar)
625 /* continue normally anyway, this isn't serious */ 680 /* continue normally anyway, this isn't serious */
626 ath10k_warn("failed to start htt stats workqueue: %d\n", ret); 681 ath10k_warn("failed to start htt stats workqueue: %d\n", ret);
627 682
683 if (ar->debug.fw_dbglog_mask) {
684 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
685 if (ret)
686 /* not serious */
687 ath10k_warn("failed to enable dbglog during start: %d",
688 ret);
689 }
690
628 return 0; 691 return 0;
629} 692}
630 693
@@ -639,6 +702,86 @@ void ath10k_debug_stop(struct ath10k *ar)
639 cancel_delayed_work(&ar->debug.htt_stats_dwork); 702 cancel_delayed_work(&ar->debug.htt_stats_dwork);
640} 703}
641 704
705static ssize_t ath10k_write_simulate_radar(struct file *file,
706 const char __user *user_buf,
707 size_t count, loff_t *ppos)
708{
709 struct ath10k *ar = file->private_data;
710
711 ieee80211_radar_detected(ar->hw);
712
713 return count;
714}
715
716static const struct file_operations fops_simulate_radar = {
717 .write = ath10k_write_simulate_radar,
718 .open = simple_open,
719 .owner = THIS_MODULE,
720 .llseek = default_llseek,
721};
722
723#define ATH10K_DFS_STAT(s, p) (\
724 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
725 ar->debug.dfs_stats.p))
726
727#define ATH10K_DFS_POOL_STAT(s, p) (\
728 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
729 ar->debug.dfs_pool_stats.p))
730
731static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
732 size_t count, loff_t *ppos)
733{
734 int retval = 0, len = 0;
735 const int size = 8000;
736 struct ath10k *ar = file->private_data;
737 char *buf;
738
739 buf = kzalloc(size, GFP_KERNEL);
740 if (buf == NULL)
741 return -ENOMEM;
742
743 if (!ar->dfs_detector) {
744 len += scnprintf(buf + len, size - len, "DFS not enabled\n");
745 goto exit;
746 }
747
748 ar->debug.dfs_pool_stats =
749 ar->dfs_detector->get_stats(ar->dfs_detector);
750
751 len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
752
753 ATH10K_DFS_STAT("reported phy errors", phy_errors);
754 ATH10K_DFS_STAT("pulse events reported", pulses_total);
755 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
756 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
757 ATH10K_DFS_STAT("Radars detected", radar_detected);
758
759 len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
760 ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
761 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
762 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
763 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
764 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
765 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
766 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
767
768exit:
769 if (len > size)
770 len = size;
771
772 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
773 kfree(buf);
774
775 return retval;
776}
777
778static const struct file_operations fops_dfs_stats = {
779 .read = ath10k_read_dfs_stats,
780 .open = simple_open,
781 .owner = THIS_MODULE,
782 .llseek = default_llseek,
783};
784
642int ath10k_debug_create(struct ath10k *ar) 785int ath10k_debug_create(struct ath10k *ar)
643{ 786{
644 ar->debug.debugfs_phy = debugfs_create_dir("ath10k", 787 ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
@@ -667,6 +810,23 @@ int ath10k_debug_create(struct ath10k *ar)
667 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, 810 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
668 ar, &fops_htt_stats_mask); 811 ar, &fops_htt_stats_mask);
669 812
813 debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
814 ar, &fops_fw_dbglog);
815
816 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
817 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
818 ar->debug.debugfs_phy, ar,
819 &fops_simulate_radar);
820
821 debugfs_create_bool("dfs_block_radar_events", S_IWUSR,
822 ar->debug.debugfs_phy,
823 &ar->dfs_block_radar_events);
824
825 debugfs_create_file("dfs_stats", S_IRUSR,
826 ar->debug.debugfs_phy, ar,
827 &fops_dfs_stats);
828 }
829
670 return 0; 830 return 0;
671} 831}
672 832
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 3cfe3ee90dbe..1773c36c71a0 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -33,6 +33,7 @@ enum ath10k_debug_mask {
33 ATH10K_DBG_MGMT = 0x00000100, 33 ATH10K_DBG_MGMT = 0x00000100,
34 ATH10K_DBG_DATA = 0x00000200, 34 ATH10K_DBG_DATA = 0x00000200,
35 ATH10K_DBG_BMI = 0x00000400, 35 ATH10K_DBG_BMI = 0x00000400,
36 ATH10K_DBG_REGULATORY = 0x00000800,
36 ATH10K_DBG_ANY = 0xffffffff, 37 ATH10K_DBG_ANY = 0xffffffff,
37}; 38};
38 39
@@ -53,6 +54,8 @@ void ath10k_debug_read_service_map(struct ath10k *ar,
53void ath10k_debug_read_target_stats(struct ath10k *ar, 54void ath10k_debug_read_target_stats(struct ath10k *ar,
54 struct wmi_stats_event *ev); 55 struct wmi_stats_event *ev);
55 56
57#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
58
56#else 59#else
57static inline int ath10k_debug_start(struct ath10k *ar) 60static inline int ath10k_debug_start(struct ath10k *ar)
58{ 61{
@@ -82,6 +85,9 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
82 struct wmi_stats_event *ev) 85 struct wmi_stats_event *ev)
83{ 86{
84} 87}
88
89#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
90
85#endif /* CONFIG_ATH10K_DEBUGFS */ 91#endif /* CONFIG_ATH10K_DEBUGFS */
86 92
87#ifdef CONFIG_ATH10K_DEBUG 93#ifdef CONFIG_ATH10K_DEBUG
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index edae50b52806..edc57ab505c8 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -191,6 +191,11 @@ static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
191 struct ath10k_htc *htc = &ar->htc; 191 struct ath10k_htc *htc = &ar->htc;
192 struct ath10k_htc_ep *ep = &htc->endpoint[eid]; 192 struct ath10k_htc_ep *ep = &htc->endpoint[eid];
193 193
194 if (!skb) {
195 ath10k_warn("invalid sk_buff completion - NULL pointer. firmware crashed?\n");
196 return 0;
197 }
198
194 ath10k_htc_notify_tx_completion(ep, skb); 199 ath10k_htc_notify_tx_completion(ep, skb);
195 /* the skb now belongs to the completion handler */ 200 /* the skb now belongs to the completion handler */
196 201
@@ -534,14 +539,6 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
534 u16 credit_count; 539 u16 credit_count;
535 u16 credit_size; 540 u16 credit_size;
536 541
537 reinit_completion(&htc->ctl_resp);
538
539 status = ath10k_hif_start(htc->ar);
540 if (status) {
541 ath10k_err("could not start HIF (%d)\n", status);
542 goto err_start;
543 }
544
545 status = wait_for_completion_timeout(&htc->ctl_resp, 542 status = wait_for_completion_timeout(&htc->ctl_resp,
546 ATH10K_HTC_WAIT_TIMEOUT_HZ); 543 ATH10K_HTC_WAIT_TIMEOUT_HZ);
547 if (status <= 0) { 544 if (status <= 0) {
@@ -549,15 +546,13 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
549 status = -ETIMEDOUT; 546 status = -ETIMEDOUT;
550 547
551 ath10k_err("ctl_resp never came in (%d)\n", status); 548 ath10k_err("ctl_resp never came in (%d)\n", status);
552 goto err_target; 549 return status;
553 } 550 }
554 551
555 if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { 552 if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
556 ath10k_err("Invalid HTC ready msg len:%d\n", 553 ath10k_err("Invalid HTC ready msg len:%d\n",
557 htc->control_resp_len); 554 htc->control_resp_len);
558 555 return -ECOMM;
559 status = -ECOMM;
560 goto err_target;
561 } 556 }
562 557
563 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer; 558 msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
@@ -567,8 +562,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
567 562
568 if (message_id != ATH10K_HTC_MSG_READY_ID) { 563 if (message_id != ATH10K_HTC_MSG_READY_ID) {
569 ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id); 564 ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id);
570 status = -ECOMM; 565 return -ECOMM;
571 goto err_target;
572 } 566 }
573 567
574 htc->total_transmit_credits = credit_count; 568 htc->total_transmit_credits = credit_count;
@@ -581,9 +575,8 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
581 575
582 if ((htc->total_transmit_credits == 0) || 576 if ((htc->total_transmit_credits == 0) ||
583 (htc->target_credit_size == 0)) { 577 (htc->target_credit_size == 0)) {
584 status = -ECOMM;
585 ath10k_err("Invalid credit size received\n"); 578 ath10k_err("Invalid credit size received\n");
586 goto err_target; 579 return -ECOMM;
587 } 580 }
588 581
589 ath10k_htc_setup_target_buffer_assignments(htc); 582 ath10k_htc_setup_target_buffer_assignments(htc);
@@ -600,14 +593,10 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
600 status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); 593 status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
601 if (status) { 594 if (status) {
602 ath10k_err("could not connect to htc service (%d)\n", status); 595 ath10k_err("could not connect to htc service (%d)\n", status);
603 goto err_target; 596 return status;
604 } 597 }
605 598
606 return 0; 599 return 0;
607err_target:
608 ath10k_hif_stop(htc->ar);
609err_start:
610 return status;
611} 600}
612 601
613int ath10k_htc_connect_service(struct ath10k_htc *htc, 602int ath10k_htc_connect_service(struct ath10k_htc *htc,
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 5f7eeebc5432..69697af59ce0 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -104,8 +104,8 @@ err_htc_attach:
104 104
105static int ath10k_htt_verify_version(struct ath10k_htt *htt) 105static int ath10k_htt_verify_version(struct ath10k_htt *htt)
106{ 106{
107 ath10k_info("htt target version %d.%d\n", 107 ath10k_dbg(ATH10K_DBG_BOOT, "htt target version %d.%d\n",
108 htt->target_version_major, htt->target_version_minor); 108 htt->target_version_major, htt->target_version_minor);
109 109
110 if (htt->target_version_major != 2 && 110 if (htt->target_version_major != 2 &&
111 htt->target_version_major != 3) { 111 htt->target_version_major != 3) {
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 1a337e93b7e9..b93ae355bc08 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1182,6 +1182,8 @@ struct htt_rx_info {
1182 u32 info2; 1182 u32 info2;
1183 } rate; 1183 } rate;
1184 bool fcs_err; 1184 bool fcs_err;
1185 bool amsdu_more;
1186 bool mic_err;
1185}; 1187};
1186 1188
1187struct ath10k_htt { 1189struct ath10k_htt {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 90d4f74c28d7..fe8bd1b59f0e 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -659,23 +659,6 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
659 memcpy(hdr_buf, hdr, hdr_len); 659 memcpy(hdr_buf, hdr, hdr_len);
660 hdr = (struct ieee80211_hdr *)hdr_buf; 660 hdr = (struct ieee80211_hdr *)hdr_buf;
661 661
662 /* FIXME: Hopefully this is a temporary measure.
663 *
664 * Reporting individual A-MSDU subframes means each reported frame
665 * shares the same sequence number.
666 *
667 * mac80211 drops frames it recognizes as duplicates, i.e.
668 * retransmission flag is set and sequence number matches sequence
669 * number from a previous frame (as per IEEE 802.11-2012: 9.3.2.10
670 * "Duplicate detection and recovery")
671 *
672 * To avoid frames being dropped clear retransmission flag for all
673 * received A-MSDUs.
674 *
675 * Worst case: actual duplicate frames will be reported but this should
676 * still be handled gracefully by other OSI/ISO layers. */
677 hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_RETRY);
678
679 first = skb; 662 first = skb;
680 while (skb) { 663 while (skb) {
681 void *decap_hdr; 664 void *decap_hdr;
@@ -746,6 +729,9 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
746 skb = skb->next; 729 skb = skb->next;
747 info->skb->next = NULL; 730 info->skb->next = NULL;
748 731
732 if (skb)
733 info->amsdu_more = true;
734
749 ath10k_process_rx(htt->ar, info); 735 ath10k_process_rx(htt->ar, info);
750 } 736 }
751 737
@@ -852,6 +838,20 @@ static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
852 return false; 838 return false;
853} 839}
854 840
841static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb)
842{
843 struct htt_rx_desc *rxd;
844 u32 flags;
845
846 rxd = (void *)skb->data - sizeof(*rxd);
847 flags = __le32_to_cpu(rxd->attention.flags);
848
849 if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
850 return true;
851
852 return false;
853}
854
855static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) 855static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
856{ 856{
857 struct htt_rx_desc *rxd; 857 struct htt_rx_desc *rxd;
@@ -959,6 +959,11 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
959 continue; 959 continue;
960 } 960 }
961 961
962 if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
963 ath10k_htt_rx_free_msdu_chain(msdu_head);
964 continue;
965 }
966
962 /* FIXME: we do not support chaining yet. 967 /* FIXME: we do not support chaining yet.
963 * this needs investigation */ 968 * this needs investigation */
964 if (msdu_chaining) { 969 if (msdu_chaining) {
@@ -969,6 +974,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
969 974
970 info.skb = msdu_head; 975 info.skb = msdu_head;
971 info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head); 976 info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
977 info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
972 info.signal = ATH10K_DEFAULT_NOISE_FLOOR; 978 info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
973 info.signal += rx->ppdu.combined_rssi; 979 info.signal += rx->ppdu.combined_rssi;
974 980
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index d9335e9d0d04..f1d36d2d2723 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -85,16 +85,13 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
85 85
86int ath10k_htt_tx_attach(struct ath10k_htt *htt) 86int ath10k_htt_tx_attach(struct ath10k_htt *htt)
87{ 87{
88 u8 pipe;
89
90 spin_lock_init(&htt->tx_lock); 88 spin_lock_init(&htt->tx_lock);
91 init_waitqueue_head(&htt->empty_tx_wq); 89 init_waitqueue_head(&htt->empty_tx_wq);
92 90
93 /* At the beginning free queue number should hint us the maximum 91 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, htt->ar->fw_features))
94 * queue length */ 92 htt->max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
95 pipe = htt->ar->htc.endpoint[htt->eid].ul_pipe_id; 93 else
96 htt->max_num_pending_tx = ath10k_hif_get_free_queue_number(htt->ar, 94 htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC;
97 pipe);
98 95
99 ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", 96 ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
100 htt->max_num_pending_tx); 97 htt->max_num_pending_tx);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 8aeb46d9b534..f1505a25d810 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -115,6 +115,7 @@ enum ath10k_mcast2ucast_mode {
115#define TARGET_10X_MAC_AGGR_DELIM 0 115#define TARGET_10X_MAC_AGGR_DELIM 0
116#define TARGET_10X_AST_SKID_LIMIT 16 116#define TARGET_10X_AST_SKID_LIMIT 16
117#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) 117#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS))
118#define TARGET_10X_NUM_PEERS_MAX 128
118#define TARGET_10X_NUM_OFFLOAD_PEERS 0 119#define TARGET_10X_NUM_OFFLOAD_PEERS 0
119#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 120#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0
120#define TARGET_10X_NUM_PEER_KEYS 2 121#define TARGET_10X_NUM_PEER_KEYS 2
@@ -269,6 +270,7 @@ enum ath10k_mcast2ucast_mode {
269#define CORE_CTRL_CPU_INTR_MASK 0x00002000 270#define CORE_CTRL_CPU_INTR_MASK 0x00002000
270#define CORE_CTRL_ADDRESS 0x0000 271#define CORE_CTRL_ADDRESS 0x0000
271#define PCIE_INTR_ENABLE_ADDRESS 0x0008 272#define PCIE_INTR_ENABLE_ADDRESS 0x0008
273#define PCIE_INTR_CAUSE_ADDRESS 0x000c
272#define PCIE_INTR_CLR_ADDRESS 0x0014 274#define PCIE_INTR_CLR_ADDRESS 0x0014
273#define SCRATCH_3_ADDRESS 0x0030 275#define SCRATCH_3_ADDRESS 0x0030
274 276
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 97ac8c87cba2..776e364eadcd 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -322,12 +322,19 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
322 lockdep_assert_held(&ar->conf_mutex); 322 lockdep_assert_held(&ar->conf_mutex);
323 323
324 ret = ath10k_wmi_peer_create(ar, vdev_id, addr); 324 ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
325 if (ret) 325 if (ret) {
326 ath10k_warn("Failed to create wmi peer: %i\n", ret);
326 return ret; 327 return ret;
328 }
327 329
328 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr); 330 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
329 if (ret) 331 if (ret) {
332 ath10k_warn("Failed to wait for created wmi peer: %i\n", ret);
330 return ret; 333 return ret;
334 }
335 spin_lock_bh(&ar->data_lock);
336 ar->num_peers++;
337 spin_unlock_bh(&ar->data_lock);
331 338
332 return 0; 339 return 0;
333} 340}
@@ -373,6 +380,10 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
373 if (ret) 380 if (ret)
374 return ret; 381 return ret;
375 382
383 spin_lock_bh(&ar->data_lock);
384 ar->num_peers--;
385 spin_unlock_bh(&ar->data_lock);
386
376 return 0; 387 return 0;
377} 388}
378 389
@@ -392,6 +403,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
392 403
393 list_del(&peer->list); 404 list_del(&peer->list);
394 kfree(peer); 405 kfree(peer);
406 ar->num_peers--;
395 } 407 }
396 spin_unlock_bh(&ar->data_lock); 408 spin_unlock_bh(&ar->data_lock);
397} 409}
@@ -407,6 +419,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
407 list_del(&peer->list); 419 list_del(&peer->list);
408 kfree(peer); 420 kfree(peer);
409 } 421 }
422 ar->num_peers = 0;
410 spin_unlock_bh(&ar->data_lock); 423 spin_unlock_bh(&ar->data_lock);
411} 424}
412 425
@@ -450,15 +463,19 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
450 463
451 arg.channel.mode = chan_to_phymode(&conf->chandef); 464 arg.channel.mode = chan_to_phymode(&conf->chandef);
452 465
453 arg.channel.min_power = channel->max_power * 3; 466 arg.channel.min_power = 0;
454 arg.channel.max_power = channel->max_power * 4; 467 arg.channel.max_power = channel->max_power * 2;
455 arg.channel.max_reg_power = channel->max_reg_power * 4; 468 arg.channel.max_reg_power = channel->max_reg_power * 2;
456 arg.channel.max_antenna_gain = channel->max_antenna_gain; 469 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
457 470
458 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 471 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
459 arg.ssid = arvif->u.ap.ssid; 472 arg.ssid = arvif->u.ap.ssid;
460 arg.ssid_len = arvif->u.ap.ssid_len; 473 arg.ssid_len = arvif->u.ap.ssid_len;
461 arg.hidden_ssid = arvif->u.ap.hidden_ssid; 474 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
475
476 /* For now allow DFS for AP mode */
477 arg.channel.chan_radar =
478 !!(channel->flags & IEEE80211_CHAN_RADAR);
462 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { 479 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
463 arg.ssid = arvif->vif->bss_conf.ssid; 480 arg.ssid = arvif->vif->bss_conf.ssid;
464 arg.ssid_len = arvif->vif->bss_conf.ssid_len; 481 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
@@ -516,6 +533,11 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
516 533
517 lockdep_assert_held(&ar->conf_mutex); 534 lockdep_assert_held(&ar->conf_mutex);
518 535
536 if (!ar->monitor_present) {
537 ath10k_warn("mac montor stop -- monitor is not present\n");
538 return -EINVAL;
539 }
540
519 arg.vdev_id = vdev_id; 541 arg.vdev_id = vdev_id;
520 arg.channel.freq = channel->center_freq; 542 arg.channel.freq = channel->center_freq;
521 arg.channel.band_center_freq1 = ar->hw->conf.chandef.center_freq1; 543 arg.channel.band_center_freq1 = ar->hw->conf.chandef.center_freq1;
@@ -523,11 +545,13 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
523 /* TODO setup this dynamically, what in case we 545 /* TODO setup this dynamically, what in case we
524 don't have any vifs? */ 546 don't have any vifs? */
525 arg.channel.mode = chan_to_phymode(&ar->hw->conf.chandef); 547 arg.channel.mode = chan_to_phymode(&ar->hw->conf.chandef);
548 arg.channel.chan_radar =
549 !!(channel->flags & IEEE80211_CHAN_RADAR);
526 550
527 arg.channel.min_power = channel->max_power * 3; 551 arg.channel.min_power = 0;
528 arg.channel.max_power = channel->max_power * 4; 552 arg.channel.max_power = channel->max_power * 2;
529 arg.channel.max_reg_power = channel->max_reg_power * 4; 553 arg.channel.max_reg_power = channel->max_reg_power * 2;
530 arg.channel.max_antenna_gain = channel->max_antenna_gain; 554 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
531 555
532 ret = ath10k_wmi_vdev_start(ar, &arg); 556 ret = ath10k_wmi_vdev_start(ar, &arg);
533 if (ret) { 557 if (ret) {
@@ -566,6 +590,16 @@ static int ath10k_monitor_stop(struct ath10k *ar)
566 590
567 lockdep_assert_held(&ar->conf_mutex); 591 lockdep_assert_held(&ar->conf_mutex);
568 592
593 if (!ar->monitor_present) {
594 ath10k_warn("mac montor stop -- monitor is not present\n");
595 return -EINVAL;
596 }
597
598 if (!ar->monitor_enabled) {
599 ath10k_warn("mac montor stop -- monitor is not enabled\n");
600 return -EINVAL;
601 }
602
569 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); 603 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
570 if (ret) 604 if (ret)
571 ath10k_warn("Monitor vdev down failed: %d\n", ret); 605 ath10k_warn("Monitor vdev down failed: %d\n", ret);
@@ -647,6 +681,107 @@ static int ath10k_monitor_destroy(struct ath10k *ar)
647 return ret; 681 return ret;
648} 682}
649 683
684static int ath10k_start_cac(struct ath10k *ar)
685{
686 int ret;
687
688 lockdep_assert_held(&ar->conf_mutex);
689
690 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
691
692 ret = ath10k_monitor_create(ar);
693 if (ret) {
694 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
695 return ret;
696 }
697
698 ret = ath10k_monitor_start(ar, ar->monitor_vdev_id);
699 if (ret) {
700 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
701 ath10k_monitor_destroy(ar);
702 return ret;
703 }
704
705 ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
706 ar->monitor_vdev_id);
707
708 return 0;
709}
710
711static int ath10k_stop_cac(struct ath10k *ar)
712{
713 lockdep_assert_held(&ar->conf_mutex);
714
715 /* CAC is not running - do nothing */
716 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
717 return 0;
718
719 ath10k_monitor_stop(ar);
720 ath10k_monitor_destroy(ar);
721 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
722
723 ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n");
724
725 return 0;
726}
727
728static const char *ath10k_dfs_state(enum nl80211_dfs_state dfs_state)
729{
730 switch (dfs_state) {
731 case NL80211_DFS_USABLE:
732 return "USABLE";
733 case NL80211_DFS_UNAVAILABLE:
734 return "UNAVAILABLE";
735 case NL80211_DFS_AVAILABLE:
736 return "AVAILABLE";
737 default:
738 WARN_ON(1);
739 return "bug";
740 }
741}
742
743static void ath10k_config_radar_detection(struct ath10k *ar)
744{
745 struct ieee80211_channel *chan = ar->hw->conf.chandef.chan;
746 bool radar = ar->hw->conf.radar_enabled;
747 bool chan_radar = !!(chan->flags & IEEE80211_CHAN_RADAR);
748 enum nl80211_dfs_state dfs_state = chan->dfs_state;
749 int ret;
750
751 lockdep_assert_held(&ar->conf_mutex);
752
753 ath10k_dbg(ATH10K_DBG_MAC,
754 "mac radar config update: chan %dMHz radar %d chan radar %d chan state %s\n",
755 chan->center_freq, radar, chan_radar,
756 ath10k_dfs_state(dfs_state));
757
758 /*
759 * It's safe to call it even if CAC is not started.
760 * This call here guarantees changing channel, etc. will stop CAC.
761 */
762 ath10k_stop_cac(ar);
763
764 if (!radar)
765 return;
766
767 if (!chan_radar)
768 return;
769
770 if (dfs_state != NL80211_DFS_USABLE)
771 return;
772
773 ret = ath10k_start_cac(ar);
774 if (ret) {
775 /*
776 * Not possible to start CAC on current channel so starting
777 * radiation is not allowed, make this channel DFS_UNAVAILABLE
778 * by indicating that radar was detected.
779 */
780 ath10k_warn("failed to start CAC (%d)\n", ret);
781 ieee80211_radar_detected(ar->hw);
782 }
783}
784
650static void ath10k_control_beaconing(struct ath10k_vif *arvif, 785static void ath10k_control_beaconing(struct ath10k_vif *arvif,
651 struct ieee80211_bss_conf *info) 786 struct ieee80211_bss_conf *info)
652{ 787{
@@ -1351,19 +1486,22 @@ static int ath10k_update_channel_list(struct ath10k *ar)
1351 ch->allow_vht = true; 1486 ch->allow_vht = true;
1352 1487
1353 ch->allow_ibss = 1488 ch->allow_ibss =
1354 !(channel->flags & IEEE80211_CHAN_NO_IBSS); 1489 !(channel->flags & IEEE80211_CHAN_NO_IR);
1355 1490
1356 ch->ht40plus = 1491 ch->ht40plus =
1357 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS); 1492 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
1358 1493
1359 passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN; 1494 ch->chan_radar =
1495 !!(channel->flags & IEEE80211_CHAN_RADAR);
1496
1497 passive = channel->flags & IEEE80211_CHAN_NO_IR;
1360 ch->passive = passive; 1498 ch->passive = passive;
1361 1499
1362 ch->freq = channel->center_freq; 1500 ch->freq = channel->center_freq;
1363 ch->min_power = channel->max_power * 3; 1501 ch->min_power = 0;
1364 ch->max_power = channel->max_power * 4; 1502 ch->max_power = channel->max_power * 2;
1365 ch->max_reg_power = channel->max_reg_power * 4; 1503 ch->max_reg_power = channel->max_reg_power * 2;
1366 ch->max_antenna_gain = channel->max_antenna_gain; 1504 ch->max_antenna_gain = channel->max_antenna_gain * 2;
1367 ch->reg_class_id = 0; /* FIXME */ 1505 ch->reg_class_id = 0; /* FIXME */
1368 1506
1369 /* FIXME: why use only legacy modes, why not any 1507 /* FIXME: why use only legacy modes, why not any
@@ -1423,9 +1561,20 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
1423{ 1561{
1424 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 1562 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1425 struct ath10k *ar = hw->priv; 1563 struct ath10k *ar = hw->priv;
1564 bool result;
1426 1565
1427 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); 1566 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
1428 1567
1568 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
1569 ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
1570 request->dfs_region);
1571 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
1572 request->dfs_region);
1573 if (!result)
1574 ath10k_warn("dfs region 0x%X not supported, will trigger radar for every pulse\n",
1575 request->dfs_region);
1576 }
1577
1429 mutex_lock(&ar->conf_mutex); 1578 mutex_lock(&ar->conf_mutex);
1430 if (ar->state == ATH10K_STATE_ON) 1579 if (ar->state == ATH10K_STATE_ON)
1431 ath10k_regd_update(ar); 1580 ath10k_regd_update(ar);
@@ -1714,8 +1863,10 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
1714 break; 1863 break;
1715 1864
1716 ret = ath10k_wmi_mgmt_tx(ar, skb); 1865 ret = ath10k_wmi_mgmt_tx(ar, skb);
1717 if (ret) 1866 if (ret) {
1718 ath10k_warn("wmi mgmt_tx failed (%d)\n", ret); 1867 ath10k_warn("wmi mgmt_tx failed (%d)\n", ret);
1868 ieee80211_free_txskb(ar->hw, skb);
1869 }
1719 } 1870 }
1720} 1871}
1721 1872
@@ -1889,6 +2040,7 @@ void ath10k_halt(struct ath10k *ar)
1889{ 2040{
1890 lockdep_assert_held(&ar->conf_mutex); 2041 lockdep_assert_held(&ar->conf_mutex);
1891 2042
2043 ath10k_stop_cac(ar);
1892 del_timer_sync(&ar->scan.timeout); 2044 del_timer_sync(&ar->scan.timeout);
1893 ath10k_offchan_tx_purge(ar); 2045 ath10k_offchan_tx_purge(ar);
1894 ath10k_mgmt_over_wmi_tx_purge(ar); 2046 ath10k_mgmt_over_wmi_tx_purge(ar);
@@ -1943,7 +2095,7 @@ static int ath10k_start(struct ieee80211_hw *hw)
1943 ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n", 2095 ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n",
1944 ret); 2096 ret);
1945 2097
1946 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 0); 2098 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
1947 if (ret) 2099 if (ret)
1948 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", 2100 ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
1949 ret); 2101 ret);
@@ -1998,15 +2150,40 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
1998 struct ath10k *ar = hw->priv; 2150 struct ath10k *ar = hw->priv;
1999 struct ieee80211_conf *conf = &hw->conf; 2151 struct ieee80211_conf *conf = &hw->conf;
2000 int ret = 0; 2152 int ret = 0;
2153 u32 param;
2001 2154
2002 mutex_lock(&ar->conf_mutex); 2155 mutex_lock(&ar->conf_mutex);
2003 2156
2004 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 2157 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
2005 ath10k_dbg(ATH10K_DBG_MAC, "mac config channel %d mhz\n", 2158 ath10k_dbg(ATH10K_DBG_MAC,
2006 conf->chandef.chan->center_freq); 2159 "mac config channel %d mhz flags 0x%x\n",
2160 conf->chandef.chan->center_freq,
2161 conf->chandef.chan->flags);
2162
2007 spin_lock_bh(&ar->data_lock); 2163 spin_lock_bh(&ar->data_lock);
2008 ar->rx_channel = conf->chandef.chan; 2164 ar->rx_channel = conf->chandef.chan;
2009 spin_unlock_bh(&ar->data_lock); 2165 spin_unlock_bh(&ar->data_lock);
2166
2167 ath10k_config_radar_detection(ar);
2168 }
2169
2170 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2171 ath10k_dbg(ATH10K_DBG_MAC, "mac config power %d\n",
2172 hw->conf.power_level);
2173
2174 param = ar->wmi.pdev_param->txpower_limit2g;
2175 ret = ath10k_wmi_pdev_set_param(ar, param,
2176 hw->conf.power_level * 2);
2177 if (ret)
2178 ath10k_warn("mac failed to set 2g txpower %d (%d)\n",
2179 hw->conf.power_level, ret);
2180
2181 param = ar->wmi.pdev_param->txpower_limit5g;
2182 ret = ath10k_wmi_pdev_set_param(ar, param,
2183 hw->conf.power_level * 2);
2184 if (ret)
2185 ath10k_warn("mac failed to set 5g txpower %d (%d)\n",
2186 hw->conf.power_level, ret);
2010 } 2187 }
2011 2188
2012 if (changed & IEEE80211_CONF_CHANGE_PS) 2189 if (changed & IEEE80211_CONF_CHANGE_PS)
@@ -2037,7 +2214,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2037 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 2214 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2038 enum wmi_sta_powersave_param param; 2215 enum wmi_sta_powersave_param param;
2039 int ret = 0; 2216 int ret = 0;
2040 u32 value; 2217 u32 value, param_id;
2041 int bit; 2218 int bit;
2042 u32 vdev_param; 2219 u32 vdev_param;
2043 2220
@@ -2049,6 +2226,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2049 arvif->vif = vif; 2226 arvif->vif = vif;
2050 2227
2051 INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); 2228 INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work);
2229 INIT_LIST_HEAD(&arvif->list);
2052 2230
2053 if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) { 2231 if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) {
2054 ath10k_warn("Only one monitor interface allowed\n"); 2232 ath10k_warn("Only one monitor interface allowed\n");
@@ -2128,6 +2306,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2128 ath10k_warn("Failed to create peer for AP: %d\n", ret); 2306 ath10k_warn("Failed to create peer for AP: %d\n", ret);
2129 goto err_vdev_delete; 2307 goto err_vdev_delete;
2130 } 2308 }
2309
2310 param_id = ar->wmi.pdev_param->sta_kickout_th;
2311
2312 /* Disable STA KICKOUT functionality in FW */
2313 ret = ath10k_wmi_pdev_set_param(ar, param_id, 0);
2314 if (ret)
2315 ath10k_warn("Failed to disable STA KICKOUT\n");
2131 } 2316 }
2132 2317
2133 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { 2318 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
@@ -2265,8 +2450,14 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
2265 *total_flags &= SUPPORTED_FILTERS; 2450 *total_flags &= SUPPORTED_FILTERS;
2266 ar->filter_flags = *total_flags; 2451 ar->filter_flags = *total_flags;
2267 2452
2453 /* Monitor must not be started if it wasn't created first.
2454 * Promiscuous mode may be started on a non-monitor interface - in
2455 * such case the monitor vdev is not created so starting the
2456 * monitor makes no sense. Since ath10k uses no special RX filters
2457 * (only BSS filter in STA mode) there's no need for any special
2458 * action here. */
2268 if ((ar->filter_flags & FIF_PROMISC_IN_BSS) && 2459 if ((ar->filter_flags & FIF_PROMISC_IN_BSS) &&
2269 !ar->monitor_enabled) { 2460 !ar->monitor_enabled && ar->monitor_present) {
2270 ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d start\n", 2461 ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d start\n",
2271 ar->monitor_vdev_id); 2462 ar->monitor_vdev_id);
2272 2463
@@ -2274,7 +2465,7 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
2274 if (ret) 2465 if (ret)
2275 ath10k_warn("Unable to start monitor mode\n"); 2466 ath10k_warn("Unable to start monitor mode\n");
2276 } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && 2467 } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) &&
2277 ar->monitor_enabled) { 2468 ar->monitor_enabled && ar->monitor_present) {
2278 ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d stop\n", 2469 ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d stop\n",
2279 ar->monitor_vdev_id); 2470 ar->monitor_vdev_id);
2280 2471
@@ -2360,8 +2551,8 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
2360 ret = ath10k_peer_create(ar, arvif->vdev_id, 2551 ret = ath10k_peer_create(ar, arvif->vdev_id,
2361 info->bssid); 2552 info->bssid);
2362 if (ret) 2553 if (ret)
2363 ath10k_warn("Failed to add peer: %pM for VDEV: %d\n", 2554 ath10k_warn("Failed to add peer %pM for vdev %d when changin bssid: %i\n",
2364 info->bssid, arvif->vdev_id); 2555 info->bssid, arvif->vdev_id, ret);
2365 2556
2366 if (vif->type == NL80211_IFTYPE_STATION) { 2557 if (vif->type == NL80211_IFTYPE_STATION) {
2367 /* 2558 /*
@@ -2542,6 +2733,44 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
2542 mutex_unlock(&ar->conf_mutex); 2733 mutex_unlock(&ar->conf_mutex);
2543} 2734}
2544 2735
2736static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
2737 struct ath10k_vif *arvif,
2738 enum set_key_cmd cmd,
2739 struct ieee80211_key_conf *key)
2740{
2741 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
2742 int ret;
2743
2744 /* 10.1 firmware branch requires default key index to be set to group
2745 * key index after installing it. Otherwise FW/HW Txes corrupted
2746 * frames with multi-vif APs. This is not required for main firmware
2747 * branch (e.g. 636).
2748 *
2749 * FIXME: This has been tested only in AP. It remains unknown if this
2750 * is required for multi-vif STA interfaces on 10.1 */
2751
2752 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
2753 return;
2754
2755 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
2756 return;
2757
2758 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
2759 return;
2760
2761 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
2762 return;
2763
2764 if (cmd != SET_KEY)
2765 return;
2766
2767 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
2768 key->keyidx);
2769 if (ret)
2770 ath10k_warn("failed to set group key as default key: %d\n",
2771 ret);
2772}
2773
2545static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2774static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2546 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 2775 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2547 struct ieee80211_key_conf *key) 2776 struct ieee80211_key_conf *key)
@@ -2603,6 +2832,8 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2603 goto exit; 2832 goto exit;
2604 } 2833 }
2605 2834
2835 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
2836
2606 spin_lock_bh(&ar->data_lock); 2837 spin_lock_bh(&ar->data_lock);
2607 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr); 2838 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
2608 if (peer && cmd == SET_KEY) 2839 if (peer && cmd == SET_KEY)
@@ -2627,6 +2858,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
2627{ 2858{
2628 struct ath10k *ar = hw->priv; 2859 struct ath10k *ar = hw->priv;
2629 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 2860 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2861 int max_num_peers;
2630 int ret = 0; 2862 int ret = 0;
2631 2863
2632 mutex_lock(&ar->conf_mutex); 2864 mutex_lock(&ar->conf_mutex);
@@ -2637,14 +2869,26 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
2637 /* 2869 /*
2638 * New station addition. 2870 * New station addition.
2639 */ 2871 */
2872 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
2873 max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1;
2874 else
2875 max_num_peers = TARGET_NUM_PEERS;
2876
2877 if (ar->num_peers >= max_num_peers) {
2878 ath10k_warn("Number of peers exceeded: peers number %d (max peers %d)\n",
2879 ar->num_peers, max_num_peers);
2880 ret = -ENOBUFS;
2881 goto exit;
2882 }
2883
2640 ath10k_dbg(ATH10K_DBG_MAC, 2884 ath10k_dbg(ATH10K_DBG_MAC,
2641 "mac vdev %d peer create %pM (new sta)\n", 2885 "mac vdev %d peer create %pM (new sta) num_peers %d\n",
2642 arvif->vdev_id, sta->addr); 2886 arvif->vdev_id, sta->addr, ar->num_peers);
2643 2887
2644 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); 2888 ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
2645 if (ret) 2889 if (ret)
2646 ath10k_warn("Failed to add peer: %pM for VDEV: %d\n", 2890 ath10k_warn("Failed to add peer %pM for vdev %d when adding a new sta: %i\n",
2647 sta->addr, arvif->vdev_id); 2891 sta->addr, arvif->vdev_id, ret);
2648 } else if ((old_state == IEEE80211_STA_NONE && 2892 } else if ((old_state == IEEE80211_STA_NONE &&
2649 new_state == IEEE80211_STA_NOTEXIST)) { 2893 new_state == IEEE80211_STA_NOTEXIST)) {
2650 /* 2894 /*
@@ -2689,7 +2933,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
2689 ath10k_warn("Failed to disassociate station: %pM\n", 2933 ath10k_warn("Failed to disassociate station: %pM\n",
2690 sta->addr); 2934 sta->addr);
2691 } 2935 }
2692 2936exit:
2693 mutex_unlock(&ar->conf_mutex); 2937 mutex_unlock(&ar->conf_mutex);
2694 return ret; 2938 return ret;
2695} 2939}
@@ -3095,6 +3339,307 @@ exit:
3095 return ret; 3339 return ret;
3096} 3340}
3097 3341
3342/* Helper table for legacy fixed_rate/bitrate_mask */
3343static const u8 cck_ofdm_rate[] = {
3344 /* CCK */
3345 3, /* 1Mbps */
3346 2, /* 2Mbps */
3347 1, /* 5.5Mbps */
3348 0, /* 11Mbps */
3349 /* OFDM */
3350 3, /* 6Mbps */
3351 7, /* 9Mbps */
3352 2, /* 12Mbps */
3353 6, /* 18Mbps */
3354 1, /* 24Mbps */
3355 5, /* 36Mbps */
3356 0, /* 48Mbps */
3357 4, /* 54Mbps */
3358};
3359
3360/* Check if only one bit set */
3361static int ath10k_check_single_mask(u32 mask)
3362{
3363 int bit;
3364
3365 bit = ffs(mask);
3366 if (!bit)
3367 return 0;
3368
3369 mask &= ~BIT(bit - 1);
3370 if (mask)
3371 return 2;
3372
3373 return 1;
3374}
3375
3376static bool
3377ath10k_default_bitrate_mask(struct ath10k *ar,
3378 enum ieee80211_band band,
3379 const struct cfg80211_bitrate_mask *mask)
3380{
3381 u32 legacy = 0x00ff;
3382 u8 ht = 0xff, i;
3383 u16 vht = 0x3ff;
3384
3385 switch (band) {
3386 case IEEE80211_BAND_2GHZ:
3387 legacy = 0x00fff;
3388 vht = 0;
3389 break;
3390 case IEEE80211_BAND_5GHZ:
3391 break;
3392 default:
3393 return false;
3394 }
3395
3396 if (mask->control[band].legacy != legacy)
3397 return false;
3398
3399 for (i = 0; i < ar->num_rf_chains; i++)
3400 if (mask->control[band].ht_mcs[i] != ht)
3401 return false;
3402
3403 for (i = 0; i < ar->num_rf_chains; i++)
3404 if (mask->control[band].vht_mcs[i] != vht)
3405 return false;
3406
3407 return true;
3408}
3409
3410static bool
3411ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask,
3412 enum ieee80211_band band,
3413 u8 *fixed_nss)
3414{
3415 int ht_nss = 0, vht_nss = 0, i;
3416
3417 /* check legacy */
3418 if (ath10k_check_single_mask(mask->control[band].legacy))
3419 return false;
3420
3421 /* check HT */
3422 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3423 if (mask->control[band].ht_mcs[i] == 0xff)
3424 continue;
3425 else if (mask->control[band].ht_mcs[i] == 0x00)
3426 break;
3427 else
3428 return false;
3429 }
3430
3431 ht_nss = i;
3432
3433 /* check VHT */
3434 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3435 if (mask->control[band].vht_mcs[i] == 0x03ff)
3436 continue;
3437 else if (mask->control[band].vht_mcs[i] == 0x0000)
3438 break;
3439 else
3440 return false;
3441 }
3442
3443 vht_nss = i;
3444
3445 if (ht_nss > 0 && vht_nss > 0)
3446 return false;
3447
3448 if (ht_nss)
3449 *fixed_nss = ht_nss;
3450 else if (vht_nss)
3451 *fixed_nss = vht_nss;
3452 else
3453 return false;
3454
3455 return true;
3456}
3457
3458static bool
3459ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask,
3460 enum ieee80211_band band,
3461 enum wmi_rate_preamble *preamble)
3462{
3463 int legacy = 0, ht = 0, vht = 0, i;
3464
3465 *preamble = WMI_RATE_PREAMBLE_OFDM;
3466
3467 /* check legacy */
3468 legacy = ath10k_check_single_mask(mask->control[band].legacy);
3469 if (legacy > 1)
3470 return false;
3471
3472 /* check HT */
3473 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3474 ht += ath10k_check_single_mask(mask->control[band].ht_mcs[i]);
3475 if (ht > 1)
3476 return false;
3477
3478 /* check VHT */
3479 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3480 vht += ath10k_check_single_mask(mask->control[band].vht_mcs[i]);
3481 if (vht > 1)
3482 return false;
3483
3484 /* Currently we support only one fixed_rate */
3485 if ((legacy + ht + vht) != 1)
3486 return false;
3487
3488 if (ht)
3489 *preamble = WMI_RATE_PREAMBLE_HT;
3490 else if (vht)
3491 *preamble = WMI_RATE_PREAMBLE_VHT;
3492
3493 return true;
3494}
3495
3496static bool
3497ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask,
3498 enum ieee80211_band band,
3499 u8 *fixed_rate,
3500 u8 *fixed_nss)
3501{
3502 u8 rate = 0, pream = 0, nss = 0, i;
3503 enum wmi_rate_preamble preamble;
3504
3505 /* Check if single rate correct */
3506 if (!ath10k_bitrate_mask_correct(mask, band, &preamble))
3507 return false;
3508
3509 pream = preamble;
3510
3511 switch (preamble) {
3512 case WMI_RATE_PREAMBLE_CCK:
3513 case WMI_RATE_PREAMBLE_OFDM:
3514 i = ffs(mask->control[band].legacy) - 1;
3515
3516 if (band == IEEE80211_BAND_2GHZ && i < 4)
3517 pream = WMI_RATE_PREAMBLE_CCK;
3518
3519 if (band == IEEE80211_BAND_5GHZ)
3520 i += 4;
3521
3522 if (i >= ARRAY_SIZE(cck_ofdm_rate))
3523 return false;
3524
3525 rate = cck_ofdm_rate[i];
3526 break;
3527 case WMI_RATE_PREAMBLE_HT:
3528 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3529 if (mask->control[band].ht_mcs[i])
3530 break;
3531
3532 if (i == IEEE80211_HT_MCS_MASK_LEN)
3533 return false;
3534
3535 rate = ffs(mask->control[band].ht_mcs[i]) - 1;
3536 nss = i;
3537 break;
3538 case WMI_RATE_PREAMBLE_VHT:
3539 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3540 if (mask->control[band].vht_mcs[i])
3541 break;
3542
3543 if (i == NL80211_VHT_NSS_MAX)
3544 return false;
3545
3546 rate = ffs(mask->control[band].vht_mcs[i]) - 1;
3547 nss = i;
3548 break;
3549 }
3550
3551 *fixed_nss = nss + 1;
3552 nss <<= 4;
3553 pream <<= 6;
3554
3555 ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
3556 pream, nss, rate);
3557
3558 *fixed_rate = pream | nss | rate;
3559
3560 return true;
3561}
3562
3563static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask,
3564 enum ieee80211_band band,
3565 u8 *fixed_rate,
3566 u8 *fixed_nss)
3567{
3568 /* First check full NSS mask, if we can simply limit NSS */
3569 if (ath10k_bitrate_mask_nss(mask, band, fixed_nss))
3570 return true;
3571
3572 /* Next Check single rate is set */
3573 return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss);
3574}
3575
3576static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
3577 u8 fixed_rate,
3578 u8 fixed_nss)
3579{
3580 struct ath10k *ar = arvif->ar;
3581 u32 vdev_param;
3582 int ret = 0;
3583
3584 mutex_lock(&ar->conf_mutex);
3585
3586 if (arvif->fixed_rate == fixed_rate &&
3587 arvif->fixed_nss == fixed_nss)
3588 goto exit;
3589
3590 if (fixed_rate == WMI_FIXED_RATE_NONE)
3591 ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n");
3592
3593 vdev_param = ar->wmi.vdev_param->fixed_rate;
3594 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
3595 vdev_param, fixed_rate);
3596 if (ret) {
3597 ath10k_warn("Could not set fixed_rate param 0x%02x: %d\n",
3598 fixed_rate, ret);
3599 ret = -EINVAL;
3600 goto exit;
3601 }
3602
3603 arvif->fixed_rate = fixed_rate;
3604
3605 vdev_param = ar->wmi.vdev_param->nss;
3606 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
3607 vdev_param, fixed_nss);
3608
3609 if (ret) {
3610 ath10k_warn("Could not set fixed_nss param %d: %d\n",
3611 fixed_nss, ret);
3612 ret = -EINVAL;
3613 goto exit;
3614 }
3615
3616 arvif->fixed_nss = fixed_nss;
3617
3618exit:
3619 mutex_unlock(&ar->conf_mutex);
3620 return ret;
3621}
3622
3623static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
3624 struct ieee80211_vif *vif,
3625 const struct cfg80211_bitrate_mask *mask)
3626{
3627 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3628 struct ath10k *ar = arvif->ar;
3629 enum ieee80211_band band = ar->hw->conf.chandef.chan->band;
3630 u8 fixed_rate = WMI_FIXED_RATE_NONE;
3631 u8 fixed_nss = ar->num_rf_chains;
3632
3633 if (!ath10k_default_bitrate_mask(ar, band, mask)) {
3634 if (!ath10k_get_fixed_rate_nss(mask, band,
3635 &fixed_rate,
3636 &fixed_nss))
3637 return -EINVAL;
3638 }
3639
3640 return ath10k_set_fixed_rate_param(arvif, fixed_rate, fixed_nss);
3641}
3642
3098static const struct ieee80211_ops ath10k_ops = { 3643static const struct ieee80211_ops ath10k_ops = {
3099 .tx = ath10k_tx, 3644 .tx = ath10k_tx,
3100 .start = ath10k_start, 3645 .start = ath10k_start,
@@ -3117,6 +3662,7 @@ static const struct ieee80211_ops ath10k_ops = {
3117 .tx_last_beacon = ath10k_tx_last_beacon, 3662 .tx_last_beacon = ath10k_tx_last_beacon,
3118 .restart_complete = ath10k_restart_complete, 3663 .restart_complete = ath10k_restart_complete,
3119 .get_survey = ath10k_get_survey, 3664 .get_survey = ath10k_get_survey,
3665 .set_bitrate_mask = ath10k_set_bitrate_mask,
3120#ifdef CONFIG_PM 3666#ifdef CONFIG_PM
3121 .suspend = ath10k_suspend, 3667 .suspend = ath10k_suspend,
3122 .resume = ath10k_resume, 3668 .resume = ath10k_resume,
@@ -3249,12 +3795,37 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
3249 }, 3795 },
3250}; 3796};
3251 3797
3252static const struct ieee80211_iface_combination ath10k_if_comb = { 3798static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
3253 .limits = ath10k_if_limits, 3799 {
3254 .n_limits = ARRAY_SIZE(ath10k_if_limits), 3800 .max = 8,
3255 .max_interfaces = 8, 3801 .types = BIT(NL80211_IFTYPE_AP)
3256 .num_different_channels = 1, 3802 },
3257 .beacon_int_infra_match = true, 3803};
3804
3805static const struct ieee80211_iface_combination ath10k_if_comb[] = {
3806 {
3807 .limits = ath10k_if_limits,
3808 .n_limits = ARRAY_SIZE(ath10k_if_limits),
3809 .max_interfaces = 8,
3810 .num_different_channels = 1,
3811 .beacon_int_infra_match = true,
3812 },
3813};
3814
3815static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
3816 {
3817 .limits = ath10k_10x_if_limits,
3818 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
3819 .max_interfaces = 8,
3820 .num_different_channels = 1,
3821 .beacon_int_infra_match = true,
3822#ifdef CONFIG_ATH10K_DFS_CERTIFIED
3823 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
3824 BIT(NL80211_CHAN_WIDTH_20) |
3825 BIT(NL80211_CHAN_WIDTH_40) |
3826 BIT(NL80211_CHAN_WIDTH_80),
3827#endif
3828 },
3258}; 3829};
3259 3830
3260static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) 3831static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
@@ -3433,9 +4004,12 @@ int ath10k_mac_register(struct ath10k *ar)
3433 ar->hw->wiphy->interface_modes = 4004 ar->hw->wiphy->interface_modes =
3434 BIT(NL80211_IFTYPE_STATION) | 4005 BIT(NL80211_IFTYPE_STATION) |
3435 BIT(NL80211_IFTYPE_ADHOC) | 4006 BIT(NL80211_IFTYPE_ADHOC) |
3436 BIT(NL80211_IFTYPE_AP) | 4007 BIT(NL80211_IFTYPE_AP);
3437 BIT(NL80211_IFTYPE_P2P_CLIENT) | 4008
3438 BIT(NL80211_IFTYPE_P2P_GO); 4009 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
4010 ar->hw->wiphy->interface_modes |=
4011 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4012 BIT(NL80211_IFTYPE_P2P_GO);
3439 4013
3440 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | 4014 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
3441 IEEE80211_HW_SUPPORTS_PS | 4015 IEEE80211_HW_SUPPORTS_PS |
@@ -3465,7 +4039,6 @@ int ath10k_mac_register(struct ath10k *ar)
3465 4039
3466 ar->hw->vif_data_size = sizeof(struct ath10k_vif); 4040 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
3467 4041
3468 ar->hw->channel_change_time = 5000;
3469 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; 4042 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
3470 4043
3471 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 4044 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
@@ -3478,11 +4051,28 @@ int ath10k_mac_register(struct ath10k *ar)
3478 */ 4051 */
3479 ar->hw->queues = 4; 4052 ar->hw->queues = 4;
3480 4053
3481 ar->hw->wiphy->iface_combinations = &ath10k_if_comb; 4054 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
3482 ar->hw->wiphy->n_iface_combinations = 1; 4055 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
4056 ar->hw->wiphy->n_iface_combinations =
4057 ARRAY_SIZE(ath10k_10x_if_comb);
4058 } else {
4059 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
4060 ar->hw->wiphy->n_iface_combinations =
4061 ARRAY_SIZE(ath10k_if_comb);
4062 }
3483 4063
3484 ar->hw->netdev_features = NETIF_F_HW_CSUM; 4064 ar->hw->netdev_features = NETIF_F_HW_CSUM;
3485 4065
4066 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
4067 /* Init ath dfs pattern detector */
4068 ar->ath_common.debug_mask = ATH_DBG_DFS;
4069 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
4070 NL80211_DFS_UNSET);
4071
4072 if (!ar->dfs_detector)
4073 ath10k_warn("dfs pattern detector init failed\n");
4074 }
4075
3486 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, 4076 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
3487 ath10k_reg_notifier); 4077 ath10k_reg_notifier);
3488 if (ret) { 4078 if (ret) {
@@ -3518,6 +4108,9 @@ void ath10k_mac_unregister(struct ath10k *ar)
3518{ 4108{
3519 ieee80211_unregister_hw(ar->hw); 4109 ieee80211_unregister_hw(ar->hw);
3520 4110
4111 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
4112 ar->dfs_detector->exit(ar->dfs_detector);
4113
3521 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels); 4114 kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
3522 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels); 4115 kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
3523 4116
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 9e86a811086f..29fd197d1fd8 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/bitops.h>
22 23
23#include "core.h" 24#include "core.h"
24#include "debug.h" 25#include "debug.h"
@@ -32,10 +33,21 @@
32#include "ce.h" 33#include "ce.h"
33#include "pci.h" 34#include "pci.h"
34 35
36enum ath10k_pci_irq_mode {
37 ATH10K_PCI_IRQ_AUTO = 0,
38 ATH10K_PCI_IRQ_LEGACY = 1,
39 ATH10K_PCI_IRQ_MSI = 2,
40};
41
35static unsigned int ath10k_target_ps; 42static unsigned int ath10k_target_ps;
43static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO;
44
36module_param(ath10k_target_ps, uint, 0644); 45module_param(ath10k_target_ps, uint, 0644);
37MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option"); 46MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
38 47
48module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644);
49MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)");
50
39#define QCA988X_2_0_DEVICE_ID (0x003c) 51#define QCA988X_2_0_DEVICE_ID (0x003c)
40 52
41static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = { 53static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = {
@@ -52,10 +64,16 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
52 int num); 64 int num);
53static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); 65static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info);
54static void ath10k_pci_stop_ce(struct ath10k *ar); 66static void ath10k_pci_stop_ce(struct ath10k *ar);
55static void ath10k_pci_device_reset(struct ath10k *ar); 67static int ath10k_pci_device_reset(struct ath10k *ar);
56static int ath10k_pci_reset_target(struct ath10k *ar); 68static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
57static int ath10k_pci_start_intr(struct ath10k *ar); 69static int ath10k_pci_init_irq(struct ath10k *ar);
58static void ath10k_pci_stop_intr(struct ath10k *ar); 70static int ath10k_pci_deinit_irq(struct ath10k *ar);
71static int ath10k_pci_request_irq(struct ath10k *ar);
72static void ath10k_pci_free_irq(struct ath10k *ar);
73static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
74 struct ath10k_ce_pipe *rx_pipe,
75 struct bmi_xfer *xfer);
76static void ath10k_pci_cleanup_ce(struct ath10k *ar);
59 77
60static const struct ce_attr host_ce_config_wlan[] = { 78static const struct ce_attr host_ce_config_wlan[] = {
61 /* CE0: host->target HTC control and raw streams */ 79 /* CE0: host->target HTC control and raw streams */
@@ -200,6 +218,87 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
200 /* CE7 used only by Host */ 218 /* CE7 used only by Host */
201}; 219};
202 220
221static bool ath10k_pci_irq_pending(struct ath10k *ar)
222{
223 u32 cause;
224
225 /* Check if the shared legacy irq is for us */
226 cause = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
227 PCIE_INTR_CAUSE_ADDRESS);
228 if (cause & (PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL))
229 return true;
230
231 return false;
232}
233
234static void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar)
235{
236 /* IMPORTANT: INTR_CLR register has to be set after
237 * INTR_ENABLE is set to 0, otherwise interrupt can not be
238 * really cleared. */
239 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS,
240 0);
241 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_CLR_ADDRESS,
242 PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
243
244 /* IMPORTANT: this extra read transaction is required to
245 * flush the posted write buffer. */
246 (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
247 PCIE_INTR_ENABLE_ADDRESS);
248}
249
250static void ath10k_pci_enable_legacy_irq(struct ath10k *ar)
251{
252 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
253 PCIE_INTR_ENABLE_ADDRESS,
254 PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
255
256 /* IMPORTANT: this extra read transaction is required to
257 * flush the posted write buffer. */
258 (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
259 PCIE_INTR_ENABLE_ADDRESS);
260}
261
262static irqreturn_t ath10k_pci_early_irq_handler(int irq, void *arg)
263{
264 struct ath10k *ar = arg;
265 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
266
267 if (ar_pci->num_msi_intrs == 0) {
268 if (!ath10k_pci_irq_pending(ar))
269 return IRQ_NONE;
270
271 ath10k_pci_disable_and_clear_legacy_irq(ar);
272 }
273
274 tasklet_schedule(&ar_pci->early_irq_tasklet);
275
276 return IRQ_HANDLED;
277}
278
279static int ath10k_pci_request_early_irq(struct ath10k *ar)
280{
281 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
282 int ret;
283
284 /* Regardless whether MSI-X/MSI/legacy irqs have been set up the first
285 * interrupt from irq vector is triggered in all cases for FW
286 * indication/errors */
287 ret = request_irq(ar_pci->pdev->irq, ath10k_pci_early_irq_handler,
288 IRQF_SHARED, "ath10k_pci (early)", ar);
289 if (ret) {
290 ath10k_warn("failed to request early irq: %d\n", ret);
291 return ret;
292 }
293
294 return 0;
295}
296
297static void ath10k_pci_free_early_irq(struct ath10k *ar)
298{
299 free_irq(ath10k_pci_priv(ar)->pdev->irq, ar);
300}
301
203/* 302/*
204 * Diagnostic read/write access is provided for startup/config/debug usage. 303 * Diagnostic read/write access is provided for startup/config/debug usage.
205 * Caller must guarantee proper alignment, when applicable, and single user 304 * Caller must guarantee proper alignment, when applicable, and single user
@@ -526,17 +625,6 @@ static bool ath10k_pci_target_is_awake(struct ath10k *ar)
526 return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON); 625 return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON);
527} 626}
528 627
529static void ath10k_pci_wait(struct ath10k *ar)
530{
531 int n = 100;
532
533 while (n-- && !ath10k_pci_target_is_awake(ar))
534 msleep(10);
535
536 if (n < 0)
537 ath10k_warn("Unable to wakeup target\n");
538}
539
540int ath10k_do_pci_wake(struct ath10k *ar) 628int ath10k_do_pci_wake(struct ath10k *ar)
541{ 629{
542 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 630 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
@@ -723,7 +811,7 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
723 ret = ath10k_ce_send(ce_hdl, nbuf, skb_cb->paddr, len, transfer_id, 811 ret = ath10k_ce_send(ce_hdl, nbuf, skb_cb->paddr, len, transfer_id,
724 flags); 812 flags);
725 if (ret) 813 if (ret)
726 ath10k_warn("CE send failed: %p\n", nbuf); 814 ath10k_warn("failed to send sk_buff to CE: %p\n", nbuf);
727 815
728 return ret; 816 return ret;
729} 817}
@@ -750,9 +838,10 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
750 ar->fw_version_build); 838 ar->fw_version_build);
751 839
752 host_addr = host_interest_item_address(HI_ITEM(hi_failure_state)); 840 host_addr = host_interest_item_address(HI_ITEM(hi_failure_state));
753 if (ath10k_pci_diag_read_mem(ar, host_addr, 841 ret = ath10k_pci_diag_read_mem(ar, host_addr,
754 &reg_dump_area, sizeof(u32)) != 0) { 842 &reg_dump_area, sizeof(u32));
755 ath10k_warn("could not read hi_failure_state\n"); 843 if (ret) {
844 ath10k_err("failed to read FW dump area address: %d\n", ret);
756 return; 845 return;
757 } 846 }
758 847
@@ -762,7 +851,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
762 &reg_dump_values[0], 851 &reg_dump_values[0],
763 REG_DUMP_COUNT_QCA988X * sizeof(u32)); 852 REG_DUMP_COUNT_QCA988X * sizeof(u32));
764 if (ret != 0) { 853 if (ret != 0) {
765 ath10k_err("could not dump FW Dump Area\n"); 854 ath10k_err("failed to read FW dump area: %d\n", ret);
766 return; 855 return;
767 } 856 }
768 857
@@ -777,7 +866,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
777 reg_dump_values[i + 2], 866 reg_dump_values[i + 2],
778 reg_dump_values[i + 3]); 867 reg_dump_values[i + 3]);
779 868
780 ieee80211_queue_work(ar->hw, &ar->restart_work); 869 queue_work(ar->workqueue, &ar->restart_work);
781} 870}
782 871
783static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, 872static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
@@ -815,53 +904,41 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
815 sizeof(ar_pci->msg_callbacks_current)); 904 sizeof(ar_pci->msg_callbacks_current));
816} 905}
817 906
818static int ath10k_pci_start_ce(struct ath10k *ar) 907static int ath10k_pci_alloc_compl(struct ath10k *ar)
819{ 908{
820 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 909 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
821 struct ath10k_ce_pipe *ce_diag = ar_pci->ce_diag;
822 const struct ce_attr *attr; 910 const struct ce_attr *attr;
823 struct ath10k_pci_pipe *pipe_info; 911 struct ath10k_pci_pipe *pipe_info;
824 struct ath10k_pci_compl *compl; 912 struct ath10k_pci_compl *compl;
825 int i, pipe_num, completions, disable_interrupts; 913 int i, pipe_num, completions;
826 914
827 spin_lock_init(&ar_pci->compl_lock); 915 spin_lock_init(&ar_pci->compl_lock);
828 INIT_LIST_HEAD(&ar_pci->compl_process); 916 INIT_LIST_HEAD(&ar_pci->compl_process);
829 917
830 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 918 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
831 pipe_info = &ar_pci->pipe_info[pipe_num]; 919 pipe_info = &ar_pci->pipe_info[pipe_num];
832 920
833 spin_lock_init(&pipe_info->pipe_lock); 921 spin_lock_init(&pipe_info->pipe_lock);
834 INIT_LIST_HEAD(&pipe_info->compl_free); 922 INIT_LIST_HEAD(&pipe_info->compl_free);
835 923
836 /* Handle Diagnostic CE specially */ 924 /* Handle Diagnostic CE specially */
837 if (pipe_info->ce_hdl == ce_diag) 925 if (pipe_info->ce_hdl == ar_pci->ce_diag)
838 continue; 926 continue;
839 927
840 attr = &host_ce_config_wlan[pipe_num]; 928 attr = &host_ce_config_wlan[pipe_num];
841 completions = 0; 929 completions = 0;
842 930
843 if (attr->src_nentries) { 931 if (attr->src_nentries)
844 disable_interrupts = attr->flags & CE_ATTR_DIS_INTR;
845 ath10k_ce_send_cb_register(pipe_info->ce_hdl,
846 ath10k_pci_ce_send_done,
847 disable_interrupts);
848 completions += attr->src_nentries; 932 completions += attr->src_nentries;
849 }
850 933
851 if (attr->dest_nentries) { 934 if (attr->dest_nentries)
852 ath10k_ce_recv_cb_register(pipe_info->ce_hdl,
853 ath10k_pci_ce_recv_data);
854 completions += attr->dest_nentries; 935 completions += attr->dest_nentries;
855 }
856
857 if (completions == 0)
858 continue;
859 936
860 for (i = 0; i < completions; i++) { 937 for (i = 0; i < completions; i++) {
861 compl = kmalloc(sizeof(*compl), GFP_KERNEL); 938 compl = kmalloc(sizeof(*compl), GFP_KERNEL);
862 if (!compl) { 939 if (!compl) {
863 ath10k_warn("No memory for completion state\n"); 940 ath10k_warn("No memory for completion state\n");
864 ath10k_pci_stop_ce(ar); 941 ath10k_pci_cleanup_ce(ar);
865 return -ENOMEM; 942 return -ENOMEM;
866 } 943 }
867 944
@@ -873,20 +950,55 @@ static int ath10k_pci_start_ce(struct ath10k *ar)
873 return 0; 950 return 0;
874} 951}
875 952
876static void ath10k_pci_stop_ce(struct ath10k *ar) 953static int ath10k_pci_setup_ce_irq(struct ath10k *ar)
877{ 954{
878 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 955 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
879 struct ath10k_pci_compl *compl; 956 const struct ce_attr *attr;
880 struct sk_buff *skb; 957 struct ath10k_pci_pipe *pipe_info;
881 int i; 958 int pipe_num, disable_interrupts;
882 959
883 ath10k_ce_disable_interrupts(ar); 960 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
961 pipe_info = &ar_pci->pipe_info[pipe_num];
962
963 /* Handle Diagnostic CE specially */
964 if (pipe_info->ce_hdl == ar_pci->ce_diag)
965 continue;
966
967 attr = &host_ce_config_wlan[pipe_num];
968
969 if (attr->src_nentries) {
970 disable_interrupts = attr->flags & CE_ATTR_DIS_INTR;
971 ath10k_ce_send_cb_register(pipe_info->ce_hdl,
972 ath10k_pci_ce_send_done,
973 disable_interrupts);
974 }
975
976 if (attr->dest_nentries)
977 ath10k_ce_recv_cb_register(pipe_info->ce_hdl,
978 ath10k_pci_ce_recv_data);
979 }
980
981 return 0;
982}
983
984static void ath10k_pci_kill_tasklet(struct ath10k *ar)
985{
986 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
987 int i;
884 988
885 /* Cancel the pending tasklet */
886 tasklet_kill(&ar_pci->intr_tq); 989 tasklet_kill(&ar_pci->intr_tq);
990 tasklet_kill(&ar_pci->msi_fw_err);
991 tasklet_kill(&ar_pci->early_irq_tasklet);
887 992
888 for (i = 0; i < CE_COUNT; i++) 993 for (i = 0; i < CE_COUNT; i++)
889 tasklet_kill(&ar_pci->pipe_info[i].intr); 994 tasklet_kill(&ar_pci->pipe_info[i].intr);
995}
996
997static void ath10k_pci_stop_ce(struct ath10k *ar)
998{
999 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1000 struct ath10k_pci_compl *compl;
1001 struct sk_buff *skb;
890 1002
891 /* Mark pending completions as aborted, so that upper layers free up 1003 /* Mark pending completions as aborted, so that upper layers free up
892 * their associated resources */ 1004 * their associated resources */
@@ -920,7 +1032,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
920 spin_unlock_bh(&ar_pci->compl_lock); 1032 spin_unlock_bh(&ar_pci->compl_lock);
921 1033
922 /* Free unused completions for each pipe. */ 1034 /* Free unused completions for each pipe. */
923 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 1035 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
924 pipe_info = &ar_pci->pipe_info[pipe_num]; 1036 pipe_info = &ar_pci->pipe_info[pipe_num];
925 1037
926 spin_lock_bh(&pipe_info->pipe_lock); 1038 spin_lock_bh(&pipe_info->pipe_lock);
@@ -974,8 +1086,8 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
974 case ATH10K_PCI_COMPL_RECV: 1086 case ATH10K_PCI_COMPL_RECV:
975 ret = ath10k_pci_post_rx_pipe(compl->pipe_info, 1); 1087 ret = ath10k_pci_post_rx_pipe(compl->pipe_info, 1);
976 if (ret) { 1088 if (ret) {
977 ath10k_warn("Unable to post recv buffer for pipe: %d\n", 1089 ath10k_warn("failed to post RX buffer for pipe %d: %d\n",
978 compl->pipe_info->pipe_num); 1090 compl->pipe_info->pipe_num, ret);
979 break; 1091 break;
980 } 1092 }
981 1093
@@ -1114,7 +1226,7 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
1114 for (i = 0; i < num; i++) { 1226 for (i = 0; i < num; i++) {
1115 skb = dev_alloc_skb(pipe_info->buf_sz); 1227 skb = dev_alloc_skb(pipe_info->buf_sz);
1116 if (!skb) { 1228 if (!skb) {
1117 ath10k_warn("could not allocate skbuff for pipe %d\n", 1229 ath10k_warn("failed to allocate skbuff for pipe %d\n",
1118 num); 1230 num);
1119 ret = -ENOMEM; 1231 ret = -ENOMEM;
1120 goto err; 1232 goto err;
@@ -1127,7 +1239,7 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
1127 DMA_FROM_DEVICE); 1239 DMA_FROM_DEVICE);
1128 1240
1129 if (unlikely(dma_mapping_error(ar->dev, ce_data))) { 1241 if (unlikely(dma_mapping_error(ar->dev, ce_data))) {
1130 ath10k_warn("could not dma map skbuff\n"); 1242 ath10k_warn("failed to DMA map sk_buff\n");
1131 dev_kfree_skb_any(skb); 1243 dev_kfree_skb_any(skb);
1132 ret = -EIO; 1244 ret = -EIO;
1133 goto err; 1245 goto err;
@@ -1142,7 +1254,7 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
1142 ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb, 1254 ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb,
1143 ce_data); 1255 ce_data);
1144 if (ret) { 1256 if (ret) {
1145 ath10k_warn("could not enqueue to pipe %d (%d)\n", 1257 ath10k_warn("failed to enqueue to pipe %d: %d\n",
1146 num, ret); 1258 num, ret);
1147 goto err; 1259 goto err;
1148 } 1260 }
@@ -1162,7 +1274,7 @@ static int ath10k_pci_post_rx(struct ath10k *ar)
1162 const struct ce_attr *attr; 1274 const struct ce_attr *attr;
1163 int pipe_num, ret = 0; 1275 int pipe_num, ret = 0;
1164 1276
1165 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 1277 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
1166 pipe_info = &ar_pci->pipe_info[pipe_num]; 1278 pipe_info = &ar_pci->pipe_info[pipe_num];
1167 attr = &host_ce_config_wlan[pipe_num]; 1279 attr = &host_ce_config_wlan[pipe_num];
1168 1280
@@ -1172,8 +1284,8 @@ static int ath10k_pci_post_rx(struct ath10k *ar)
1172 ret = ath10k_pci_post_rx_pipe(pipe_info, 1284 ret = ath10k_pci_post_rx_pipe(pipe_info,
1173 attr->dest_nentries - 1); 1285 attr->dest_nentries - 1);
1174 if (ret) { 1286 if (ret) {
1175 ath10k_warn("Unable to replenish recv buffers for pipe: %d\n", 1287 ath10k_warn("failed to post RX buffer for pipe %d: %d\n",
1176 pipe_num); 1288 pipe_num, ret);
1177 1289
1178 for (; pipe_num >= 0; pipe_num--) { 1290 for (; pipe_num >= 0; pipe_num--) {
1179 pipe_info = &ar_pci->pipe_info[pipe_num]; 1291 pipe_info = &ar_pci->pipe_info[pipe_num];
@@ -1189,23 +1301,58 @@ static int ath10k_pci_post_rx(struct ath10k *ar)
1189static int ath10k_pci_hif_start(struct ath10k *ar) 1301static int ath10k_pci_hif_start(struct ath10k *ar)
1190{ 1302{
1191 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1303 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1192 int ret; 1304 int ret, ret_early;
1193 1305
1194 ret = ath10k_pci_start_ce(ar); 1306 ath10k_pci_free_early_irq(ar);
1307 ath10k_pci_kill_tasklet(ar);
1308
1309 ret = ath10k_pci_alloc_compl(ar);
1195 if (ret) { 1310 if (ret) {
1196 ath10k_warn("could not start CE (%d)\n", ret); 1311 ath10k_warn("failed to allocate CE completions: %d\n", ret);
1197 return ret; 1312 goto err_early_irq;
1313 }
1314
1315 ret = ath10k_pci_request_irq(ar);
1316 if (ret) {
1317 ath10k_warn("failed to post RX buffers for all pipes: %d\n",
1318 ret);
1319 goto err_free_compl;
1320 }
1321
1322 ret = ath10k_pci_setup_ce_irq(ar);
1323 if (ret) {
1324 ath10k_warn("failed to setup CE interrupts: %d\n", ret);
1325 goto err_stop;
1198 } 1326 }
1199 1327
1200 /* Post buffers once to start things off. */ 1328 /* Post buffers once to start things off. */
1201 ret = ath10k_pci_post_rx(ar); 1329 ret = ath10k_pci_post_rx(ar);
1202 if (ret) { 1330 if (ret) {
1203 ath10k_warn("could not post rx pipes (%d)\n", ret); 1331 ath10k_warn("failed to post RX buffers for all pipes: %d\n",
1204 return ret; 1332 ret);
1333 goto err_stop;
1205 } 1334 }
1206 1335
1207 ar_pci->started = 1; 1336 ar_pci->started = 1;
1208 return 0; 1337 return 0;
1338
1339err_stop:
1340 ath10k_ce_disable_interrupts(ar);
1341 ath10k_pci_free_irq(ar);
1342 ath10k_pci_kill_tasklet(ar);
1343 ath10k_pci_stop_ce(ar);
1344 ath10k_pci_process_ce(ar);
1345err_free_compl:
1346 ath10k_pci_cleanup_ce(ar);
1347err_early_irq:
1348 /* Though there should be no interrupts (device was reset)
1349 * power_down() expects the early IRQ to be installed as per the
1350 * driver lifecycle. */
1351 ret_early = ath10k_pci_request_early_irq(ar);
1352 if (ret_early)
1353 ath10k_warn("failed to re-enable early irq: %d\n", ret_early);
1354
1355 return ret;
1209} 1356}
1210 1357
1211static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) 1358static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info)
@@ -1271,6 +1418,13 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info)
1271 * Indicate the completion to higer layer to free 1418 * Indicate the completion to higer layer to free
1272 * the buffer 1419 * the buffer
1273 */ 1420 */
1421
1422 if (!netbuf) {
1423 ath10k_warn("invalid sk_buff on CE %d - NULL pointer. firmware crashed?\n",
1424 ce_hdl->id);
1425 continue;
1426 }
1427
1274 ATH10K_SKB_CB(netbuf)->is_aborted = true; 1428 ATH10K_SKB_CB(netbuf)->is_aborted = true;
1275 ar_pci->msg_callbacks_current.tx_completion(ar, 1429 ar_pci->msg_callbacks_current.tx_completion(ar,
1276 netbuf, 1430 netbuf,
@@ -1291,7 +1445,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
1291 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1445 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1292 int pipe_num; 1446 int pipe_num;
1293 1447
1294 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 1448 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
1295 struct ath10k_pci_pipe *pipe_info; 1449 struct ath10k_pci_pipe *pipe_info;
1296 1450
1297 pipe_info = &ar_pci->pipe_info[pipe_num]; 1451 pipe_info = &ar_pci->pipe_info[pipe_num];
@@ -1306,7 +1460,7 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
1306 struct ath10k_pci_pipe *pipe_info; 1460 struct ath10k_pci_pipe *pipe_info;
1307 int pipe_num; 1461 int pipe_num;
1308 1462
1309 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 1463 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
1310 pipe_info = &ar_pci->pipe_info[pipe_num]; 1464 pipe_info = &ar_pci->pipe_info[pipe_num];
1311 if (pipe_info->ce_hdl) { 1465 if (pipe_info->ce_hdl) {
1312 ath10k_ce_deinit(pipe_info->ce_hdl); 1466 ath10k_ce_deinit(pipe_info->ce_hdl);
@@ -1316,27 +1470,25 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
1316 } 1470 }
1317} 1471}
1318 1472
1319static void ath10k_pci_disable_irqs(struct ath10k *ar)
1320{
1321 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1322 int i;
1323
1324 for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
1325 disable_irq(ar_pci->pdev->irq + i);
1326}
1327
1328static void ath10k_pci_hif_stop(struct ath10k *ar) 1473static void ath10k_pci_hif_stop(struct ath10k *ar)
1329{ 1474{
1330 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1475 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1476 int ret;
1331 1477
1332 ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__); 1478 ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
1333 1479
1334 /* Irqs are never explicitly re-enabled. They are implicitly re-enabled 1480 ret = ath10k_ce_disable_interrupts(ar);
1335 * by ath10k_pci_start_intr(). */ 1481 if (ret)
1336 ath10k_pci_disable_irqs(ar); 1482 ath10k_warn("failed to disable CE interrupts: %d\n", ret);
1337 1483
1484 ath10k_pci_free_irq(ar);
1485 ath10k_pci_kill_tasklet(ar);
1338 ath10k_pci_stop_ce(ar); 1486 ath10k_pci_stop_ce(ar);
1339 1487
1488 ret = ath10k_pci_request_early_irq(ar);
1489 if (ret)
1490 ath10k_warn("failed to re-enable early irq: %d\n", ret);
1491
1340 /* At this point, asynchronous threads are stopped, the target should 1492 /* At this point, asynchronous threads are stopped, the target should
1341 * not DMA nor interrupt. We process the leftovers and then free 1493 * not DMA nor interrupt. We process the leftovers and then free
1342 * everything else up. */ 1494 * everything else up. */
@@ -1345,6 +1497,13 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
1345 ath10k_pci_cleanup_ce(ar); 1497 ath10k_pci_cleanup_ce(ar);
1346 ath10k_pci_buffer_cleanup(ar); 1498 ath10k_pci_buffer_cleanup(ar);
1347 1499
1500 /* Make the sure the device won't access any structures on the host by
1501 * resetting it. The device was fed with PCI CE ringbuffer
1502 * configuration during init. If ringbuffers are freed and the device
1503 * were to access them this could lead to memory corruption on the
1504 * host. */
1505 ath10k_pci_device_reset(ar);
1506
1348 ar_pci->started = 0; 1507 ar_pci->started = 0;
1349} 1508}
1350 1509
@@ -1363,6 +1522,8 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
1363 void *treq, *tresp = NULL; 1522 void *treq, *tresp = NULL;
1364 int ret = 0; 1523 int ret = 0;
1365 1524
1525 might_sleep();
1526
1366 if (resp && !resp_len) 1527 if (resp && !resp_len)
1367 return -EINVAL; 1528 return -EINVAL;
1368 1529
@@ -1403,14 +1564,12 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
1403 if (ret) 1564 if (ret)
1404 goto err_resp; 1565 goto err_resp;
1405 1566
1406 ret = wait_for_completion_timeout(&xfer.done, 1567 ret = ath10k_pci_bmi_wait(ce_tx, ce_rx, &xfer);
1407 BMI_COMMUNICATION_TIMEOUT_HZ); 1568 if (ret) {
1408 if (ret <= 0) {
1409 u32 unused_buffer; 1569 u32 unused_buffer;
1410 unsigned int unused_nbytes; 1570 unsigned int unused_nbytes;
1411 unsigned int unused_id; 1571 unsigned int unused_id;
1412 1572
1413 ret = -ETIMEDOUT;
1414 ath10k_ce_cancel_send_next(ce_tx, NULL, &unused_buffer, 1573 ath10k_ce_cancel_send_next(ce_tx, NULL, &unused_buffer,
1415 &unused_nbytes, &unused_id); 1574 &unused_nbytes, &unused_id);
1416 } else { 1575 } else {
@@ -1478,6 +1637,25 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
1478 complete(&xfer->done); 1637 complete(&xfer->done);
1479} 1638}
1480 1639
1640static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
1641 struct ath10k_ce_pipe *rx_pipe,
1642 struct bmi_xfer *xfer)
1643{
1644 unsigned long timeout = jiffies + BMI_COMMUNICATION_TIMEOUT_HZ;
1645
1646 while (time_before_eq(jiffies, timeout)) {
1647 ath10k_pci_bmi_send_done(tx_pipe);
1648 ath10k_pci_bmi_recv_data(rx_pipe);
1649
1650 if (completion_done(&xfer->done))
1651 return 0;
1652
1653 schedule();
1654 }
1655
1656 return -ETIMEDOUT;
1657}
1658
1481/* 1659/*
1482 * Map from service/endpoint to Copy Engine. 1660 * Map from service/endpoint to Copy Engine.
1483 * This table is derived from the CE_PCI TABLE, above. 1661 * This table is derived from the CE_PCI TABLE, above.
@@ -1587,7 +1765,7 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
1587 CORE_CTRL_ADDRESS, 1765 CORE_CTRL_ADDRESS,
1588 &core_ctrl); 1766 &core_ctrl);
1589 if (ret) { 1767 if (ret) {
1590 ath10k_warn("Unable to read core ctrl\n"); 1768 ath10k_warn("failed to read core_ctrl: %d\n", ret);
1591 return ret; 1769 return ret;
1592 } 1770 }
1593 1771
@@ -1597,10 +1775,13 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
1597 ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS | 1775 ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS |
1598 CORE_CTRL_ADDRESS, 1776 CORE_CTRL_ADDRESS,
1599 core_ctrl); 1777 core_ctrl);
1600 if (ret) 1778 if (ret) {
1601 ath10k_warn("Unable to set interrupt mask\n"); 1779 ath10k_warn("failed to set target CPU interrupt mask: %d\n",
1780 ret);
1781 return ret;
1782 }
1602 1783
1603 return ret; 1784 return 0;
1604} 1785}
1605 1786
1606static int ath10k_pci_init_config(struct ath10k *ar) 1787static int ath10k_pci_init_config(struct ath10k *ar)
@@ -1751,7 +1932,7 @@ static int ath10k_pci_ce_init(struct ath10k *ar)
1751 const struct ce_attr *attr; 1932 const struct ce_attr *attr;
1752 int pipe_num; 1933 int pipe_num;
1753 1934
1754 for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { 1935 for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
1755 pipe_info = &ar_pci->pipe_info[pipe_num]; 1936 pipe_info = &ar_pci->pipe_info[pipe_num];
1756 pipe_info->pipe_num = pipe_num; 1937 pipe_info->pipe_num = pipe_num;
1757 pipe_info->hif_ce_state = ar; 1938 pipe_info->hif_ce_state = ar;
@@ -1759,7 +1940,7 @@ static int ath10k_pci_ce_init(struct ath10k *ar)
1759 1940
1760 pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr); 1941 pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr);
1761 if (pipe_info->ce_hdl == NULL) { 1942 if (pipe_info->ce_hdl == NULL) {
1762 ath10k_err("Unable to initialize CE for pipe: %d\n", 1943 ath10k_err("failed to initialize CE for pipe: %d\n",
1763 pipe_num); 1944 pipe_num);
1764 1945
1765 /* It is safe to call it here. It checks if ce_hdl is 1946 /* It is safe to call it here. It checks if ce_hdl is
@@ -1768,31 +1949,18 @@ static int ath10k_pci_ce_init(struct ath10k *ar)
1768 return -1; 1949 return -1;
1769 } 1950 }
1770 1951
1771 if (pipe_num == ar_pci->ce_count - 1) { 1952 if (pipe_num == CE_COUNT - 1) {
1772 /* 1953 /*
1773 * Reserve the ultimate CE for 1954 * Reserve the ultimate CE for
1774 * diagnostic Window support 1955 * diagnostic Window support
1775 */ 1956 */
1776 ar_pci->ce_diag = 1957 ar_pci->ce_diag = pipe_info->ce_hdl;
1777 ar_pci->pipe_info[ar_pci->ce_count - 1].ce_hdl;
1778 continue; 1958 continue;
1779 } 1959 }
1780 1960
1781 pipe_info->buf_sz = (size_t) (attr->src_sz_max); 1961 pipe_info->buf_sz = (size_t) (attr->src_sz_max);
1782 } 1962 }
1783 1963
1784 /*
1785 * Initially, establish CE completion handlers for use with BMI.
1786 * These are overwritten with generic handlers after we exit BMI phase.
1787 */
1788 pipe_info = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG];
1789 ath10k_ce_send_cb_register(pipe_info->ce_hdl,
1790 ath10k_pci_bmi_send_done, 0);
1791
1792 pipe_info = &ar_pci->pipe_info[BMI_CE_NUM_TO_HOST];
1793 ath10k_ce_recv_cb_register(pipe_info->ce_hdl,
1794 ath10k_pci_bmi_recv_data);
1795
1796 return 0; 1964 return 0;
1797} 1965}
1798 1966
@@ -1828,14 +1996,9 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
1828static int ath10k_pci_hif_power_up(struct ath10k *ar) 1996static int ath10k_pci_hif_power_up(struct ath10k *ar)
1829{ 1997{
1830 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1998 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1999 const char *irq_mode;
1831 int ret; 2000 int ret;
1832 2001
1833 ret = ath10k_pci_start_intr(ar);
1834 if (ret) {
1835 ath10k_err("could not start interrupt handling (%d)\n", ret);
1836 goto err;
1837 }
1838
1839 /* 2002 /*
1840 * Bring the target up cleanly. 2003 * Bring the target up cleanly.
1841 * 2004 *
@@ -1846,39 +2009,80 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
1846 * is in an unexpected state. We try to catch that here in order to 2009 * is in an unexpected state. We try to catch that here in order to
1847 * reset the Target and retry the probe. 2010 * reset the Target and retry the probe.
1848 */ 2011 */
1849 ath10k_pci_device_reset(ar); 2012 ret = ath10k_pci_device_reset(ar);
1850 2013 if (ret) {
1851 ret = ath10k_pci_reset_target(ar); 2014 ath10k_err("failed to reset target: %d\n", ret);
1852 if (ret) 2015 goto err;
1853 goto err_irq; 2016 }
1854 2017
1855 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) 2018 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
1856 /* Force AWAKE forever */ 2019 /* Force AWAKE forever */
1857 ath10k_do_pci_wake(ar); 2020 ath10k_do_pci_wake(ar);
1858 2021
1859 ret = ath10k_pci_ce_init(ar); 2022 ret = ath10k_pci_ce_init(ar);
1860 if (ret) 2023 if (ret) {
2024 ath10k_err("failed to initialize CE: %d\n", ret);
1861 goto err_ps; 2025 goto err_ps;
2026 }
1862 2027
1863 ret = ath10k_pci_init_config(ar); 2028 ret = ath10k_ce_disable_interrupts(ar);
1864 if (ret) 2029 if (ret) {
2030 ath10k_err("failed to disable CE interrupts: %d\n", ret);
1865 goto err_ce; 2031 goto err_ce;
2032 }
1866 2033
1867 ret = ath10k_pci_wake_target_cpu(ar); 2034 ret = ath10k_pci_init_irq(ar);
1868 if (ret) { 2035 if (ret) {
1869 ath10k_err("could not wake up target CPU (%d)\n", ret); 2036 ath10k_err("failed to init irqs: %d\n", ret);
1870 goto err_ce; 2037 goto err_ce;
1871 } 2038 }
1872 2039
2040 ret = ath10k_pci_request_early_irq(ar);
2041 if (ret) {
2042 ath10k_err("failed to request early irq: %d\n", ret);
2043 goto err_deinit_irq;
2044 }
2045
2046 ret = ath10k_pci_wait_for_target_init(ar);
2047 if (ret) {
2048 ath10k_err("failed to wait for target to init: %d\n", ret);
2049 goto err_free_early_irq;
2050 }
2051
2052 ret = ath10k_pci_init_config(ar);
2053 if (ret) {
2054 ath10k_err("failed to setup init config: %d\n", ret);
2055 goto err_free_early_irq;
2056 }
2057
2058 ret = ath10k_pci_wake_target_cpu(ar);
2059 if (ret) {
2060 ath10k_err("could not wake up target CPU: %d\n", ret);
2061 goto err_free_early_irq;
2062 }
2063
2064 if (ar_pci->num_msi_intrs > 1)
2065 irq_mode = "MSI-X";
2066 else if (ar_pci->num_msi_intrs == 1)
2067 irq_mode = "MSI";
2068 else
2069 irq_mode = "legacy";
2070
2071 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
2072 ath10k_info("pci irq %s\n", irq_mode);
2073
1873 return 0; 2074 return 0;
1874 2075
2076err_free_early_irq:
2077 ath10k_pci_free_early_irq(ar);
2078err_deinit_irq:
2079 ath10k_pci_deinit_irq(ar);
1875err_ce: 2080err_ce:
1876 ath10k_pci_ce_deinit(ar); 2081 ath10k_pci_ce_deinit(ar);
2082 ath10k_pci_device_reset(ar);
1877err_ps: 2083err_ps:
1878 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) 2084 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
1879 ath10k_do_pci_sleep(ar); 2085 ath10k_do_pci_sleep(ar);
1880err_irq:
1881 ath10k_pci_stop_intr(ar);
1882err: 2086err:
1883 return ret; 2087 return ret;
1884} 2088}
@@ -1887,7 +2091,10 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar)
1887{ 2091{
1888 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2092 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1889 2093
1890 ath10k_pci_stop_intr(ar); 2094 ath10k_pci_free_early_irq(ar);
2095 ath10k_pci_kill_tasklet(ar);
2096 ath10k_pci_deinit_irq(ar);
2097 ath10k_pci_device_reset(ar);
1891 2098
1892 ath10k_pci_ce_deinit(ar); 2099 ath10k_pci_ce_deinit(ar);
1893 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) 2100 if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
@@ -2023,25 +2230,10 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
2023 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2230 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2024 2231
2025 if (ar_pci->num_msi_intrs == 0) { 2232 if (ar_pci->num_msi_intrs == 0) {
2026 /* 2233 if (!ath10k_pci_irq_pending(ar))
2027 * IMPORTANT: INTR_CLR regiser has to be set after 2234 return IRQ_NONE;
2028 * INTR_ENABLE is set to 0, otherwise interrupt can not be 2235
2029 * really cleared. 2236 ath10k_pci_disable_and_clear_legacy_irq(ar);
2030 */
2031 iowrite32(0, ar_pci->mem +
2032 (SOC_CORE_BASE_ADDRESS |
2033 PCIE_INTR_ENABLE_ADDRESS));
2034 iowrite32(PCIE_INTR_FIRMWARE_MASK |
2035 PCIE_INTR_CE_MASK_ALL,
2036 ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
2037 PCIE_INTR_CLR_ADDRESS));
2038 /*
2039 * IMPORTANT: this extra read transaction is required to
2040 * flush the posted write buffer.
2041 */
2042 (void) ioread32(ar_pci->mem +
2043 (SOC_CORE_BASE_ADDRESS |
2044 PCIE_INTR_ENABLE_ADDRESS));
2045 } 2237 }
2046 2238
2047 tasklet_schedule(&ar_pci->intr_tq); 2239 tasklet_schedule(&ar_pci->intr_tq);
@@ -2049,6 +2241,34 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
2049 return IRQ_HANDLED; 2241 return IRQ_HANDLED;
2050} 2242}
2051 2243
2244static void ath10k_pci_early_irq_tasklet(unsigned long data)
2245{
2246 struct ath10k *ar = (struct ath10k *)data;
2247 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2248 u32 fw_ind;
2249 int ret;
2250
2251 ret = ath10k_pci_wake(ar);
2252 if (ret) {
2253 ath10k_warn("failed to wake target in early irq tasklet: %d\n",
2254 ret);
2255 return;
2256 }
2257
2258 fw_ind = ath10k_pci_read32(ar, ar_pci->fw_indicator_address);
2259 if (fw_ind & FW_IND_EVENT_PENDING) {
2260 ath10k_pci_write32(ar, ar_pci->fw_indicator_address,
2261 fw_ind & ~FW_IND_EVENT_PENDING);
2262
2263 /* Some structures are unavailable during early boot or at
2264 * driver teardown so just print that the device has crashed. */
2265 ath10k_warn("device crashed - no diagnostics available\n");
2266 }
2267
2268 ath10k_pci_sleep(ar);
2269 ath10k_pci_enable_legacy_irq(ar);
2270}
2271
2052static void ath10k_pci_tasklet(unsigned long data) 2272static void ath10k_pci_tasklet(unsigned long data)
2053{ 2273{
2054 struct ath10k *ar = (struct ath10k *)data; 2274 struct ath10k *ar = (struct ath10k *)data;
@@ -2057,40 +2277,22 @@ static void ath10k_pci_tasklet(unsigned long data)
2057 ath10k_pci_fw_interrupt_handler(ar); /* FIXME: Handle FW error */ 2277 ath10k_pci_fw_interrupt_handler(ar); /* FIXME: Handle FW error */
2058 ath10k_ce_per_engine_service_any(ar); 2278 ath10k_ce_per_engine_service_any(ar);
2059 2279
2060 if (ar_pci->num_msi_intrs == 0) { 2280 /* Re-enable legacy irq that was disabled in the irq handler */
2061 /* Enable Legacy PCI line interrupts */ 2281 if (ar_pci->num_msi_intrs == 0)
2062 iowrite32(PCIE_INTR_FIRMWARE_MASK | 2282 ath10k_pci_enable_legacy_irq(ar);
2063 PCIE_INTR_CE_MASK_ALL,
2064 ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
2065 PCIE_INTR_ENABLE_ADDRESS));
2066 /*
2067 * IMPORTANT: this extra read transaction is required to
2068 * flush the posted write buffer
2069 */
2070 (void) ioread32(ar_pci->mem +
2071 (SOC_CORE_BASE_ADDRESS |
2072 PCIE_INTR_ENABLE_ADDRESS));
2073 }
2074} 2283}
2075 2284
2076static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num) 2285static int ath10k_pci_request_irq_msix(struct ath10k *ar)
2077{ 2286{
2078 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2287 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2079 int ret; 2288 int ret, i;
2080 int i;
2081
2082 ret = pci_enable_msi_block(ar_pci->pdev, num);
2083 if (ret)
2084 return ret;
2085 2289
2086 ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, 2290 ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW,
2087 ath10k_pci_msi_fw_handler, 2291 ath10k_pci_msi_fw_handler,
2088 IRQF_SHARED, "ath10k_pci", ar); 2292 IRQF_SHARED, "ath10k_pci", ar);
2089 if (ret) { 2293 if (ret) {
2090 ath10k_warn("request_irq(%d) failed %d\n", 2294 ath10k_warn("failed to request MSI-X fw irq %d: %d\n",
2091 ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); 2295 ar_pci->pdev->irq + MSI_ASSIGN_FW, ret);
2092
2093 pci_disable_msi(ar_pci->pdev);
2094 return ret; 2296 return ret;
2095 } 2297 }
2096 2298
@@ -2099,44 +2301,38 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
2099 ath10k_pci_per_engine_handler, 2301 ath10k_pci_per_engine_handler,
2100 IRQF_SHARED, "ath10k_pci", ar); 2302 IRQF_SHARED, "ath10k_pci", ar);
2101 if (ret) { 2303 if (ret) {
2102 ath10k_warn("request_irq(%d) failed %d\n", 2304 ath10k_warn("failed to request MSI-X ce irq %d: %d\n",
2103 ar_pci->pdev->irq + i, ret); 2305 ar_pci->pdev->irq + i, ret);
2104 2306
2105 for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) 2307 for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--)
2106 free_irq(ar_pci->pdev->irq + i, ar); 2308 free_irq(ar_pci->pdev->irq + i, ar);
2107 2309
2108 free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar); 2310 free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar);
2109 pci_disable_msi(ar_pci->pdev);
2110 return ret; 2311 return ret;
2111 } 2312 }
2112 } 2313 }
2113 2314
2114 ath10k_info("MSI-X interrupt handling (%d intrs)\n", num);
2115 return 0; 2315 return 0;
2116} 2316}
2117 2317
2118static int ath10k_pci_start_intr_msi(struct ath10k *ar) 2318static int ath10k_pci_request_irq_msi(struct ath10k *ar)
2119{ 2319{
2120 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2320 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2121 int ret; 2321 int ret;
2122 2322
2123 ret = pci_enable_msi(ar_pci->pdev);
2124 if (ret < 0)
2125 return ret;
2126
2127 ret = request_irq(ar_pci->pdev->irq, 2323 ret = request_irq(ar_pci->pdev->irq,
2128 ath10k_pci_interrupt_handler, 2324 ath10k_pci_interrupt_handler,
2129 IRQF_SHARED, "ath10k_pci", ar); 2325 IRQF_SHARED, "ath10k_pci", ar);
2130 if (ret < 0) { 2326 if (ret) {
2131 pci_disable_msi(ar_pci->pdev); 2327 ath10k_warn("failed to request MSI irq %d: %d\n",
2328 ar_pci->pdev->irq, ret);
2132 return ret; 2329 return ret;
2133 } 2330 }
2134 2331
2135 ath10k_info("MSI interrupt handling\n");
2136 return 0; 2332 return 0;
2137} 2333}
2138 2334
2139static int ath10k_pci_start_intr_legacy(struct ath10k *ar) 2335static int ath10k_pci_request_irq_legacy(struct ath10k *ar)
2140{ 2336{
2141 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2337 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2142 int ret; 2338 int ret;
@@ -2144,112 +2340,165 @@ static int ath10k_pci_start_intr_legacy(struct ath10k *ar)
2144 ret = request_irq(ar_pci->pdev->irq, 2340 ret = request_irq(ar_pci->pdev->irq,
2145 ath10k_pci_interrupt_handler, 2341 ath10k_pci_interrupt_handler,
2146 IRQF_SHARED, "ath10k_pci", ar); 2342 IRQF_SHARED, "ath10k_pci", ar);
2147 if (ret < 0) 2343 if (ret) {
2344 ath10k_warn("failed to request legacy irq %d: %d\n",
2345 ar_pci->pdev->irq, ret);
2148 return ret; 2346 return ret;
2347 }
2149 2348
2150 /* 2349 return 0;
2151 * Make sure to wake the Target before enabling Legacy 2350}
2152 * Interrupt. 2351
2153 */ 2352static int ath10k_pci_request_irq(struct ath10k *ar)
2154 iowrite32(PCIE_SOC_WAKE_V_MASK, 2353{
2155 ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + 2354 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2156 PCIE_SOC_WAKE_ADDRESS);
2157 2355
2158 ath10k_pci_wait(ar); 2356 switch (ar_pci->num_msi_intrs) {
2357 case 0:
2358 return ath10k_pci_request_irq_legacy(ar);
2359 case 1:
2360 return ath10k_pci_request_irq_msi(ar);
2361 case MSI_NUM_REQUEST:
2362 return ath10k_pci_request_irq_msix(ar);
2363 }
2159 2364
2160 /* 2365 ath10k_warn("unknown irq configuration upon request\n");
2161 * A potential race occurs here: The CORE_BASE write 2366 return -EINVAL;
2162 * depends on target correctly decoding AXI address but
2163 * host won't know when target writes BAR to CORE_CTRL.
2164 * This write might get lost if target has NOT written BAR.
2165 * For now, fix the race by repeating the write in below
2166 * synchronization checking.
2167 */
2168 iowrite32(PCIE_INTR_FIRMWARE_MASK |
2169 PCIE_INTR_CE_MASK_ALL,
2170 ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
2171 PCIE_INTR_ENABLE_ADDRESS));
2172 iowrite32(PCIE_SOC_WAKE_RESET,
2173 ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
2174 PCIE_SOC_WAKE_ADDRESS);
2175
2176 ath10k_info("legacy interrupt handling\n");
2177 return 0;
2178} 2367}
2179 2368
2180static int ath10k_pci_start_intr(struct ath10k *ar) 2369static void ath10k_pci_free_irq(struct ath10k *ar)
2370{
2371 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2372 int i;
2373
2374 /* There's at least one interrupt irregardless whether its legacy INTR
2375 * or MSI or MSI-X */
2376 for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
2377 free_irq(ar_pci->pdev->irq + i, ar);
2378}
2379
2380static void ath10k_pci_init_irq_tasklets(struct ath10k *ar)
2181{ 2381{
2182 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2382 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2183 int num = MSI_NUM_REQUEST;
2184 int ret;
2185 int i; 2383 int i;
2186 2384
2187 tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long) ar); 2385 tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar);
2188 tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, 2386 tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet,
2189 (unsigned long) ar); 2387 (unsigned long)ar);
2388 tasklet_init(&ar_pci->early_irq_tasklet, ath10k_pci_early_irq_tasklet,
2389 (unsigned long)ar);
2190 2390
2191 for (i = 0; i < CE_COUNT; i++) { 2391 for (i = 0; i < CE_COUNT; i++) {
2192 ar_pci->pipe_info[i].ar_pci = ar_pci; 2392 ar_pci->pipe_info[i].ar_pci = ar_pci;
2193 tasklet_init(&ar_pci->pipe_info[i].intr, 2393 tasklet_init(&ar_pci->pipe_info[i].intr, ath10k_pci_ce_tasklet,
2194 ath10k_pci_ce_tasklet,
2195 (unsigned long)&ar_pci->pipe_info[i]); 2394 (unsigned long)&ar_pci->pipe_info[i]);
2196 } 2395 }
2396}
2397
2398static int ath10k_pci_init_irq(struct ath10k *ar)
2399{
2400 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2401 bool msix_supported = test_bit(ATH10K_PCI_FEATURE_MSI_X,
2402 ar_pci->features);
2403 int ret;
2197 2404
2198 if (!test_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features)) 2405 ath10k_pci_init_irq_tasklets(ar);
2199 num = 1;
2200 2406
2201 if (num > 1) { 2407 if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO &&
2202 ret = ath10k_pci_start_intr_msix(ar, num); 2408 !test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
2409 ath10k_info("limiting irq mode to: %d\n", ath10k_pci_irq_mode);
2410
2411 /* Try MSI-X */
2412 if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) {
2413 ar_pci->num_msi_intrs = MSI_NUM_REQUEST;
2414 ret = pci_enable_msi_block(ar_pci->pdev, ar_pci->num_msi_intrs);
2203 if (ret == 0) 2415 if (ret == 0)
2204 goto exit; 2416 return 0;
2417 if (ret > 0)
2418 pci_disable_msi(ar_pci->pdev);
2205 2419
2206 ath10k_warn("MSI-X didn't succeed (%d), trying MSI\n", ret); 2420 /* fall-through */
2207 num = 1;
2208 } 2421 }
2209 2422
2210 if (num == 1) { 2423 /* Try MSI */
2211 ret = ath10k_pci_start_intr_msi(ar); 2424 if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_LEGACY) {
2425 ar_pci->num_msi_intrs = 1;
2426 ret = pci_enable_msi(ar_pci->pdev);
2212 if (ret == 0) 2427 if (ret == 0)
2213 goto exit; 2428 return 0;
2214 2429
2215 ath10k_warn("MSI didn't succeed (%d), trying legacy INTR\n", 2430 /* fall-through */
2216 ret);
2217 num = 0;
2218 } 2431 }
2219 2432
2220 ret = ath10k_pci_start_intr_legacy(ar); 2433 /* Try legacy irq
2434 *
2435 * A potential race occurs here: The CORE_BASE write
2436 * depends on target correctly decoding AXI address but
2437 * host won't know when target writes BAR to CORE_CTRL.
2438 * This write might get lost if target has NOT written BAR.
2439 * For now, fix the race by repeating the write in below
2440 * synchronization checking. */
2441 ar_pci->num_msi_intrs = 0;
2221 2442
2222exit: 2443 ret = ath10k_pci_wake(ar);
2223 ar_pci->num_msi_intrs = num; 2444 if (ret) {
2224 ar_pci->ce_count = CE_COUNT; 2445 ath10k_warn("failed to wake target: %d\n", ret);
2225 return ret; 2446 return ret;
2447 }
2448
2449 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS,
2450 PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
2451 ath10k_pci_sleep(ar);
2452
2453 return 0;
2226} 2454}
2227 2455
2228static void ath10k_pci_stop_intr(struct ath10k *ar) 2456static int ath10k_pci_deinit_irq_legacy(struct ath10k *ar)
2229{ 2457{
2230 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2458 int ret;
2231 int i;
2232 2459
2233 /* There's at least one interrupt irregardless whether its legacy INTR 2460 ret = ath10k_pci_wake(ar);
2234 * or MSI or MSI-X */ 2461 if (ret) {
2235 for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) 2462 ath10k_warn("failed to wake target: %d\n", ret);
2236 free_irq(ar_pci->pdev->irq + i, ar); 2463 return ret;
2464 }
2237 2465
2238 if (ar_pci->num_msi_intrs > 0) 2466 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS,
2467 0);
2468 ath10k_pci_sleep(ar);
2469
2470 return 0;
2471}
2472
2473static int ath10k_pci_deinit_irq(struct ath10k *ar)
2474{
2475 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2476
2477 switch (ar_pci->num_msi_intrs) {
2478 case 0:
2479 return ath10k_pci_deinit_irq_legacy(ar);
2480 case 1:
2481 /* fall-through */
2482 case MSI_NUM_REQUEST:
2239 pci_disable_msi(ar_pci->pdev); 2483 pci_disable_msi(ar_pci->pdev);
2484 return 0;
2485 }
2486
2487 ath10k_warn("unknown irq configuration upon deinit\n");
2488 return -EINVAL;
2240} 2489}
2241 2490
2242static int ath10k_pci_reset_target(struct ath10k *ar) 2491static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
2243{ 2492{
2244 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2493 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2245 int wait_limit = 300; /* 3 sec */ 2494 int wait_limit = 300; /* 3 sec */
2495 int ret;
2246 2496
2247 /* Wait for Target to finish initialization before we proceed. */ 2497 ret = ath10k_pci_wake(ar);
2248 iowrite32(PCIE_SOC_WAKE_V_MASK, 2498 if (ret) {
2249 ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + 2499 ath10k_err("failed to wake up target: %d\n", ret);
2250 PCIE_SOC_WAKE_ADDRESS); 2500 return ret;
2251 2501 }
2252 ath10k_pci_wait(ar);
2253 2502
2254 while (wait_limit-- && 2503 while (wait_limit-- &&
2255 !(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) & 2504 !(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &
@@ -2264,34 +2513,26 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
2264 } 2513 }
2265 2514
2266 if (wait_limit < 0) { 2515 if (wait_limit < 0) {
2267 ath10k_err("Target stalled\n"); 2516 ath10k_err("target stalled\n");
2268 iowrite32(PCIE_SOC_WAKE_RESET, 2517 ret = -EIO;
2269 ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + 2518 goto out;
2270 PCIE_SOC_WAKE_ADDRESS);
2271 return -EIO;
2272 } 2519 }
2273 2520
2274 iowrite32(PCIE_SOC_WAKE_RESET, 2521out:
2275 ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + 2522 ath10k_pci_sleep(ar);
2276 PCIE_SOC_WAKE_ADDRESS); 2523 return ret;
2277
2278 return 0;
2279} 2524}
2280 2525
2281static void ath10k_pci_device_reset(struct ath10k *ar) 2526static int ath10k_pci_device_reset(struct ath10k *ar)
2282{ 2527{
2283 int i; 2528 int i, ret;
2284 u32 val; 2529 u32 val;
2285 2530
2286 if (!SOC_GLOBAL_RESET_ADDRESS) 2531 ret = ath10k_do_pci_wake(ar);
2287 return; 2532 if (ret) {
2288 2533 ath10k_err("failed to wake up target: %d\n",
2289 ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, 2534 ret);
2290 PCIE_SOC_WAKE_V_MASK); 2535 return ret;
2291 for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
2292 if (ath10k_pci_target_is_awake(ar))
2293 break;
2294 msleep(1);
2295 } 2536 }
2296 2537
2297 /* Put Target, including PCIe, into RESET. */ 2538 /* Put Target, including PCIe, into RESET. */
@@ -2317,7 +2558,8 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
2317 msleep(1); 2558 msleep(1);
2318 } 2559 }
2319 2560
2320 ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); 2561 ath10k_do_pci_sleep(ar);
2562 return 0;
2321} 2563}
2322 2564
2323static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) 2565static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
@@ -2374,7 +2616,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2374 2616
2375 ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops); 2617 ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops);
2376 if (!ar) { 2618 if (!ar) {
2377 ath10k_err("ath10k_core_create failed!\n"); 2619 ath10k_err("failed to create driver core\n");
2378 ret = -EINVAL; 2620 ret = -EINVAL;
2379 goto err_ar_pci; 2621 goto err_ar_pci;
2380 } 2622 }
@@ -2393,20 +2635,20 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2393 */ 2635 */
2394 ret = pci_assign_resource(pdev, BAR_NUM); 2636 ret = pci_assign_resource(pdev, BAR_NUM);
2395 if (ret) { 2637 if (ret) {
2396 ath10k_err("cannot assign PCI space: %d\n", ret); 2638 ath10k_err("failed to assign PCI space: %d\n", ret);
2397 goto err_ar; 2639 goto err_ar;
2398 } 2640 }
2399 2641
2400 ret = pci_enable_device(pdev); 2642 ret = pci_enable_device(pdev);
2401 if (ret) { 2643 if (ret) {
2402 ath10k_err("cannot enable PCI device: %d\n", ret); 2644 ath10k_err("failed to enable PCI device: %d\n", ret);
2403 goto err_ar; 2645 goto err_ar;
2404 } 2646 }
2405 2647
2406 /* Request MMIO resources */ 2648 /* Request MMIO resources */
2407 ret = pci_request_region(pdev, BAR_NUM, "ath"); 2649 ret = pci_request_region(pdev, BAR_NUM, "ath");
2408 if (ret) { 2650 if (ret) {
2409 ath10k_err("PCI MMIO reservation error: %d\n", ret); 2651 ath10k_err("failed to request MMIO region: %d\n", ret);
2410 goto err_device; 2652 goto err_device;
2411 } 2653 }
2412 2654
@@ -2416,13 +2658,13 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2416 */ 2658 */
2417 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 2659 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2418 if (ret) { 2660 if (ret) {
2419 ath10k_err("32-bit DMA not available: %d\n", ret); 2661 ath10k_err("failed to set DMA mask to 32-bit: %d\n", ret);
2420 goto err_region; 2662 goto err_region;
2421 } 2663 }
2422 2664
2423 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 2665 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
2424 if (ret) { 2666 if (ret) {
2425 ath10k_err("cannot enable 32-bit consistent DMA\n"); 2667 ath10k_err("failed to set consistent DMA mask to 32-bit\n");
2426 goto err_region; 2668 goto err_region;
2427 } 2669 }
2428 2670
@@ -2439,7 +2681,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2439 /* Arrange for access to Target SoC registers. */ 2681 /* Arrange for access to Target SoC registers. */
2440 mem = pci_iomap(pdev, BAR_NUM, 0); 2682 mem = pci_iomap(pdev, BAR_NUM, 0);
2441 if (!mem) { 2683 if (!mem) {
2442 ath10k_err("PCI iomap error\n"); 2684 ath10k_err("failed to perform IOMAP for BAR%d\n", BAR_NUM);
2443 ret = -EIO; 2685 ret = -EIO;
2444 goto err_master; 2686 goto err_master;
2445 } 2687 }
@@ -2451,11 +2693,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2451 ret = ath10k_do_pci_wake(ar); 2693 ret = ath10k_do_pci_wake(ar);
2452 if (ret) { 2694 if (ret) {
2453 ath10k_err("Failed to get chip id: %d\n", ret); 2695 ath10k_err("Failed to get chip id: %d\n", ret);
2454 return ret; 2696 goto err_iomap;
2455 } 2697 }
2456 2698
2457 chip_id = ath10k_pci_read32(ar, 2699 chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
2458 RTC_SOC_BASE_ADDRESS + SOC_CHIP_ID_ADDRESS);
2459 2700
2460 ath10k_do_pci_sleep(ar); 2701 ath10k_do_pci_sleep(ar);
2461 2702
@@ -2463,7 +2704,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2463 2704
2464 ret = ath10k_core_register(ar, chip_id); 2705 ret = ath10k_core_register(ar, chip_id);
2465 if (ret) { 2706 if (ret) {
2466 ath10k_err("could not register driver core (%d)\n", ret); 2707 ath10k_err("failed to register driver core: %d\n", ret);
2467 goto err_iomap; 2708 goto err_iomap;
2468 } 2709 }
2469 2710
@@ -2529,7 +2770,7 @@ static int __init ath10k_pci_init(void)
2529 2770
2530 ret = pci_register_driver(&ath10k_pci_driver); 2771 ret = pci_register_driver(&ath10k_pci_driver);
2531 if (ret) 2772 if (ret)
2532 ath10k_err("pci_register_driver failed [%d]\n", ret); 2773 ath10k_err("failed to register PCI driver: %d\n", ret);
2533 2774
2534 return ret; 2775 return ret;
2535} 2776}
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 52fb7b973571..a4f32038c440 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -198,9 +198,7 @@ struct ath10k_pci {
198 198
199 struct tasklet_struct intr_tq; 199 struct tasklet_struct intr_tq;
200 struct tasklet_struct msi_fw_err; 200 struct tasklet_struct msi_fw_err;
201 201 struct tasklet_struct early_irq_tasklet;
202 /* Number of Copy Engines supported */
203 unsigned int ce_count;
204 202
205 int started; 203 int started;
206 204
@@ -318,6 +316,16 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
318 return ioread32(ar_pci->mem + offset); 316 return ioread32(ar_pci->mem + offset);
319} 317}
320 318
319static inline u32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr)
320{
321 return ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + addr);
322}
323
324static inline void ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val)
325{
326 ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + addr, val);
327}
328
321int ath10k_do_pci_wake(struct ath10k *ar); 329int ath10k_do_pci_wake(struct ath10k *ar);
322void ath10k_do_pci_sleep(struct ath10k *ar); 330void ath10k_do_pci_sleep(struct ath10k *ar);
323 331
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index 90817ddc92ba..4eb2ecbc06ef 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -182,6 +182,27 @@ TRACE_EVENT(ath10k_htt_stats,
182 ) 182 )
183); 183);
184 184
185TRACE_EVENT(ath10k_wmi_dbglog,
186 TP_PROTO(void *buf, size_t buf_len),
187
188 TP_ARGS(buf, buf_len),
189
190 TP_STRUCT__entry(
191 __field(size_t, buf_len)
192 __dynamic_array(u8, buf, buf_len)
193 ),
194
195 TP_fast_assign(
196 __entry->buf_len = buf_len;
197 memcpy(__get_dynamic_array(buf), buf, buf_len);
198 ),
199
200 TP_printk(
201 "len %zu",
202 __entry->buf_len
203 )
204);
205
185#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ 206#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
186 207
187/* we don't want to use include/trace/events */ 208/* we don't want to use include/trace/events */
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 5ae373a1e294..74f45fa6f428 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -75,6 +75,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
75 ath10k_report_offchan_tx(htt->ar, msdu); 75 ath10k_report_offchan_tx(htt->ar, msdu);
76 76
77 info = IEEE80211_SKB_CB(msdu); 77 info = IEEE80211_SKB_CB(msdu);
78 memset(&info->status, 0, sizeof(info->status));
78 79
79 if (tx_done->discard) { 80 if (tx_done->discard) {
80 ieee80211_free_txskb(htt->ar->hw, msdu); 81 ieee80211_free_txskb(htt->ar->hw, msdu);
@@ -183,7 +184,7 @@ static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
183 /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2 184 /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
184 TODO check this */ 185 TODO check this */
185 mcs = (info2 >> 4) & 0x0F; 186 mcs = (info2 >> 4) & 0x0F;
186 nss = (info1 >> 10) & 0x07; 187 nss = ((info1 >> 10) & 0x07) + 1;
187 bw = info1 & 3; 188 bw = info1 & 3;
188 sgi = info2 & 1; 189 sgi = info2 & 1;
189 190
@@ -230,12 +231,15 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
230 ~IEEE80211_FCTL_PROTECTED); 231 ~IEEE80211_FCTL_PROTECTED);
231 } 232 }
232 233
233 if (info->status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR) 234 if (info->mic_err)
234 status->flag |= RX_FLAG_MMIC_ERROR; 235 status->flag |= RX_FLAG_MMIC_ERROR;
235 236
236 if (info->fcs_err) 237 if (info->fcs_err)
237 status->flag |= RX_FLAG_FAILED_FCS_CRC; 238 status->flag |= RX_FLAG_FAILED_FCS_CRC;
238 239
240 if (info->amsdu_more)
241 status->flag |= RX_FLAG_AMSDU_MORE;
242
239 status->signal = info->signal; 243 status->signal = info->signal;
240 244
241 spin_lock_bh(&ar->data_lock); 245 spin_lock_bh(&ar->data_lock);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index ccf3597fd9e2..712a606a080a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/ctype.h>
19 20
20#include "core.h" 21#include "core.h"
21#include "htc.h" 22#include "htc.h"
@@ -674,10 +675,8 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
674 675
675 /* Send the management frame buffer to the target */ 676 /* Send the management frame buffer to the target */
676 ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); 677 ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid);
677 if (ret) { 678 if (ret)
678 dev_kfree_skb_any(skb);
679 return ret; 679 return ret;
680 }
681 680
682 /* TODO: report tx status to mac80211 - temporary just ACK */ 681 /* TODO: report tx status to mac80211 - temporary just ACK */
683 info->flags |= IEEE80211_TX_STAT_ACK; 682 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -877,6 +876,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
877 struct wmi_mgmt_rx_event_v2 *ev_v2; 876 struct wmi_mgmt_rx_event_v2 *ev_v2;
878 struct wmi_mgmt_rx_hdr_v1 *ev_hdr; 877 struct wmi_mgmt_rx_hdr_v1 *ev_hdr;
879 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 878 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
879 struct ieee80211_channel *ch;
880 struct ieee80211_hdr *hdr; 880 struct ieee80211_hdr *hdr;
881 u32 rx_status; 881 u32 rx_status;
882 u32 channel; 882 u32 channel;
@@ -909,6 +909,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
909 ath10k_dbg(ATH10K_DBG_MGMT, 909 ath10k_dbg(ATH10K_DBG_MGMT,
910 "event mgmt rx status %08x\n", rx_status); 910 "event mgmt rx status %08x\n", rx_status);
911 911
912 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) {
913 dev_kfree_skb(skb);
914 return 0;
915 }
916
912 if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) { 917 if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) {
913 dev_kfree_skb(skb); 918 dev_kfree_skb(skb);
914 return 0; 919 return 0;
@@ -924,7 +929,25 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
924 if (rx_status & WMI_RX_STATUS_ERR_MIC) 929 if (rx_status & WMI_RX_STATUS_ERR_MIC)
925 status->flag |= RX_FLAG_MMIC_ERROR; 930 status->flag |= RX_FLAG_MMIC_ERROR;
926 931
927 status->band = phy_mode_to_band(phy_mode); 932 /* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to
933 * MODE_11B. This means phy_mode is not a reliable source for the band
934 * of mgmt rx. */
935
936 ch = ar->scan_channel;
937 if (!ch)
938 ch = ar->rx_channel;
939
940 if (ch) {
941 status->band = ch->band;
942
943 if (phy_mode == MODE_11B &&
944 status->band == IEEE80211_BAND_5GHZ)
945 ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");
946 } else {
947 ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n");
948 status->band = phy_mode_to_band(phy_mode);
949 }
950
928 status->freq = ieee80211_channel_to_frequency(channel, status->band); 951 status->freq = ieee80211_channel_to_frequency(channel, status->band);
929 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; 952 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
930 status->rate_idx = get_rate_idx(rate, status->band); 953 status->rate_idx = get_rate_idx(rate, status->band);
@@ -934,7 +957,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
934 hdr = (struct ieee80211_hdr *)skb->data; 957 hdr = (struct ieee80211_hdr *)skb->data;
935 fc = le16_to_cpu(hdr->frame_control); 958 fc = le16_to_cpu(hdr->frame_control);
936 959
937 if (fc & IEEE80211_FCTL_PROTECTED) { 960 /* FW delivers WEP Shared Auth frame with Protected Bit set and
961 * encrypted payload. However in case of PMF it delivers decrypted
962 * frames with Protected Bit set. */
963 if (ieee80211_has_protected(hdr->frame_control) &&
964 !ieee80211_is_auth(hdr->frame_control)) {
938 status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | 965 status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
939 RX_FLAG_MMIC_STRIPPED; 966 RX_FLAG_MMIC_STRIPPED;
940 hdr->frame_control = __cpu_to_le16(fc & 967 hdr->frame_control = __cpu_to_le16(fc &
@@ -1044,9 +1071,14 @@ static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
1044 ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); 1071 ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");
1045} 1072}
1046 1073
1047static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 1074static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
1048{ 1075{
1049 ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_MESG_EVENTID\n"); 1076 ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
1077 skb->len);
1078
1079 trace_ath10k_wmi_dbglog(skb->data, skb->len);
1080
1081 return 0;
1050} 1082}
1051 1083
1052static void ath10k_wmi_event_update_stats(struct ath10k *ar, 1084static void ath10k_wmi_event_update_stats(struct ath10k *ar,
@@ -1383,9 +1415,259 @@ static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar,
1383 ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); 1415 ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
1384} 1416}
1385 1417
1418static void ath10k_dfs_radar_report(struct ath10k *ar,
1419 struct wmi_single_phyerr_rx_event *event,
1420 struct phyerr_radar_report *rr,
1421 u64 tsf)
1422{
1423 u32 reg0, reg1, tsf32l;
1424 struct pulse_event pe;
1425 u64 tsf64;
1426 u8 rssi, width;
1427
1428 reg0 = __le32_to_cpu(rr->reg0);
1429 reg1 = __le32_to_cpu(rr->reg1);
1430
1431 ath10k_dbg(ATH10K_DBG_REGULATORY,
1432 "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n",
1433 MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP),
1434 MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH),
1435 MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN),
1436 MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF));
1437 ath10k_dbg(ATH10K_DBG_REGULATORY,
1438 "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n",
1439 MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK),
1440 MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX),
1441 MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID),
1442 MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN),
1443 MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK));
1444 ath10k_dbg(ATH10K_DBG_REGULATORY,
1445 "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n",
1446 MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET),
1447 MS(reg1, RADAR_REPORT_REG1_PULSE_DUR));
1448
1449 if (!ar->dfs_detector)
1450 return;
1451
1452 /* report event to DFS pattern detector */
1453 tsf32l = __le32_to_cpu(event->hdr.tsf_timestamp);
1454 tsf64 = tsf & (~0xFFFFFFFFULL);
1455 tsf64 |= tsf32l;
1456
1457 width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR);
1458 rssi = event->hdr.rssi_combined;
1459
1460 /* hardware store this as 8 bit signed value,
1461 * set to zero if negative number
1462 */
1463 if (rssi & 0x80)
1464 rssi = 0;
1465
1466 pe.ts = tsf64;
1467 pe.freq = ar->hw->conf.chandef.chan->center_freq;
1468 pe.width = width;
1469 pe.rssi = rssi;
1470
1471 ath10k_dbg(ATH10K_DBG_REGULATORY,
1472 "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n",
1473 pe.freq, pe.width, pe.rssi, pe.ts);
1474
1475 ATH10K_DFS_STAT_INC(ar, pulses_detected);
1476
1477 if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) {
1478 ath10k_dbg(ATH10K_DBG_REGULATORY,
1479 "dfs no pulse pattern detected, yet\n");
1480 return;
1481 }
1482
1483 ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs radar detected\n");
1484 ATH10K_DFS_STAT_INC(ar, radar_detected);
1485
1486 /* Control radar events reporting in debugfs file
1487 dfs_block_radar_events */
1488 if (ar->dfs_block_radar_events) {
1489 ath10k_info("DFS Radar detected, but ignored as requested\n");
1490 return;
1491 }
1492
1493 ieee80211_radar_detected(ar->hw);
1494}
1495
1496static int ath10k_dfs_fft_report(struct ath10k *ar,
1497 struct wmi_single_phyerr_rx_event *event,
1498 struct phyerr_fft_report *fftr,
1499 u64 tsf)
1500{
1501 u32 reg0, reg1;
1502 u8 rssi, peak_mag;
1503
1504 reg0 = __le32_to_cpu(fftr->reg0);
1505 reg1 = __le32_to_cpu(fftr->reg1);
1506 rssi = event->hdr.rssi_combined;
1507
1508 ath10k_dbg(ATH10K_DBG_REGULATORY,
1509 "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n",
1510 MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB),
1511 MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB),
1512 MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX),
1513 MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX));
1514 ath10k_dbg(ATH10K_DBG_REGULATORY,
1515 "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n",
1516 MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB),
1517 MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB),
1518 MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG),
1519 MS(reg1, SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB));
1520
1521 peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG);
1522
1523 /* false event detection */
1524 if (rssi == DFS_RSSI_POSSIBLY_FALSE &&
1525 peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) {
1526 ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs false pulse detected\n");
1527 ATH10K_DFS_STAT_INC(ar, pulses_discarded);
1528 return -EINVAL;
1529 }
1530
1531 return 0;
1532}
1533
1534static void ath10k_wmi_event_dfs(struct ath10k *ar,
1535 struct wmi_single_phyerr_rx_event *event,
1536 u64 tsf)
1537{
1538 int buf_len, tlv_len, res, i = 0;
1539 struct phyerr_tlv *tlv;
1540 struct phyerr_radar_report *rr;
1541 struct phyerr_fft_report *fftr;
1542 u8 *tlv_buf;
1543
1544 buf_len = __le32_to_cpu(event->hdr.buf_len);
1545 ath10k_dbg(ATH10K_DBG_REGULATORY,
1546 "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n",
1547 event->hdr.phy_err_code, event->hdr.rssi_combined,
1548 __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len);
1549
1550 /* Skip event if DFS disabled */
1551 if (!config_enabled(CONFIG_ATH10K_DFS_CERTIFIED))
1552 return;
1553
1554 ATH10K_DFS_STAT_INC(ar, pulses_total);
1555
1556 while (i < buf_len) {
1557 if (i + sizeof(*tlv) > buf_len) {
1558 ath10k_warn("too short buf for tlv header (%d)\n", i);
1559 return;
1560 }
1561
1562 tlv = (struct phyerr_tlv *)&event->bufp[i];
1563 tlv_len = __le16_to_cpu(tlv->len);
1564 tlv_buf = &event->bufp[i + sizeof(*tlv)];
1565 ath10k_dbg(ATH10K_DBG_REGULATORY,
1566 "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n",
1567 tlv_len, tlv->tag, tlv->sig);
1568
1569 switch (tlv->tag) {
1570 case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY:
1571 if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) {
1572 ath10k_warn("too short radar pulse summary (%d)\n",
1573 i);
1574 return;
1575 }
1576
1577 rr = (struct phyerr_radar_report *)tlv_buf;
1578 ath10k_dfs_radar_report(ar, event, rr, tsf);
1579 break;
1580 case PHYERR_TLV_TAG_SEARCH_FFT_REPORT:
1581 if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) {
1582 ath10k_warn("too short fft report (%d)\n", i);
1583 return;
1584 }
1585
1586 fftr = (struct phyerr_fft_report *)tlv_buf;
1587 res = ath10k_dfs_fft_report(ar, event, fftr, tsf);
1588 if (res)
1589 return;
1590 break;
1591 }
1592
1593 i += sizeof(*tlv) + tlv_len;
1594 }
1595}
1596
1597static void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
1598 struct wmi_single_phyerr_rx_event *event,
1599 u64 tsf)
1600{
1601 ath10k_dbg(ATH10K_DBG_WMI, "wmi event spectral scan\n");
1602}
1603
1386static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) 1604static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
1387{ 1605{
1388 ath10k_dbg(ATH10K_DBG_WMI, "WMI_PHYERR_EVENTID\n"); 1606 struct wmi_comb_phyerr_rx_event *comb_event;
1607 struct wmi_single_phyerr_rx_event *event;
1608 u32 count, i, buf_len, phy_err_code;
1609 u64 tsf;
1610 int left_len = skb->len;
1611
1612 ATH10K_DFS_STAT_INC(ar, phy_errors);
1613
1614 /* Check if combined event available */
1615 if (left_len < sizeof(*comb_event)) {
1616 ath10k_warn("wmi phyerr combined event wrong len\n");
1617 return;
1618 }
1619
1620 left_len -= sizeof(*comb_event);
1621
1622 /* Check number of included events */
1623 comb_event = (struct wmi_comb_phyerr_rx_event *)skb->data;
1624 count = __le32_to_cpu(comb_event->hdr.num_phyerr_events);
1625
1626 tsf = __le32_to_cpu(comb_event->hdr.tsf_u32);
1627 tsf <<= 32;
1628 tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32);
1629
1630 ath10k_dbg(ATH10K_DBG_WMI,
1631 "wmi event phyerr count %d tsf64 0x%llX\n",
1632 count, tsf);
1633
1634 event = (struct wmi_single_phyerr_rx_event *)comb_event->bufp;
1635 for (i = 0; i < count; i++) {
1636 /* Check if we can read event header */
1637 if (left_len < sizeof(*event)) {
1638 ath10k_warn("single event (%d) wrong head len\n", i);
1639 return;
1640 }
1641
1642 left_len -= sizeof(*event);
1643
1644 buf_len = __le32_to_cpu(event->hdr.buf_len);
1645 phy_err_code = event->hdr.phy_err_code;
1646
1647 if (left_len < buf_len) {
1648 ath10k_warn("single event (%d) wrong buf len\n", i);
1649 return;
1650 }
1651
1652 left_len -= buf_len;
1653
1654 switch (phy_err_code) {
1655 case PHY_ERROR_RADAR:
1656 ath10k_wmi_event_dfs(ar, event, tsf);
1657 break;
1658 case PHY_ERROR_SPECTRAL_SCAN:
1659 ath10k_wmi_event_spectral_scan(ar, event, tsf);
1660 break;
1661 case PHY_ERROR_FALSE_RADAR_EXT:
1662 ath10k_wmi_event_dfs(ar, event, tsf);
1663 ath10k_wmi_event_spectral_scan(ar, event, tsf);
1664 break;
1665 default:
1666 break;
1667 }
1668
1669 event += sizeof(*event) + buf_len;
1670 }
1389} 1671}
1390 1672
1391static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) 1673static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
@@ -1400,9 +1682,37 @@ static void ath10k_wmi_event_profile_match(struct ath10k *ar,
1400} 1682}
1401 1683
1402static void ath10k_wmi_event_debug_print(struct ath10k *ar, 1684static void ath10k_wmi_event_debug_print(struct ath10k *ar,
1403 struct sk_buff *skb) 1685 struct sk_buff *skb)
1404{ 1686{
1405 ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_PRINT_EVENTID\n"); 1687 char buf[101], c;
1688 int i;
1689
1690 for (i = 0; i < sizeof(buf) - 1; i++) {
1691 if (i >= skb->len)
1692 break;
1693
1694 c = skb->data[i];
1695
1696 if (c == '\0')
1697 break;
1698
1699 if (isascii(c) && isprint(c))
1700 buf[i] = c;
1701 else
1702 buf[i] = '.';
1703 }
1704
1705 if (i == sizeof(buf) - 1)
1706 ath10k_warn("wmi debug print truncated: %d\n", skb->len);
1707
1708 /* for some reason the debug prints end with \n, remove that */
1709 if (skb->data[i - 1] == '\n')
1710 i--;
1711
1712 /* the last byte is always reserved for the null character */
1713 buf[i] = '\0';
1714
1715 ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf);
1406} 1716}
1407 1717
1408static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) 1718static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
@@ -2062,6 +2372,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
2062{ 2372{
2063 struct wmi_set_channel_cmd *cmd; 2373 struct wmi_set_channel_cmd *cmd;
2064 struct sk_buff *skb; 2374 struct sk_buff *skb;
2375 u32 ch_flags = 0;
2065 2376
2066 if (arg->passive) 2377 if (arg->passive)
2067 return -EINVAL; 2378 return -EINVAL;
@@ -2070,10 +2381,14 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
2070 if (!skb) 2381 if (!skb)
2071 return -ENOMEM; 2382 return -ENOMEM;
2072 2383
2384 if (arg->chan_radar)
2385 ch_flags |= WMI_CHAN_FLAG_DFS;
2386
2073 cmd = (struct wmi_set_channel_cmd *)skb->data; 2387 cmd = (struct wmi_set_channel_cmd *)skb->data;
2074 cmd->chan.mhz = __cpu_to_le32(arg->freq); 2388 cmd->chan.mhz = __cpu_to_le32(arg->freq);
2075 cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq); 2389 cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq);
2076 cmd->chan.mode = arg->mode; 2390 cmd->chan.mode = arg->mode;
2391 cmd->chan.flags |= __cpu_to_le32(ch_flags);
2077 cmd->chan.min_power = arg->min_power; 2392 cmd->chan.min_power = arg->min_power;
2078 cmd->chan.max_power = arg->max_power; 2393 cmd->chan.max_power = arg->max_power;
2079 cmd->chan.reg_power = arg->max_reg_power; 2394 cmd->chan.reg_power = arg->max_reg_power;
@@ -2211,7 +2526,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
2211 } 2526 }
2212 2527
2213 ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", 2528 ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
2214 __cpu_to_le32(ar->wmi.num_mem_chunks)); 2529 ar->wmi.num_mem_chunks);
2215 2530
2216 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); 2531 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
2217 2532
@@ -2224,10 +2539,10 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
2224 __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); 2539 __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
2225 2540
2226 ath10k_dbg(ATH10K_DBG_WMI, 2541 ath10k_dbg(ATH10K_DBG_WMI,
2227 "wmi chunk %d len %d requested, addr 0x%x\n", 2542 "wmi chunk %d len %d requested, addr 0x%llx\n",
2228 i, 2543 i,
2229 cmd->host_mem_chunks[i].size, 2544 ar->wmi.mem_chunks[i].len,
2230 cmd->host_mem_chunks[i].ptr); 2545 (unsigned long long)ar->wmi.mem_chunks[i].paddr);
2231 } 2546 }
2232out: 2547out:
2233 memcpy(&cmd->resource_config, &config, sizeof(config)); 2548 memcpy(&cmd->resource_config, &config, sizeof(config));
@@ -2302,7 +2617,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
2302 } 2617 }
2303 2618
2304 ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", 2619 ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
2305 __cpu_to_le32(ar->wmi.num_mem_chunks)); 2620 ar->wmi.num_mem_chunks);
2306 2621
2307 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); 2622 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
2308 2623
@@ -2315,10 +2630,10 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
2315 __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); 2630 __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
2316 2631
2317 ath10k_dbg(ATH10K_DBG_WMI, 2632 ath10k_dbg(ATH10K_DBG_WMI,
2318 "wmi chunk %d len %d requested, addr 0x%x\n", 2633 "wmi chunk %d len %d requested, addr 0x%llx\n",
2319 i, 2634 i,
2320 cmd->host_mem_chunks[i].size, 2635 ar->wmi.mem_chunks[i].len,
2321 cmd->host_mem_chunks[i].ptr); 2636 (unsigned long long)ar->wmi.mem_chunks[i].paddr);
2322 } 2637 }
2323out: 2638out:
2324 memcpy(&cmd->resource_config, &config, sizeof(config)); 2639 memcpy(&cmd->resource_config, &config, sizeof(config));
@@ -2622,6 +2937,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
2622 struct sk_buff *skb; 2937 struct sk_buff *skb;
2623 const char *cmdname; 2938 const char *cmdname;
2624 u32 flags = 0; 2939 u32 flags = 0;
2940 u32 ch_flags = 0;
2625 2941
2626 if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && 2942 if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid &&
2627 cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) 2943 cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid)
@@ -2648,6 +2964,8 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
2648 flags |= WMI_VDEV_START_HIDDEN_SSID; 2964 flags |= WMI_VDEV_START_HIDDEN_SSID;
2649 if (arg->pmf_enabled) 2965 if (arg->pmf_enabled)
2650 flags |= WMI_VDEV_START_PMF_ENABLED; 2966 flags |= WMI_VDEV_START_PMF_ENABLED;
2967 if (arg->channel.chan_radar)
2968 ch_flags |= WMI_CHAN_FLAG_DFS;
2651 2969
2652 cmd = (struct wmi_vdev_start_request_cmd *)skb->data; 2970 cmd = (struct wmi_vdev_start_request_cmd *)skb->data;
2653 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 2971 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
@@ -2669,6 +2987,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
2669 __cpu_to_le32(arg->channel.band_center_freq1); 2987 __cpu_to_le32(arg->channel.band_center_freq1);
2670 2988
2671 cmd->chan.mode = arg->channel.mode; 2989 cmd->chan.mode = arg->channel.mode;
2990 cmd->chan.flags |= __cpu_to_le32(ch_flags);
2672 cmd->chan.min_power = arg->channel.min_power; 2991 cmd->chan.min_power = arg->channel.min_power;
2673 cmd->chan.max_power = arg->channel.max_power; 2992 cmd->chan.max_power = arg->channel.max_power;
2674 cmd->chan.reg_power = arg->channel.max_reg_power; 2993 cmd->chan.reg_power = arg->channel.max_reg_power;
@@ -2676,9 +2995,10 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
2676 cmd->chan.antenna_max = arg->channel.max_antenna_gain; 2995 cmd->chan.antenna_max = arg->channel.max_antenna_gain;
2677 2996
2678 ath10k_dbg(ATH10K_DBG_WMI, 2997 ath10k_dbg(ATH10K_DBG_WMI,
2679 "wmi vdev %s id 0x%x freq %d, mode %d, ch_flags: 0x%0X," 2998 "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, "
2680 "max_power: %d\n", cmdname, arg->vdev_id, arg->channel.freq, 2999 "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id,
2681 arg->channel.mode, flags, arg->channel.max_power); 3000 flags, arg->channel.freq, arg->channel.mode,
3001 cmd->chan.flags, arg->channel.max_power);
2682 3002
2683 return ath10k_wmi_cmd_send(ar, skb, cmd_id); 3003 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
2684} 3004}
@@ -3012,6 +3332,8 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
3012 flags |= WMI_CHAN_FLAG_ALLOW_VHT; 3332 flags |= WMI_CHAN_FLAG_ALLOW_VHT;
3013 if (ch->ht40plus) 3333 if (ch->ht40plus)
3014 flags |= WMI_CHAN_FLAG_HT40_PLUS; 3334 flags |= WMI_CHAN_FLAG_HT40_PLUS;
3335 if (ch->chan_radar)
3336 flags |= WMI_CHAN_FLAG_DFS;
3015 3337
3016 ci->mhz = __cpu_to_le32(ch->freq); 3338 ci->mhz = __cpu_to_le32(ch->freq);
3017 ci->band_center_freq1 = __cpu_to_le32(ch->freq); 3339 ci->band_center_freq1 = __cpu_to_le32(ch->freq);
@@ -3094,6 +3416,7 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar,
3094{ 3416{
3095 struct wmi_bcn_tx_cmd *cmd; 3417 struct wmi_bcn_tx_cmd *cmd;
3096 struct sk_buff *skb; 3418 struct sk_buff *skb;
3419 int ret;
3097 3420
3098 skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len); 3421 skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len);
3099 if (!skb) 3422 if (!skb)
@@ -3106,7 +3429,11 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar,
3106 cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); 3429 cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len);
3107 memcpy(cmd->bcn, arg->bcn, arg->bcn_len); 3430 memcpy(cmd->bcn, arg->bcn, arg->bcn_len);
3108 3431
3109 return ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid); 3432 ret = ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid);
3433 if (ret)
3434 dev_kfree_skb(skb);
3435
3436 return ret;
3110} 3437}
3111 3438
3112static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, 3439static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
@@ -3175,3 +3502,40 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar,
3175 type, delay_ms); 3502 type, delay_ms);
3176 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); 3503 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
3177} 3504}
3505
3506int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
3507{
3508 struct wmi_dbglog_cfg_cmd *cmd;
3509 struct sk_buff *skb;
3510 u32 cfg;
3511
3512 skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
3513 if (!skb)
3514 return -ENOMEM;
3515
3516 cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;
3517
3518 if (module_enable) {
3519 cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE,
3520 ATH10K_DBGLOG_CFG_LOG_LVL);
3521 } else {
3522 /* set back defaults, all modules with WARN level */
3523 cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,
3524 ATH10K_DBGLOG_CFG_LOG_LVL);
3525 module_enable = ~0;
3526 }
3527
3528 cmd->module_enable = __cpu_to_le32(module_enable);
3529 cmd->module_valid = __cpu_to_le32(~0);
3530 cmd->config_enable = __cpu_to_le32(cfg);
3531 cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);
3532
3533 ath10k_dbg(ATH10K_DBG_WMI,
3534 "wmi dbglog cfg modules %08x %08x config %08x %08x\n",
3535 __le32_to_cpu(cmd->module_enable),
3536 __le32_to_cpu(cmd->module_valid),
3537 __le32_to_cpu(cmd->config_enable),
3538 __le32_to_cpu(cmd->config_valid));
3539
3540 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
3541}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 78c991aec7f9..4b5e7d3d32b6 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -893,6 +893,7 @@ struct wmi_channel {
893 union { 893 union {
894 __le32 reginfo0; 894 __le32 reginfo0;
895 struct { 895 struct {
896 /* note: power unit is 0.5 dBm */
896 u8 min_power; 897 u8 min_power;
897 u8 max_power; 898 u8 max_power;
898 u8 reg_power; 899 u8 reg_power;
@@ -915,7 +916,8 @@ struct wmi_channel_arg {
915 bool allow_ht; 916 bool allow_ht;
916 bool allow_vht; 917 bool allow_vht;
917 bool ht40plus; 918 bool ht40plus;
918 /* note: power unit is 1/4th of dBm */ 919 bool chan_radar;
920 /* note: power unit is 0.5 dBm */
919 u32 min_power; 921 u32 min_power;
920 u32 max_power; 922 u32 max_power;
921 u32 max_reg_power; 923 u32 max_reg_power;
@@ -1977,6 +1979,10 @@ struct wmi_mgmt_rx_event_v2 {
1977#define WMI_RX_STATUS_ERR_MIC 0x10 1979#define WMI_RX_STATUS_ERR_MIC 0x10
1978#define WMI_RX_STATUS_ERR_KEY_CACHE_MISS 0x20 1980#define WMI_RX_STATUS_ERR_KEY_CACHE_MISS 0x20
1979 1981
1982#define PHY_ERROR_SPECTRAL_SCAN 0x26
1983#define PHY_ERROR_FALSE_RADAR_EXT 0x24
1984#define PHY_ERROR_RADAR 0x05
1985
1980struct wmi_single_phyerr_rx_hdr { 1986struct wmi_single_phyerr_rx_hdr {
1981 /* TSF timestamp */ 1987 /* TSF timestamp */
1982 __le32 tsf_timestamp; 1988 __le32 tsf_timestamp;
@@ -2068,6 +2074,87 @@ struct wmi_comb_phyerr_rx_event {
2068 u8 bufp[0]; 2074 u8 bufp[0];
2069} __packed; 2075} __packed;
2070 2076
2077#define PHYERR_TLV_SIG 0xBB
2078#define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB
2079#define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8
2080
2081struct phyerr_radar_report {
2082 __le32 reg0; /* RADAR_REPORT_REG0_* */
2083 __le32 reg1; /* REDAR_REPORT_REG1_* */
2084} __packed;
2085
2086#define RADAR_REPORT_REG0_PULSE_IS_CHIRP_MASK 0x80000000
2087#define RADAR_REPORT_REG0_PULSE_IS_CHIRP_LSB 31
2088
2089#define RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH_MASK 0x40000000
2090#define RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH_LSB 30
2091
2092#define RADAR_REPORT_REG0_AGC_TOTAL_GAIN_MASK 0x3FF00000
2093#define RADAR_REPORT_REG0_AGC_TOTAL_GAIN_LSB 20
2094
2095#define RADAR_REPORT_REG0_PULSE_DELTA_DIFF_MASK 0x000F0000
2096#define RADAR_REPORT_REG0_PULSE_DELTA_DIFF_LSB 16
2097
2098#define RADAR_REPORT_REG0_PULSE_DELTA_PEAK_MASK 0x0000FC00
2099#define RADAR_REPORT_REG0_PULSE_DELTA_PEAK_LSB 10
2100
2101#define RADAR_REPORT_REG0_PULSE_SIDX_MASK 0x000003FF
2102#define RADAR_REPORT_REG0_PULSE_SIDX_LSB 0
2103
2104#define RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID_MASK 0x80000000
2105#define RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID_LSB 31
2106
2107#define RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN_MASK 0x7F000000
2108#define RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN_LSB 24
2109
2110#define RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK_MASK 0x00FF0000
2111#define RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK_LSB 16
2112
2113#define RADAR_REPORT_REG1_PULSE_TSF_OFFSET_MASK 0x0000FF00
2114#define RADAR_REPORT_REG1_PULSE_TSF_OFFSET_LSB 8
2115
2116#define RADAR_REPORT_REG1_PULSE_DUR_MASK 0x000000FF
2117#define RADAR_REPORT_REG1_PULSE_DUR_LSB 0
2118
2119struct phyerr_fft_report {
2120 __le32 reg0; /* SEARCH_FFT_REPORT_REG0_ * */
2121 __le32 reg1; /* SEARCH_FFT_REPORT_REG1_ * */
2122} __packed;
2123
2124#define SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB_MASK 0xFF800000
2125#define SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB_LSB 23
2126
2127#define SEARCH_FFT_REPORT_REG0_BASE_PWR_DB_MASK 0x007FC000
2128#define SEARCH_FFT_REPORT_REG0_BASE_PWR_DB_LSB 14
2129
2130#define SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX_MASK 0x00003000
2131#define SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX_LSB 12
2132
2133#define SEARCH_FFT_REPORT_REG0_PEAK_SIDX_MASK 0x00000FFF
2134#define SEARCH_FFT_REPORT_REG0_PEAK_SIDX_LSB 0
2135
2136#define SEARCH_FFT_REPORT_REG1_RELPWR_DB_MASK 0xFC000000
2137#define SEARCH_FFT_REPORT_REG1_RELPWR_DB_LSB 26
2138
2139#define SEARCH_FFT_REPORT_REG1_AVGPWR_DB_MASK 0x03FC0000
2140#define SEARCH_FFT_REPORT_REG1_AVGPWR_DB_LSB 18
2141
2142#define SEARCH_FFT_REPORT_REG1_PEAK_MAG_MASK 0x0003FF00
2143#define SEARCH_FFT_REPORT_REG1_PEAK_MAG_LSB 8
2144
2145#define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_MASK 0x000000FF
2146#define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_LSB 0
2147
2148
2149struct phyerr_tlv {
2150 __le16 len;
2151 u8 tag;
2152 u8 sig;
2153} __packed;
2154
2155#define DFS_RSSI_POSSIBLY_FALSE 50
2156#define DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE 40
2157
2071struct wmi_mgmt_tx_hdr { 2158struct wmi_mgmt_tx_hdr {
2072 __le32 vdev_id; 2159 __le32 vdev_id;
2073 struct wmi_mac_addr peer_macaddr; 2160 struct wmi_mac_addr peer_macaddr;
@@ -2233,7 +2320,12 @@ enum wmi_pdev_param {
2233 * 0: no protection 1:use CTS-to-self 2: use RTS/CTS 2320 * 0: no protection 1:use CTS-to-self 2: use RTS/CTS
2234 */ 2321 */
2235 WMI_PDEV_PARAM_PROTECTION_MODE, 2322 WMI_PDEV_PARAM_PROTECTION_MODE,
2236 /* Dynamic bandwidth 0: disable 1: enable */ 2323 /*
2324 * Dynamic bandwidth - 0: disable, 1: enable
2325 *
2326 * When enabled HW rate control tries different bandwidths when
2327 * retransmitting frames.
2328 */
2237 WMI_PDEV_PARAM_DYNAMIC_BW, 2329 WMI_PDEV_PARAM_DYNAMIC_BW,
2238 /* Non aggregrate/ 11g sw retry threshold.0-disable */ 2330 /* Non aggregrate/ 11g sw retry threshold.0-disable */
2239 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, 2331 WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
@@ -2911,6 +3003,18 @@ struct wmi_vdev_install_key_arg {
2911 const void *key_data; 3003 const void *key_data;
2912}; 3004};
2913 3005
3006/*
3007 * vdev fixed rate format:
3008 * - preamble - b7:b6 - see WMI_RATE_PREMABLE_
3009 * - nss - b5:b4 - ss number (0 mean 1ss)
3010 * - rate_mcs - b3:b0 - as below
3011 * CCK: 0 - 11Mbps, 1 - 5,5Mbps, 2 - 2Mbps, 3 - 1Mbps,
3012 * 4 - 11Mbps (s), 5 - 5,5Mbps (s), 6 - 2Mbps (s)
3013 * OFDM: 0 - 48Mbps, 1 - 24Mbps, 2 - 12Mbps, 3 - 6Mbps,
3014 * 4 - 54Mbps, 5 - 36Mbps, 6 - 18Mbps, 7 - 9Mbps
3015 * HT/VHT: MCS index
3016 */
3017
2914/* Preamble types to be used with VDEV fixed rate configuration */ 3018/* Preamble types to be used with VDEV fixed rate configuration */
2915enum wmi_rate_preamble { 3019enum wmi_rate_preamble {
2916 WMI_RATE_PREAMBLE_OFDM, 3020 WMI_RATE_PREAMBLE_OFDM,
@@ -3998,6 +4102,54 @@ struct wmi_force_fw_hang_cmd {
3998 __le32 delay_ms; 4102 __le32 delay_ms;
3999} __packed; 4103} __packed;
4000 4104
4105enum ath10k_dbglog_level {
4106 ATH10K_DBGLOG_LEVEL_VERBOSE = 0,
4107 ATH10K_DBGLOG_LEVEL_INFO = 1,
4108 ATH10K_DBGLOG_LEVEL_WARN = 2,
4109 ATH10K_DBGLOG_LEVEL_ERR = 3,
4110};
4111
4112/* VAP ids to enable dbglog */
4113#define ATH10K_DBGLOG_CFG_VAP_LOG_LSB 0
4114#define ATH10K_DBGLOG_CFG_VAP_LOG_MASK 0x0000ffff
4115
4116/* to enable dbglog in the firmware */
4117#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_LSB 16
4118#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_MASK 0x00010000
4119
4120/* timestamp resolution */
4121#define ATH10K_DBGLOG_CFG_RESOLUTION_LSB 17
4122#define ATH10K_DBGLOG_CFG_RESOLUTION_MASK 0x000E0000
4123
4124/* number of queued messages before sending them to the host */
4125#define ATH10K_DBGLOG_CFG_REPORT_SIZE_LSB 20
4126#define ATH10K_DBGLOG_CFG_REPORT_SIZE_MASK 0x0ff00000
4127
4128/*
4129 * Log levels to enable. This defines the minimum level to enable, this is
4130 * not a bitmask. See enum ath10k_dbglog_level for the values.
4131 */
4132#define ATH10K_DBGLOG_CFG_LOG_LVL_LSB 28
4133#define ATH10K_DBGLOG_CFG_LOG_LVL_MASK 0x70000000
4134
4135/*
4136 * Note: this is a cleaned up version of a struct firmware uses. For
4137 * example, config_valid was hidden inside an array.
4138 */
4139struct wmi_dbglog_cfg_cmd {
4140 /* bitmask to hold mod id config*/
4141 __le32 module_enable;
4142
4143 /* see ATH10K_DBGLOG_CFG_ */
4144 __le32 config_enable;
4145
4146 /* mask of module id bits to be changed */
4147 __le32 module_valid;
4148
4149 /* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */
4150 __le32 config_valid;
4151} __packed;
4152
4001#define ATH10K_RTS_MAX 2347 4153#define ATH10K_RTS_MAX 2347
4002#define ATH10K_FRAGMT_THRESHOLD_MIN 540 4154#define ATH10K_FRAGMT_THRESHOLD_MIN 540
4003#define ATH10K_FRAGMT_THRESHOLD_MAX 2346 4155#define ATH10K_FRAGMT_THRESHOLD_MAX 2346
@@ -4075,5 +4227,6 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
4075int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4227int ath10k_wmi_force_fw_hang(struct ath10k *ar,
4076 enum wmi_force_fw_hang_type type, u32 delay_ms); 4228 enum wmi_force_fw_hang_type type, u32 delay_ms);
4077int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); 4229int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
4230int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable);
4078 4231
4079#endif /* _WMI_H_ */ 4232#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 69f58b073e85..ef35da84f63b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1238,14 +1238,11 @@ static void
1238ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, 1238ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
1239 struct ieee80211_rx_status *rxs) 1239 struct ieee80211_rx_status *rxs)
1240{ 1240{
1241 struct ath_common *common = ath5k_hw_common(ah);
1242 u64 tsf, bc_tstamp; 1241 u64 tsf, bc_tstamp;
1243 u32 hw_tu; 1242 u32 hw_tu;
1244 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1243 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1245 1244
1246 if (ieee80211_is_beacon(mgmt->frame_control) && 1245 if (le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS) {
1247 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
1248 ether_addr_equal(mgmt->bssid, common->curbssid)) {
1249 /* 1246 /*
1250 * Received an IBSS beacon with the same BSSID. Hardware *must* 1247 * Received an IBSS beacon with the same BSSID. Hardware *must*
1251 * have updated the local TSF. We have to work around various 1248 * have updated the local TSF. We have to work around various
@@ -1301,23 +1298,6 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
1301 } 1298 }
1302} 1299}
1303 1300
1304static void
1305ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)
1306{
1307 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1308 struct ath_common *common = ath5k_hw_common(ah);
1309
1310 /* only beacons from our BSSID */
1311 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1312 !ether_addr_equal(mgmt->bssid, common->curbssid))
1313 return;
1314
1315 ewma_add(&ah->ah_beacon_rssi_avg, rssi);
1316
1317 /* in IBSS mode we should keep RSSI statistics per neighbour */
1318 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1319}
1320
1321/* 1301/*
1322 * Compute padding position. skb must contain an IEEE 802.11 frame 1302 * Compute padding position. skb must contain an IEEE 802.11 frame
1323 */ 1303 */
@@ -1390,6 +1370,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
1390 struct ath5k_rx_status *rs) 1370 struct ath5k_rx_status *rs)
1391{ 1371{
1392 struct ieee80211_rx_status *rxs; 1372 struct ieee80211_rx_status *rxs;
1373 struct ath_common *common = ath5k_hw_common(ah);
1393 1374
1394 ath5k_remove_padding(skb); 1375 ath5k_remove_padding(skb);
1395 1376
@@ -1442,11 +1423,13 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
1442 1423
1443 trace_ath5k_rx(ah, skb); 1424 trace_ath5k_rx(ah, skb);
1444 1425
1445 ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi); 1426 if (ath_is_mybeacon(common, (struct ieee80211_hdr *)skb->data)) {
1427 ewma_add(&ah->ah_beacon_rssi_avg, rs->rs_rssi);
1446 1428
1447 /* check beacons in IBSS mode */ 1429 /* check beacons in IBSS mode */
1448 if (ah->opmode == NL80211_IFTYPE_ADHOC) 1430 if (ah->opmode == NL80211_IFTYPE_ADHOC)
1449 ath5k_check_ibss_tsf(ah, skb, rxs); 1431 ath5k_check_ibss_tsf(ah, skb, rxs);
1432 }
1450 1433
1451 ieee80211_rx(ah->hw, skb); 1434 ieee80211_rx(ah->hw, skb);
1452} 1435}
@@ -2549,7 +2532,6 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
2549 hw->wiphy->available_antennas_rx = 0x3; 2532 hw->wiphy->available_antennas_rx = 0x3;
2550 2533
2551 hw->extra_tx_headroom = 2; 2534 hw->extra_tx_headroom = 2;
2552 hw->channel_change_time = 5000;
2553 2535
2554 /* 2536 /*
2555 * Mark the device as detached to avoid processing 2537 * Mark the device as detached to avoid processing
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index ba200b24be64..e6c52f7c26e7 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -616,7 +616,16 @@ ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
616 * SISRs will also clear PISR so no need to worry here. 616 * SISRs will also clear PISR so no need to worry here.
617 */ 617 */
618 618
619 pisr_clear = pisr & ~AR5K_ISR_BITS_FROM_SISRS; 619 /* XXX: There seems to be an issue on some cards
620 * with tx interrupt flags not being updated
621 * on PISR despite that all Tx interrupt bits
622 * are cleared on SISRs. Since we handle all
623 * Tx queues all together it shouldn't be an
624 * issue if we clear Tx interrupt flags also
625 * on PISR to avoid that.
626 */
627 pisr_clear = (pisr & ~AR5K_ISR_BITS_FROM_SISRS) |
628 (pisr & AR5K_INT_TX_ALL);
620 629
621 /* 630 /*
622 * Write to clear them... 631 * Write to clear them...
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 2437ad26949d..fd4c89df67e1 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1109,7 +1109,9 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1109 (mode == WMI_11G_HT20) ? 1109 (mode == WMI_11G_HT20) ?
1110 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); 1110 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1111 1111
1112 mutex_lock(&vif->wdev.mtx);
1112 cfg80211_ch_switch_notify(vif->ndev, &chandef); 1113 cfg80211_ch_switch_notify(vif->ndev, &chandef);
1114 mutex_unlock(&vif->wdev.mtx);
1113} 1115}
1114 1116
1115static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1117static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -3169,12 +3171,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3169} 3171}
3170 3172
3171static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3173static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3172 struct ieee80211_channel *chan, bool offchan, 3174 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3173 unsigned int wait, const u8 *buf, size_t len,
3174 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3175{ 3175{
3176 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3176 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3177 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3177 struct ath6kl *ar = ath6kl_priv(vif->ndev);
3178 struct ieee80211_channel *chan = params->chan;
3179 const u8 *buf = params->buf;
3180 size_t len = params->len;
3181 unsigned int wait = params->wait;
3182 bool no_cck = params->no_cck;
3178 u32 id, freq; 3183 u32 id, freq;
3179 const struct ieee80211_mgmt *mgmt; 3184 const struct ieee80211_mgmt *mgmt;
3180 bool more_data, queued; 3185 bool more_data, queued;
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 546d5da0b894..4f16d79c9eb1 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -2754,9 +2754,9 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
2754 mask->control[band].legacy << 4; 2754 mask->control[band].legacy << 4;
2755 2755
2756 /* copy mcs rate mask */ 2756 /* copy mcs rate mask */
2757 mcsrate = mask->control[band].mcs[1]; 2757 mcsrate = mask->control[band].ht_mcs[1];
2758 mcsrate <<= 8; 2758 mcsrate <<= 8;
2759 mcsrate |= mask->control[band].mcs[0]; 2759 mcsrate |= mask->control[band].ht_mcs[0];
2760 ratemask[band] |= mcsrate << 12; 2760 ratemask[band] |= mcsrate << 12;
2761 ratemask[band] |= mcsrate << 28; 2761 ratemask[band] |= mcsrate << 28;
2762 } 2762 }
@@ -2806,7 +2806,7 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
2806 mask->control[band].legacy << 4; 2806 mask->control[band].legacy << 4;
2807 2807
2808 /* copy mcs rate mask */ 2808 /* copy mcs rate mask */
2809 mcsrate = mask->control[band].mcs[0]; 2809 mcsrate = mask->control[band].ht_mcs[0];
2810 ratemask[band] |= mcsrate << 12; 2810 ratemask[band] |= mcsrate << 12;
2811 ratemask[band] |= mcsrate << 20; 2811 ratemask[band] |= mcsrate << 20;
2812 } 2812 }
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 32f139e2e897..7b96b3e5712d 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -65,6 +65,14 @@ config ATH9K_DEBUGFS
65 65
66 Also required for changing debug message flags at run time. 66 Also required for changing debug message flags at run time.
67 67
68config ATH9K_STATION_STATISTICS
69 bool "Detailed station statistics"
70 depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS
71 select MAC80211_DEBUGFS
72 default n
73 ---help---
74 This option enables detailed statistics for association stations.
75
68config ATH9K_DFS_CERTIFIED 76config ATH9K_DFS_CERTIFIED
69 bool "Atheros DFS support for certified platforms" 77 bool "Atheros DFS support for certified platforms"
70 depends on ATH9K && CFG80211_CERTIFICATION_ONUS 78 depends on ATH9K && CFG80211_CERTIFICATION_ONUS
@@ -86,7 +94,7 @@ config ATH9K_DFS_CERTIFIED
86 94
87config ATH9K_TX99 95config ATH9K_TX99
88 bool "Atheros ath9k TX99 testing support" 96 bool "Atheros ath9k TX99 testing support"
89 depends on CFG80211_CERTIFICATION_ONUS 97 depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
90 default n 98 default n
91 ---help--- 99 ---help---
92 Say N. This should only be enabled on systems undergoing 100 Say N. This should only be enabled on systems undergoing
@@ -104,6 +112,14 @@ config ATH9K_TX99
104 be evaluated to meet the RF exposure limits set forth in the 112 be evaluated to meet the RF exposure limits set forth in the
105 governmental SAR regulations. 113 governmental SAR regulations.
106 114
115config ATH9K_WOW
116 bool "Wake on Wireless LAN support (EXPERIMENTAL)"
117 depends on ATH9K && PM
118 default n
119 ---help---
120 This option enables Wake on Wireless LAN support for certain cards.
121 Currently, AR9462 is supported.
122
107config ATH9K_LEGACY_RATE_CONTROL 123config ATH9K_LEGACY_RATE_CONTROL
108 bool "Atheros ath9k rate control" 124 bool "Atheros ath9k rate control"
109 depends on ATH9K 125 depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6205ef5a9321..a40e5c5d7418 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -11,11 +11,15 @@ ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
11ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o 11ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
12ath9k-$(CONFIG_ATH9K_PCI) += pci.o 12ath9k-$(CONFIG_ATH9K_PCI) += pci.o
13ath9k-$(CONFIG_ATH9K_AHB) += ahb.o 13ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
14ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
15ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o 14ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
16ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \ 15ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
17 dfs.o 16ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
18ath9k-$(CONFIG_PM_SLEEP) += wow.o 17ath9k-$(CONFIG_ATH9K_WOW) += wow.o
18
19ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o \
20 spectral.o
21
22ath9k-$(CONFIG_ATH9K_STATION_STATISTICS) += debug_sta.o
19 23
20obj-$(CONFIG_ATH9K) += ath9k.o 24obj-$(CONFIG_ATH9K) += ath9k.o
21 25
@@ -41,6 +45,8 @@ ath9k_hw-y:= \
41 ar9003_eeprom.o \ 45 ar9003_eeprom.o \
42 ar9003_paprd.o 46 ar9003_paprd.o
43 47
48ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
49
44ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ 50ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
45 ar9003_mci.o 51 ar9003_mci.o
46obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 52obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c
index bd048cc69a33..a3668433dc02 100644
--- a/drivers/net/wireless/ath/ath9k/antenna.c
+++ b/drivers/net/wireless/ath/ath9k/antenna.c
@@ -724,14 +724,14 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
724 struct ath_ant_comb *antcomb = &sc->ant_comb; 724 struct ath_ant_comb *antcomb = &sc->ant_comb;
725 int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; 725 int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
726 int curr_main_set; 726 int curr_main_set;
727 int main_rssi = rs->rs_rssi_ctl0; 727 int main_rssi = rs->rs_rssi_ctl[0];
728 int alt_rssi = rs->rs_rssi_ctl1; 728 int alt_rssi = rs->rs_rssi_ctl[1];
729 int rx_ant_conf, main_ant_conf; 729 int rx_ant_conf, main_ant_conf;
730 bool short_scan = false, ret; 730 bool short_scan = false, ret;
731 731
732 rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & 732 rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
733 ATH_ANT_RX_MASK; 733 ATH_ANT_RX_MASK;
734 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & 734 main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
735 ATH_ANT_RX_MASK; 735 ATH_ANT_RX_MASK;
736 736
737 if (alt_rssi >= antcomb->low_rssi_thresh) { 737 if (alt_rssi >= antcomb->low_rssi_thresh) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 5c95fd9e9c9e..d480d2f3e185 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -32,12 +32,8 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
32 return 0; 32 return 0;
33 } 33 }
34 34
35 if (ah->config.pcie_clock_req) 35 INIT_INI_ARRAY(&ah->iniPcieSerdes,
36 INIT_INI_ARRAY(&ah->iniPcieSerdes, 36 ar9280PciePhy_clkreq_always_on_L1_9280);
37 ar9280PciePhy_clkreq_off_L1_9280);
38 else
39 INIT_INI_ARRAY(&ah->iniPcieSerdes,
40 ar9280PciePhy_clkreq_always_on_L1_9280);
41 37
42 if (AR_SREV_9287_11_OR_LATER(ah)) { 38 if (AR_SREV_9287_11_OR_LATER(ah)) {
43 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1); 39 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
@@ -387,6 +383,20 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
387 } 383 }
388} 384}
389 385
386static void ar9002_hw_init_hang_checks(struct ath_hw *ah)
387{
388 if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
389 ah->config.hw_hang_checks |= HW_BB_RIFS_HANG;
390 ah->config.hw_hang_checks |= HW_BB_DFS_HANG;
391 }
392
393 if (AR_SREV_9280(ah))
394 ah->config.hw_hang_checks |= HW_BB_RX_CLEAR_STUCK_HANG;
395
396 if (AR_SREV_5416(ah) || AR_SREV_9100(ah) || AR_SREV_9160(ah))
397 ah->config.hw_hang_checks |= HW_MAC_HANG;
398}
399
390/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ 400/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
391int ar9002_hw_attach_ops(struct ath_hw *ah) 401int ar9002_hw_attach_ops(struct ath_hw *ah)
392{ 402{
@@ -399,6 +409,7 @@ int ar9002_hw_attach_ops(struct ath_hw *ah)
399 return ret; 409 return ret;
400 410
401 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; 411 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
412 priv_ops->init_hang_checks = ar9002_hw_init_hang_checks;
402 413
403 ops->config_pci_powersave = ar9002_hw_configpcipowersave; 414 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
404 415
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index a366d6b4626f..741b38ddcb37 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -29,7 +29,8 @@ static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
29 ((struct ath_desc*) ds)->ds_link = ds_link; 29 ((struct ath_desc*) ds)->ds_link = ds_link;
30} 30}
31 31
32static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) 32static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked,
33 u32 *sync_cause_p)
33{ 34{
34 u32 isr = 0; 35 u32 isr = 0;
35 u32 mask2 = 0; 36 u32 mask2 = 0;
@@ -170,7 +171,8 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
170 return true; 171 return true;
171 172
172 if (sync_cause) { 173 if (sync_cause) {
173 ath9k_debug_sync_cause(common, sync_cause); 174 if (sync_cause_p)
175 *sync_cause_p = sync_cause;
174 fatal_int = 176 fatal_int =
175 (sync_cause & 177 (sync_cause &
176 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) 178 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index f087117b2e6b..9a2afa2c690b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -201,7 +201,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
201 ath9k_hw_get_channel_centers(ah, chan, &centers); 201 ath9k_hw_get_channel_centers(ah, chan, &centers);
202 freq = centers.synth_center; 202 freq = centers.synth_center;
203 203
204 ah->config.spurmode = SPUR_ENABLE_EEPROM;
205 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 204 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
206 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); 205 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
207 206
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 7546b9a7dcbf..0a6163e9248c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -303,7 +303,7 @@ static const u32 ar9300_2p2_mac_postamble[][5] = {
303 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, 303 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
304 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, 304 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
305 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, 305 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
306 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, 306 {0x00008120, 0x18f04800, 0x18f04800, 0x18f04810, 0x18f04810},
307 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, 307 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
308 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 308 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
309}; 309};
@@ -352,7 +352,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
352 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 352 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
353 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 353 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
354 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 354 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
355 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 355 {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
356 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 356 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
357 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 357 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
358 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, 358 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
@@ -378,9 +378,9 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
378 {0x00009814, 0x9280c00a}, 378 {0x00009814, 0x9280c00a},
379 {0x00009818, 0x00000000}, 379 {0x00009818, 0x00000000},
380 {0x0000981c, 0x00020028}, 380 {0x0000981c, 0x00020028},
381 {0x00009834, 0x6400a290}, 381 {0x00009834, 0x6400a190},
382 {0x00009838, 0x0108ecff}, 382 {0x00009838, 0x0108ecff},
383 {0x0000983c, 0x0d000600}, 383 {0x0000983c, 0x14000600},
384 {0x00009880, 0x201fff00}, 384 {0x00009880, 0x201fff00},
385 {0x00009884, 0x00001042}, 385 {0x00009884, 0x00001042},
386 {0x000098a4, 0x00200400}, 386 {0x000098a4, 0x00200400},
@@ -401,7 +401,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
401 {0x00009d04, 0x40206c10}, 401 {0x00009d04, 0x40206c10},
402 {0x00009d08, 0x009c4060}, 402 {0x00009d08, 0x009c4060},
403 {0x00009d0c, 0x9883800a}, 403 {0x00009d0c, 0x9883800a},
404 {0x00009d10, 0x01834061}, 404 {0x00009d10, 0x01884061},
405 {0x00009d14, 0x00c0040b}, 405 {0x00009d14, 0x00c0040b},
406 {0x00009d18, 0x00000000}, 406 {0x00009d18, 0x00000000},
407 {0x00009e08, 0x0038230c}, 407 {0x00009e08, 0x0038230c},
@@ -459,7 +459,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
459 {0x0000a3e8, 0x20202020}, 459 {0x0000a3e8, 0x20202020},
460 {0x0000a3ec, 0x20202020}, 460 {0x0000a3ec, 0x20202020},
461 {0x0000a3f0, 0x00000000}, 461 {0x0000a3f0, 0x00000000},
462 {0x0000a3f4, 0x00000246}, 462 {0x0000a3f4, 0x00000000},
463 {0x0000a3f8, 0x0c9bd380}, 463 {0x0000a3f8, 0x0c9bd380},
464 {0x0000a3fc, 0x000f0f01}, 464 {0x0000a3fc, 0x000f0f01},
465 {0x0000a400, 0x8fa91f01}, 465 {0x0000a400, 0x8fa91f01},
@@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
534 534
535static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { 535static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
536 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 536 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
537 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 537 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
538 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 538 {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
539 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 539 {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
540 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 540 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
541 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 541 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
542 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 542 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
543 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 543 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
544 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, 544 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
545 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, 545 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
546 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, 546 {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
547 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, 547 {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
548 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, 548 {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
549 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, 549 {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
550 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, 550 {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
551 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, 551 {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
552 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, 552 {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
553 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, 553 {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
554 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, 554 {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
555 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, 555 {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
556 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, 556 {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
557 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, 557 {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
558 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, 558 {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
559 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, 559 {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
560 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, 560 {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
561 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, 561 {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
562 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, 562 {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
563 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, 563 {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
564 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, 564 {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
565 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, 565 {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
566 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, 566 {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
567 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 567 {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
568 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 568 {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
569 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 569 {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
570 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 570 {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
571 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 571 {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
572 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 572 {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
573 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, 573 {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
574 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, 574 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
575 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, 575 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
576 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, 576 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
577 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, 577 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
578 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, 578 {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
579 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, 579 {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
580 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, 580 {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
581 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, 581 {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
582 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, 582 {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
583 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, 583 {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
584 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, 584 {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
585 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, 585 {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
586 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, 586 {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
587 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, 587 {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
588 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, 588 {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
589 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, 589 {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
590 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, 590 {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
591 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, 591 {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
592 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, 592 {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
593 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, 593 {0x0000a5cc, 0x5e88442e, 0x5e88442e, 0x47801a83, 0x47801a83},
594 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, 594 {0x0000a5d0, 0x628a4431, 0x628a4431, 0x4a801c84, 0x4a801c84},
595 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, 595 {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
596 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, 596 {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
597 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, 597 {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
598 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, 598 {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
599 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 599 {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
600 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 600 {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
601 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 601 {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
602 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 602 {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
603 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 603 {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
604 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 604 {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
605 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, 605 {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
606 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 606 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
607 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 607 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
608 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 608 {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
609 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 609 {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
610 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, 610 {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
611 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, 611 {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
612 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, 612 {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
613 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, 613 {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
614 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, 614 {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
615 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, 615 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
616 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, 616 {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
617 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 617 {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
618 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 618 {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
619 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 619 {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
620 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 620 {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
621 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, 621 {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
622 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 622 {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
623 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 623 {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
624 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 624 {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
625 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 625 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
626 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 626 {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
627 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, 627 {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
628 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, 628 {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
629 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 629 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
630 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 630 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
631 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 631 {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
632 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 632 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
633 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 633 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
634 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 634 {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
635 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 635 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
636 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 636 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
637 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, 637 {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
638 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 638 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
639}; 639};
640 640
@@ -644,7 +644,7 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
644 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 644 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
645 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 645 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
646 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 646 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
647 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 647 {0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9},
648 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 648 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
649 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 649 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
650 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, 650 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
@@ -1086,8 +1086,8 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
1086 {0x0000b074, 0x00000000}, 1086 {0x0000b074, 0x00000000},
1087 {0x0000b078, 0x00000000}, 1087 {0x0000b078, 0x00000000},
1088 {0x0000b07c, 0x00000000}, 1088 {0x0000b07c, 0x00000000},
1089 {0x0000b080, 0x2a2d2f32}, 1089 {0x0000b080, 0x23232323},
1090 {0x0000b084, 0x21232328}, 1090 {0x0000b084, 0x21232323},
1091 {0x0000b088, 0x19191c1e}, 1091 {0x0000b088, 0x19191c1e},
1092 {0x0000b08c, 0x12141417}, 1092 {0x0000b08c, 0x12141417},
1093 {0x0000b090, 0x07070e0e}, 1093 {0x0000b090, 0x07070e0e},
@@ -1385,9 +1385,9 @@ static const u32 ar9300_2p2_mac_core[][2] = {
1385 {0x000081f8, 0x00000000}, 1385 {0x000081f8, 0x00000000},
1386 {0x000081fc, 0x00000000}, 1386 {0x000081fc, 0x00000000},
1387 {0x00008240, 0x00100000}, 1387 {0x00008240, 0x00100000},
1388 {0x00008244, 0x0010f424}, 1388 {0x00008244, 0x0010f400},
1389 {0x00008248, 0x00000800}, 1389 {0x00008248, 0x00000800},
1390 {0x0000824c, 0x0001e848}, 1390 {0x0000824c, 0x0001e800},
1391 {0x00008250, 0x00000000}, 1391 {0x00008250, 0x00000000},
1392 {0x00008254, 0x00000000}, 1392 {0x00008254, 0x00000000},
1393 {0x00008258, 0x00000000}, 1393 {0x00008258, 0x00000000},
@@ -1726,16 +1726,30 @@ static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
1726 1726
1727static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = { 1727static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
1728 /* Addr allmodes */ 1728 /* Addr allmodes */
1729 {0x00004040, 0x08253e5e}, 1729 {0x00004040, 0x0825365e},
1730 {0x00004040, 0x0008003b}, 1730 {0x00004040, 0x0008003b},
1731 {0x00004044, 0x00000000}, 1731 {0x00004044, 0x00000000},
1732}; 1732};
1733 1733
1734static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = { 1734static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
1735 /* Addr allmodes */ 1735 /* Addr allmodes */
1736 {0x00004040, 0x08213e5e}, 1736 {0x00004040, 0x0821365e},
1737 {0x00004040, 0x0008003b}, 1737 {0x00004040, 0x0008003b},
1738 {0x00004044, 0x00000000}, 1738 {0x00004044, 0x00000000},
1739}; 1739};
1740 1740
1741static const u32 ar9300_2p2_baseband_core_txfir_coeff_japan_2484[][2] = {
1742 /* Addr allmodes */
1743 {0x0000a398, 0x00000000},
1744 {0x0000a39c, 0x6f7f0301},
1745 {0x0000a3a0, 0xca9228ee},
1746};
1747
1748static const u32 ar9300_2p2_baseband_postamble_dfs_channel[][3] = {
1749 /* Addr 5G 2G */
1750 {0x00009824, 0x5ac668d0, 0x5ac668d0},
1751 {0x00009e0c, 0x6d4000e2, 0x6d4000e2},
1752 {0x00009e14, 0x37b9625e, 0x37b9625e},
1753};
1754
1741#endif /* INITVALS_9003_2P2_H */ 1755#endif /* INITVALS_9003_2P2_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h
new file mode 100644
index 000000000000..59cf738f70df
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_9003_BUFFALO_H
18#define INITVALS_9003_BUFFALO_H
19
20static const u32 ar9300Modes_high_power_tx_gain_table_buffalo[][5] = {
21 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
22 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
23 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
24 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
25 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
26 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
27 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
28 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
29 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
30 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
31 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
32 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
33 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
34 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
35 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
36 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
37 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
38 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
39 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
40 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
41 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
42 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
43 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
44 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
45 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
46 {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
47 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
48 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
49 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
50 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
51 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
52 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
53 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
54 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
55 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
56 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
57 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
58 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
59 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
60 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
61 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
62 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
63 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
64 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
65 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
66 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
67 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
68 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
69 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
70 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
71 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
72 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
73 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
74 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
75 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
76 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
77 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
78 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
79 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
80 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
81 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
82 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
83 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
84 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
85 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
86 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
87 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
88 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
89 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
90 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
91 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
92 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
93 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
94 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
95 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
96 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
97 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
98 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
99 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
100 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
101 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
102 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
103 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
104 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
105 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
106 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
107 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
108 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
109 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
110 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
111 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
112 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
113 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
114 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
115 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
116 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
117 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
118 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
119 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
120 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
121 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
122 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
123 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
124};
125
126#endif /* INITVALS_9003_BUFFALO_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 22934d3ca544..a352128c40ad 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -326,6 +326,224 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
326 ah->supp_cals = IQ_MISMATCH_CAL; 326 ah->supp_cals = IQ_MISMATCH_CAL;
327} 327}
328 328
329#define OFF_UPPER_LT 24
330#define OFF_LOWER_LT 7
331
332static bool ar9003_hw_dynamic_osdac_selection(struct ath_hw *ah,
333 bool txiqcal_done)
334{
335 struct ath_common *common = ath9k_hw_common(ah);
336 int ch0_done, osdac_ch0, dc_off_ch0_i1, dc_off_ch0_q1, dc_off_ch0_i2,
337 dc_off_ch0_q2, dc_off_ch0_i3, dc_off_ch0_q3;
338 int ch1_done, osdac_ch1, dc_off_ch1_i1, dc_off_ch1_q1, dc_off_ch1_i2,
339 dc_off_ch1_q2, dc_off_ch1_i3, dc_off_ch1_q3;
340 int ch2_done, osdac_ch2, dc_off_ch2_i1, dc_off_ch2_q1, dc_off_ch2_i2,
341 dc_off_ch2_q2, dc_off_ch2_i3, dc_off_ch2_q3;
342 bool status;
343 u32 temp, val;
344
345 /*
346 * Clear offset and IQ calibration, run AGC cal.
347 */
348 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
349 AR_PHY_AGC_CONTROL_OFFSET_CAL);
350 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
351 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
352 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
353 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
354
355 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
356 AR_PHY_AGC_CONTROL_CAL,
357 0, AH_WAIT_TIMEOUT);
358 if (!status) {
359 ath_dbg(common, CALIBRATE,
360 "AGC cal without offset cal failed to complete in 1ms");
361 return false;
362 }
363
364 /*
365 * Allow only offset calibration and disable the others
366 * (Carrier Leak calibration, TX Filter calibration and
367 * Peak Detector offset calibration).
368 */
369 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
370 AR_PHY_AGC_CONTROL_OFFSET_CAL);
371 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
372 AR_PHY_CL_CAL_ENABLE);
373 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
374 AR_PHY_AGC_CONTROL_FLTR_CAL);
375 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
376 AR_PHY_AGC_CONTROL_PKDET_CAL);
377
378 ch0_done = 0;
379 ch1_done = 0;
380 ch2_done = 0;
381
382 while ((ch0_done == 0) || (ch1_done == 0) || (ch2_done == 0)) {
383 osdac_ch0 = (REG_READ(ah, AR_PHY_65NM_CH0_BB1) >> 30) & 0x3;
384 osdac_ch1 = (REG_READ(ah, AR_PHY_65NM_CH1_BB1) >> 30) & 0x3;
385 osdac_ch2 = (REG_READ(ah, AR_PHY_65NM_CH2_BB1) >> 30) & 0x3;
386
387 REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
388
389 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
390 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
391
392 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
393 AR_PHY_AGC_CONTROL_CAL,
394 0, AH_WAIT_TIMEOUT);
395 if (!status) {
396 ath_dbg(common, CALIBRATE,
397 "DC offset cal failed to complete in 1ms");
398 return false;
399 }
400
401 REG_CLR_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
402
403 /*
404 * High gain.
405 */
406 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
407 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (1 << 8)));
408 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
409 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (1 << 8)));
410 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
411 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (1 << 8)));
412
413 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
414 dc_off_ch0_i1 = (temp >> 26) & 0x1f;
415 dc_off_ch0_q1 = (temp >> 21) & 0x1f;
416
417 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
418 dc_off_ch1_i1 = (temp >> 26) & 0x1f;
419 dc_off_ch1_q1 = (temp >> 21) & 0x1f;
420
421 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
422 dc_off_ch2_i1 = (temp >> 26) & 0x1f;
423 dc_off_ch2_q1 = (temp >> 21) & 0x1f;
424
425 /*
426 * Low gain.
427 */
428 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
429 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (2 << 8)));
430 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
431 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (2 << 8)));
432 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
433 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (2 << 8)));
434
435 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
436 dc_off_ch0_i2 = (temp >> 26) & 0x1f;
437 dc_off_ch0_q2 = (temp >> 21) & 0x1f;
438
439 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
440 dc_off_ch1_i2 = (temp >> 26) & 0x1f;
441 dc_off_ch1_q2 = (temp >> 21) & 0x1f;
442
443 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
444 dc_off_ch2_i2 = (temp >> 26) & 0x1f;
445 dc_off_ch2_q2 = (temp >> 21) & 0x1f;
446
447 /*
448 * Loopback.
449 */
450 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3,
451 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (3 << 8)));
452 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3,
453 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (3 << 8)));
454 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3,
455 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (3 << 8)));
456
457 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3);
458 dc_off_ch0_i3 = (temp >> 26) & 0x1f;
459 dc_off_ch0_q3 = (temp >> 21) & 0x1f;
460
461 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3);
462 dc_off_ch1_i3 = (temp >> 26) & 0x1f;
463 dc_off_ch1_q3 = (temp >> 21) & 0x1f;
464
465 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3);
466 dc_off_ch2_i3 = (temp >> 26) & 0x1f;
467 dc_off_ch2_q3 = (temp >> 21) & 0x1f;
468
469 if ((dc_off_ch0_i1 > OFF_UPPER_LT) || (dc_off_ch0_i1 < OFF_LOWER_LT) ||
470 (dc_off_ch0_i2 > OFF_UPPER_LT) || (dc_off_ch0_i2 < OFF_LOWER_LT) ||
471 (dc_off_ch0_i3 > OFF_UPPER_LT) || (dc_off_ch0_i3 < OFF_LOWER_LT) ||
472 (dc_off_ch0_q1 > OFF_UPPER_LT) || (dc_off_ch0_q1 < OFF_LOWER_LT) ||
473 (dc_off_ch0_q2 > OFF_UPPER_LT) || (dc_off_ch0_q2 < OFF_LOWER_LT) ||
474 (dc_off_ch0_q3 > OFF_UPPER_LT) || (dc_off_ch0_q3 < OFF_LOWER_LT)) {
475 if (osdac_ch0 == 3) {
476 ch0_done = 1;
477 } else {
478 osdac_ch0++;
479
480 val = REG_READ(ah, AR_PHY_65NM_CH0_BB1) & 0x3fffffff;
481 val |= (osdac_ch0 << 30);
482 REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, val);
483
484 ch0_done = 0;
485 }
486 } else {
487 ch0_done = 1;
488 }
489
490 if ((dc_off_ch1_i1 > OFF_UPPER_LT) || (dc_off_ch1_i1 < OFF_LOWER_LT) ||
491 (dc_off_ch1_i2 > OFF_UPPER_LT) || (dc_off_ch1_i2 < OFF_LOWER_LT) ||
492 (dc_off_ch1_i3 > OFF_UPPER_LT) || (dc_off_ch1_i3 < OFF_LOWER_LT) ||
493 (dc_off_ch1_q1 > OFF_UPPER_LT) || (dc_off_ch1_q1 < OFF_LOWER_LT) ||
494 (dc_off_ch1_q2 > OFF_UPPER_LT) || (dc_off_ch1_q2 < OFF_LOWER_LT) ||
495 (dc_off_ch1_q3 > OFF_UPPER_LT) || (dc_off_ch1_q3 < OFF_LOWER_LT)) {
496 if (osdac_ch1 == 3) {
497 ch1_done = 1;
498 } else {
499 osdac_ch1++;
500
501 val = REG_READ(ah, AR_PHY_65NM_CH1_BB1) & 0x3fffffff;
502 val |= (osdac_ch1 << 30);
503 REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, val);
504
505 ch1_done = 0;
506 }
507 } else {
508 ch1_done = 1;
509 }
510
511 if ((dc_off_ch2_i1 > OFF_UPPER_LT) || (dc_off_ch2_i1 < OFF_LOWER_LT) ||
512 (dc_off_ch2_i2 > OFF_UPPER_LT) || (dc_off_ch2_i2 < OFF_LOWER_LT) ||
513 (dc_off_ch2_i3 > OFF_UPPER_LT) || (dc_off_ch2_i3 < OFF_LOWER_LT) ||
514 (dc_off_ch2_q1 > OFF_UPPER_LT) || (dc_off_ch2_q1 < OFF_LOWER_LT) ||
515 (dc_off_ch2_q2 > OFF_UPPER_LT) || (dc_off_ch2_q2 < OFF_LOWER_LT) ||
516 (dc_off_ch2_q3 > OFF_UPPER_LT) || (dc_off_ch2_q3 < OFF_LOWER_LT)) {
517 if (osdac_ch2 == 3) {
518 ch2_done = 1;
519 } else {
520 osdac_ch2++;
521
522 val = REG_READ(ah, AR_PHY_65NM_CH2_BB1) & 0x3fffffff;
523 val |= (osdac_ch2 << 30);
524 REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, val);
525
526 ch2_done = 0;
527 }
528 } else {
529 ch2_done = 1;
530 }
531 }
532
533 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
534 AR_PHY_AGC_CONTROL_OFFSET_CAL);
535 REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
536
537 /*
538 * We don't need to check txiqcal_done here since it is always
539 * set for AR9550.
540 */
541 REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
542 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
543
544 return true;
545}
546
329/* 547/*
330 * solve 4x4 linear equation used in loopback iq cal. 548 * solve 4x4 linear equation used in loopback iq cal.
331 */ 549 */
@@ -347,7 +565,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
347 const s32 result_shift = 1 << 15; 565 const s32 result_shift = 1 << 15;
348 struct ath_common *common = ath9k_hw_common(ah); 566 struct ath_common *common = ath9k_hw_common(ah);
349 567
350 f2 = (f1 * f1 + f3 * f3) / result_shift; 568 f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9;
351 569
352 if (!f2) { 570 if (!f2) {
353 ath_dbg(common, CALIBRATE, "Divide by 0\n"); 571 ath_dbg(common, CALIBRATE, "Divide by 0\n");
@@ -437,8 +655,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
437 if (i2_m_q2_a0_d1 > 0x800) 655 if (i2_m_q2_a0_d1 > 0x800)
438 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); 656 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
439 657
440 if (i2_p_q2_a0_d1 > 0x800) 658 if (i2_p_q2_a0_d1 > 0x1000)
441 i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1); 659 i2_p_q2_a0_d1 = -((0x1fff - i2_p_q2_a0_d1) + 1);
442 660
443 if (iq_corr_a0_d1 > 0x800) 661 if (iq_corr_a0_d1 > 0x800)
444 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); 662 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
@@ -482,6 +700,19 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
482 return false; 700 return false;
483 } 701 }
484 702
703 if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) ||
704 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
705 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
706 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
707 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
708 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
709 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
710 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
711 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
712 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
713 return false;
714 }
715
485 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; 716 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
486 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; 717 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
487 718
@@ -898,7 +1129,7 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
898 1129
899static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) 1130static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
900{ 1131{
901 int offset[8], total = 0, test; 1132 int offset[8] = {0}, total = 0, test;
902 int agc_out, i; 1133 int agc_out, i;
903 1134
904 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1135 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
@@ -923,12 +1154,18 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
923 AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); 1154 AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
924 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1155 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
925 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); 1156 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
926 if (is_2g) 1157
927 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1158 if (AR_SREV_9330_11(ah)) {
928 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
929 else
930 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1159 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
931 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); 1160 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
1161 } else {
1162 if (is_2g)
1163 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1164 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
1165 else
1166 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1167 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0);
1168 }
932 1169
933 for (i = 6; i > 0; i--) { 1170 for (i = 6; i > 0; i--) {
934 offset[i] = BIT(i - 1); 1171 offset[i] = BIT(i - 1);
@@ -964,9 +1201,9 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
964 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); 1201 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
965} 1202}
966 1203
967static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, 1204static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah,
968 struct ath9k_channel *chan, 1205 struct ath9k_channel *chan,
969 bool run_rtt_cal) 1206 bool run_rtt_cal)
970{ 1207{
971 struct ath9k_hw_cal_data *caldata = ah->caldata; 1208 struct ath9k_hw_cal_data *caldata = ah->caldata;
972 int i; 1209 int i;
@@ -1040,14 +1277,14 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1040 } 1277 }
1041} 1278}
1042 1279
1043static bool ar9003_hw_init_cal(struct ath_hw *ah, 1280static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
1044 struct ath9k_channel *chan) 1281 struct ath9k_channel *chan)
1045{ 1282{
1046 struct ath_common *common = ath9k_hw_common(ah); 1283 struct ath_common *common = ath9k_hw_common(ah);
1047 struct ath9k_hw_cal_data *caldata = ah->caldata; 1284 struct ath9k_hw_cal_data *caldata = ah->caldata;
1048 bool txiqcal_done = false; 1285 bool txiqcal_done = false;
1049 bool is_reusable = true, status = true; 1286 bool is_reusable = true, status = true;
1050 bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; 1287 bool run_rtt_cal = false, run_agc_cal;
1051 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); 1288 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1052 u32 rx_delay = 0; 1289 u32 rx_delay = 0;
1053 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | 1290 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
@@ -1119,22 +1356,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
1119 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1356 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1120 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1357 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1121 txiqcal_done = run_agc_cal = true; 1358 txiqcal_done = run_agc_cal = true;
1122 } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
1123 run_agc_cal = true;
1124 sep_iq_cal = true;
1125 } 1359 }
1126 1360
1127skip_tx_iqcal: 1361skip_tx_iqcal:
1128 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1362 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1129 ar9003_mci_init_cal_req(ah, &is_reusable); 1363 ar9003_mci_init_cal_req(ah, &is_reusable);
1130 1364
1131 if (sep_iq_cal) {
1132 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1133 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1134 udelay(5);
1135 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1136 }
1137
1138 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1365 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1139 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); 1366 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1140 /* Disable BB_active */ 1367 /* Disable BB_active */
@@ -1155,7 +1382,7 @@ skip_tx_iqcal:
1155 AR_PHY_AGC_CONTROL_CAL, 1382 AR_PHY_AGC_CONTROL_CAL,
1156 0, AH_WAIT_TIMEOUT); 1383 0, AH_WAIT_TIMEOUT);
1157 1384
1158 ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal); 1385 ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal);
1159 } 1386 }
1160 1387
1161 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1388 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
@@ -1228,13 +1455,117 @@ skip_tx_iqcal:
1228 return true; 1455 return true;
1229} 1456}
1230 1457
1458static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
1459 struct ath9k_channel *chan)
1460{
1461 struct ath_common *common = ath9k_hw_common(ah);
1462 struct ath9k_hw_cal_data *caldata = ah->caldata;
1463 bool txiqcal_done = false;
1464 bool is_reusable = true, status = true;
1465 bool run_agc_cal = false, sep_iq_cal = false;
1466
1467 /* Use chip chainmask only for calibration */
1468 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1469
1470 if (ah->enabled_cals & TX_CL_CAL) {
1471 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1472 run_agc_cal = true;
1473 }
1474
1475 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
1476 goto skip_tx_iqcal;
1477
1478 /* Do Tx IQ Calibration */
1479 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1480 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1481 DELPT);
1482
1483 /*
1484 * For AR9485 or later chips, TxIQ cal runs as part of
1485 * AGC calibration. Specifically, AR9550 in SoC chips.
1486 */
1487 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1488 txiqcal_done = true;
1489 run_agc_cal = true;
1490 } else {
1491 sep_iq_cal = true;
1492 run_agc_cal = true;
1493 }
1494
1495 /*
1496 * In the SoC family, this will run for AR9300, AR9331 and AR9340.
1497 */
1498 if (sep_iq_cal) {
1499 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1500 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1501 udelay(5);
1502 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1503 }
1504
1505 if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) {
1506 if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done))
1507 return false;
1508 }
1509
1510skip_tx_iqcal:
1511 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1512 if (AR_SREV_9330_11(ah))
1513 ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan));
1514
1515 /* Calibrate the AGC */
1516 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1517 REG_READ(ah, AR_PHY_AGC_CONTROL) |
1518 AR_PHY_AGC_CONTROL_CAL);
1519
1520 /* Poll for offset calibration complete */
1521 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1522 AR_PHY_AGC_CONTROL_CAL,
1523 0, AH_WAIT_TIMEOUT);
1524 }
1525
1526 if (!status) {
1527 ath_dbg(common, CALIBRATE,
1528 "offset calibration failed to complete in %d ms; noisy environment?\n",
1529 AH_WAIT_TIMEOUT / 1000);
1530 return false;
1531 }
1532
1533 if (txiqcal_done)
1534 ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
1535
1536 /* Revert chainmask to runtime parameters */
1537 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1538
1539 /* Initialize list pointers */
1540 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1541
1542 INIT_CAL(&ah->iq_caldata);
1543 INSERT_CAL(ah, &ah->iq_caldata);
1544 ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
1545
1546 /* Initialize current pointer to first element in list */
1547 ah->cal_list_curr = ah->cal_list;
1548
1549 if (ah->cal_list_curr)
1550 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1551
1552 if (caldata)
1553 caldata->CalValid = 0;
1554
1555 return true;
1556}
1557
1231void ar9003_hw_attach_calib_ops(struct ath_hw *ah) 1558void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1232{ 1559{
1233 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1560 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1234 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1561 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1235 1562
1563 if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah))
1564 priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
1565 else
1566 priv_ops->init_cal = ar9003_hw_init_cal_soc;
1567
1236 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 1568 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1237 priv_ops->init_cal = ar9003_hw_init_cal;
1238 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 1569 priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1239 1570
1240 ops->calibrate = ar9003_hw_calibrate; 1571 ops->calibrate = ar9003_hw_calibrate;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 130657db5c43..25243cbc07f0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -131,6 +131,7 @@ static const struct ar9300_eeprom ar9300_default = {
131 .thresh62 = 28, 131 .thresh62 = 28,
132 .papdRateMaskHt20 = LE32(0x0cf0e0e0), 132 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
133 .papdRateMaskHt40 = LE32(0x6cf0e0e0), 133 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
134 .switchcomspdt = 0,
134 .xlna_bias_strength = 0, 135 .xlna_bias_strength = 0,
135 .futureModal = { 136 .futureModal = {
136 0, 0, 0, 0, 0, 0, 0, 137 0, 0, 0, 0, 0, 0, 0,
@@ -138,7 +139,7 @@ static const struct ar9300_eeprom ar9300_default = {
138 }, 139 },
139 .base_ext1 = { 140 .base_ext1 = {
140 .ant_div_control = 0, 141 .ant_div_control = 0,
141 .future = {0, 0, 0}, 142 .future = {0, 0},
142 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} 143 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
143 }, 144 },
144 .calFreqPier2G = { 145 .calFreqPier2G = {
@@ -333,6 +334,7 @@ static const struct ar9300_eeprom ar9300_default = {
333 .thresh62 = 28, 334 .thresh62 = 28,
334 .papdRateMaskHt20 = LE32(0x0c80c080), 335 .papdRateMaskHt20 = LE32(0x0c80c080),
335 .papdRateMaskHt40 = LE32(0x0080c080), 336 .papdRateMaskHt40 = LE32(0x0080c080),
337 .switchcomspdt = 0,
336 .xlna_bias_strength = 0, 338 .xlna_bias_strength = 0,
337 .futureModal = { 339 .futureModal = {
338 0, 0, 0, 0, 0, 0, 0, 340 0, 0, 0, 0, 0, 0, 0,
@@ -707,6 +709,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
707 .thresh62 = 28, 709 .thresh62 = 28,
708 .papdRateMaskHt20 = LE32(0x0c80c080), 710 .papdRateMaskHt20 = LE32(0x0c80c080),
709 .papdRateMaskHt40 = LE32(0x0080c080), 711 .papdRateMaskHt40 = LE32(0x0080c080),
712 .switchcomspdt = 0,
710 .xlna_bias_strength = 0, 713 .xlna_bias_strength = 0,
711 .futureModal = { 714 .futureModal = {
712 0, 0, 0, 0, 0, 0, 0, 715 0, 0, 0, 0, 0, 0, 0,
@@ -714,7 +717,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
714 }, 717 },
715 .base_ext1 = { 718 .base_ext1 = {
716 .ant_div_control = 0, 719 .ant_div_control = 0,
717 .future = {0, 0, 0}, 720 .future = {0, 0},
718 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} 721 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
719 }, 722 },
720 .calFreqPier2G = { 723 .calFreqPier2G = {
@@ -909,6 +912,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
909 .thresh62 = 28, 912 .thresh62 = 28,
910 .papdRateMaskHt20 = LE32(0x0cf0e0e0), 913 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
911 .papdRateMaskHt40 = LE32(0x6cf0e0e0), 914 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
915 .switchcomspdt = 0,
912 .xlna_bias_strength = 0, 916 .xlna_bias_strength = 0,
913 .futureModal = { 917 .futureModal = {
914 0, 0, 0, 0, 0, 0, 0, 918 0, 0, 0, 0, 0, 0, 0,
@@ -1284,6 +1288,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1284 .thresh62 = 28, 1288 .thresh62 = 28,
1285 .papdRateMaskHt20 = LE32(0x0c80c080), 1289 .papdRateMaskHt20 = LE32(0x0c80c080),
1286 .papdRateMaskHt40 = LE32(0x0080c080), 1290 .papdRateMaskHt40 = LE32(0x0080c080),
1291 .switchcomspdt = 0,
1287 .xlna_bias_strength = 0, 1292 .xlna_bias_strength = 0,
1288 .futureModal = { 1293 .futureModal = {
1289 0, 0, 0, 0, 0, 0, 0, 1294 0, 0, 0, 0, 0, 0, 0,
@@ -1291,7 +1296,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1291 }, 1296 },
1292 .base_ext1 = { 1297 .base_ext1 = {
1293 .ant_div_control = 0, 1298 .ant_div_control = 0,
1294 .future = {0, 0, 0}, 1299 .future = {0, 0},
1295 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} 1300 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1296 }, 1301 },
1297 .calFreqPier2G = { 1302 .calFreqPier2G = {
@@ -1486,6 +1491,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1486 .thresh62 = 28, 1491 .thresh62 = 28,
1487 .papdRateMaskHt20 = LE32(0x0cf0e0e0), 1492 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
1488 .papdRateMaskHt40 = LE32(0x6cf0e0e0), 1493 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
1494 .switchcomspdt = 0,
1489 .xlna_bias_strength = 0, 1495 .xlna_bias_strength = 0,
1490 .futureModal = { 1496 .futureModal = {
1491 0, 0, 0, 0, 0, 0, 0, 1497 0, 0, 0, 0, 0, 0, 0,
@@ -1861,6 +1867,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
1861 .thresh62 = 28, 1867 .thresh62 = 28,
1862 .papdRateMaskHt20 = LE32(0x0c80c080), 1868 .papdRateMaskHt20 = LE32(0x0c80c080),
1863 .papdRateMaskHt40 = LE32(0x0080c080), 1869 .papdRateMaskHt40 = LE32(0x0080c080),
1870 .switchcomspdt = 0,
1864 .xlna_bias_strength = 0, 1871 .xlna_bias_strength = 0,
1865 .futureModal = { 1872 .futureModal = {
1866 0, 0, 0, 0, 0, 0, 0, 1873 0, 0, 0, 0, 0, 0, 0,
@@ -1868,7 +1875,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
1868 }, 1875 },
1869 .base_ext1 = { 1876 .base_ext1 = {
1870 .ant_div_control = 0, 1877 .ant_div_control = 0,
1871 .future = {0, 0, 0}, 1878 .future = {0, 0},
1872 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} 1879 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
1873 }, 1880 },
1874 .calFreqPier2G = { 1881 .calFreqPier2G = {
@@ -2063,6 +2070,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
2063 .thresh62 = 28, 2070 .thresh62 = 28,
2064 .papdRateMaskHt20 = LE32(0x0cf0e0e0), 2071 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2065 .papdRateMaskHt40 = LE32(0x6cf0e0e0), 2072 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2073 .switchcomspdt = 0,
2066 .xlna_bias_strength = 0, 2074 .xlna_bias_strength = 0,
2067 .futureModal = { 2075 .futureModal = {
2068 0, 0, 0, 0, 0, 0, 0, 2076 0, 0, 0, 0, 0, 0, 0,
@@ -2437,6 +2445,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
2437 .thresh62 = 28, 2445 .thresh62 = 28,
2438 .papdRateMaskHt20 = LE32(0x0c80C080), 2446 .papdRateMaskHt20 = LE32(0x0c80C080),
2439 .papdRateMaskHt40 = LE32(0x0080C080), 2447 .papdRateMaskHt40 = LE32(0x0080C080),
2448 .switchcomspdt = 0,
2440 .xlna_bias_strength = 0, 2449 .xlna_bias_strength = 0,
2441 .futureModal = { 2450 .futureModal = {
2442 0, 0, 0, 0, 0, 0, 0, 2451 0, 0, 0, 0, 0, 0, 0,
@@ -2444,7 +2453,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
2444 }, 2453 },
2445 .base_ext1 = { 2454 .base_ext1 = {
2446 .ant_div_control = 0, 2455 .ant_div_control = 0,
2447 .future = {0, 0, 0}, 2456 .future = {0, 0},
2448 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} 2457 .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
2449 }, 2458 },
2450 .calFreqPier2G = { 2459 .calFreqPier2G = {
@@ -2639,6 +2648,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
2639 .thresh62 = 28, 2648 .thresh62 = 28,
2640 .papdRateMaskHt20 = LE32(0x0cf0e0e0), 2649 .papdRateMaskHt20 = LE32(0x0cf0e0e0),
2641 .papdRateMaskHt40 = LE32(0x6cf0e0e0), 2650 .papdRateMaskHt40 = LE32(0x6cf0e0e0),
2651 .switchcomspdt = 0,
2642 .xlna_bias_strength = 0, 2652 .xlna_bias_strength = 0,
2643 .futureModal = { 2653 .futureModal = {
2644 0, 0, 0, 0, 0, 0, 0, 2654 0, 0, 0, 0, 0, 0, 0,
@@ -3588,7 +3598,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3588 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 3598 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3589 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3599 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3590 AR_SWITCH_TABLE_COM_AR9462_ALL, value); 3600 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3591 } else if (AR_SREV_9550(ah)) { 3601 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
3592 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3602 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3593 AR_SWITCH_TABLE_COM_AR9550_ALL, value); 3603 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3594 } else 3604 } else
@@ -3965,7 +3975,7 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
3965 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 3975 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3966 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; 3976 u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
3967 3977
3968 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) 3978 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
3969 return; 3979 return;
3970 3980
3971 if (eep->baseEepHeader.featureEnable & 0x40) { 3981 if (eep->baseEepHeader.featureEnable & 0x40) {
@@ -4020,7 +4030,10 @@ static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4020 if (!(eep->baseEepHeader.featureEnable & 0x80)) 4030 if (!(eep->baseEepHeader.featureEnable & 0x80))
4021 return; 4031 return;
4022 4032
4023 if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah)) 4033 if (!AR_SREV_9300(ah) &&
4034 !AR_SREV_9340(ah) &&
4035 !AR_SREV_9580(ah) &&
4036 !AR_SREV_9531(ah))
4024 return; 4037 return;
4025 4038
4026 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; 4039 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
@@ -4111,6 +4124,37 @@ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4111 } 4124 }
4112} 4125}
4113 4126
4127static void ar9003_hw_apply_minccapwr_thresh(struct ath_hw *ah,
4128 bool is2ghz)
4129{
4130 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4131 const u_int32_t cca_ctrl[AR9300_MAX_CHAINS] = {
4132 AR_PHY_CCA_CTRL_0,
4133 AR_PHY_CCA_CTRL_1,
4134 AR_PHY_CCA_CTRL_2,
4135 };
4136 int chain;
4137 u32 val;
4138
4139 if (is2ghz) {
4140 if (!(eep->base_ext1.misc_enable & BIT(2)))
4141 return;
4142 } else {
4143 if (!(eep->base_ext1.misc_enable & BIT(3)))
4144 return;
4145 }
4146
4147 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
4148 if (!(ah->caps.tx_chainmask & BIT(chain)))
4149 continue;
4150
4151 val = ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain];
4152 REG_RMW_FIELD(ah, cca_ctrl[chain],
4153 AR_PHY_EXT_CCA0_THRESH62_1, val);
4154 }
4155
4156}
4157
4114static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, 4158static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4115 struct ath9k_channel *chan) 4159 struct ath9k_channel *chan)
4116{ 4160{
@@ -4122,9 +4166,10 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
4122 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz); 4166 ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
4123 ar9003_hw_atten_apply(ah, chan); 4167 ar9003_hw_atten_apply(ah, chan);
4124 ar9003_hw_quick_drop_apply(ah, chan->channel); 4168 ar9003_hw_quick_drop_apply(ah, chan->channel);
4125 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah)) 4169 if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah))
4126 ar9003_hw_internal_regulator_apply(ah); 4170 ar9003_hw_internal_regulator_apply(ah);
4127 ar9003_hw_apply_tuning_caps(ah); 4171 ar9003_hw_apply_tuning_caps(ah);
4172 ar9003_hw_apply_minccapwr_thresh(ah, chan);
4128 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); 4173 ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
4129 ar9003_hw_thermometer_apply(ah); 4174 ar9003_hw_thermometer_apply(ah);
4130 ar9003_hw_thermo_cal_apply(ah); 4175 ar9003_hw_thermo_cal_apply(ah);
@@ -4746,7 +4791,7 @@ static void ar9003_hw_power_control_override(struct ath_hw *ah,
4746 } 4791 }
4747 4792
4748tempslope: 4793tempslope:
4749 if (AR_SREV_9550(ah)) { 4794 if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
4750 /* 4795 /*
4751 * AR955x has tempSlope register for each chain. 4796 * AR955x has tempSlope register for each chain.
4752 * Check whether temp_compensation feature is enabled or not. 4797 * Check whether temp_compensation feature is enabled or not.
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 0e5daa58a4fc..694ca2e680e5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -270,10 +270,20 @@ struct cal_ctl_data_5g {
270 u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G]; 270 u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
271} __packed; 271} __packed;
272 272
273#define MAX_BASE_EXTENSION_FUTURE 2
274
273struct ar9300_BaseExtension_1 { 275struct ar9300_BaseExtension_1 {
274 u8 ant_div_control; 276 u8 ant_div_control;
275 u8 future[3]; 277 u8 future[MAX_BASE_EXTENSION_FUTURE];
276 u8 tempslopextension[8]; 278 /*
279 * misc_enable:
280 *
281 * BIT 0 - TX Gain Cap enable.
282 * BIT 1 - Uncompressed Checksum enable.
283 * BIT 2/3 - MinCCApwr enable 2g/5g.
284 */
285 u8 misc_enable;
286 int8_t tempslopextension[8];
277 int8_t quick_drop_low; 287 int8_t quick_drop_low;
278 int8_t quick_drop_high; 288 int8_t quick_drop_high;
279} __packed; 289} __packed;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 20e49095db2a..ec1da0cc25f5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -17,6 +17,7 @@
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_mac.h" 18#include "ar9003_mac.h"
19#include "ar9003_2p2_initvals.h" 19#include "ar9003_2p2_initvals.h"
20#include "ar9003_buffalo_initvals.h"
20#include "ar9485_initvals.h" 21#include "ar9485_initvals.h"
21#include "ar9340_initvals.h" 22#include "ar9340_initvals.h"
22#include "ar9330_1p1_initvals.h" 23#include "ar9330_1p1_initvals.h"
@@ -26,6 +27,8 @@
26#include "ar9462_2p0_initvals.h" 27#include "ar9462_2p0_initvals.h"
27#include "ar9462_2p1_initvals.h" 28#include "ar9462_2p1_initvals.h"
28#include "ar9565_1p0_initvals.h" 29#include "ar9565_1p0_initvals.h"
30#include "ar9565_1p1_initvals.h"
31#include "ar953x_initvals.h"
29 32
30/* General hardware code for the AR9003 hadware family */ 33/* General hardware code for the AR9003 hadware family */
31 34
@@ -148,7 +151,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
148 ar9340Modes_high_ob_db_tx_gain_table_1p0); 151 ar9340Modes_high_ob_db_tx_gain_table_1p0);
149 152
150 INIT_INI_ARRAY(&ah->iniModesFastClock, 153 INIT_INI_ARRAY(&ah->iniModesFastClock,
151 ar9340Modes_fast_clock_1p0); 154 ar9340Modes_fast_clock_1p0);
155 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
156 ar9340_1p0_baseband_core_txfir_coeff_japan_2484);
157 INIT_INI_ARRAY(&ah->ini_dfs,
158 ar9340_1p0_baseband_postamble_dfs_channel);
152 159
153 if (!ah->is_clk_25mhz) 160 if (!ah->is_clk_25mhz)
154 INIT_INI_ARRAY(&ah->iniAdditional, 161 INIT_INI_ARRAY(&ah->iniAdditional,
@@ -223,6 +230,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
223 ar9462_2p1_modes_fast_clock); 230 ar9462_2p1_modes_fast_clock);
224 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 231 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
225 ar9462_2p1_baseband_core_txfir_coeff_japan_2484); 232 ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
233 INIT_INI_ARRAY(&ah->iniPcieSerdes,
234 ar9462_2p1_pciephy_clkreq_disable_L1);
235 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
236 ar9462_2p1_pciephy_clkreq_disable_L1);
226 } else if (AR_SREV_9462_20(ah)) { 237 } else if (AR_SREV_9462_20(ah)) {
227 238
228 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); 239 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -247,18 +258,18 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
247 ar9462_2p0_soc_postamble); 258 ar9462_2p0_soc_postamble);
248 259
249 INIT_INI_ARRAY(&ah->iniModesRxGain, 260 INIT_INI_ARRAY(&ah->iniModesRxGain,
250 ar9462_common_rx_gain_table_2p0); 261 ar9462_2p0_common_rx_gain);
251 262
252 /* Awake -> Sleep Setting */ 263 /* Awake -> Sleep Setting */
253 INIT_INI_ARRAY(&ah->iniPcieSerdes, 264 INIT_INI_ARRAY(&ah->iniPcieSerdes,
254 ar9462_pciephy_clkreq_disable_L1_2p0); 265 ar9462_2p0_pciephy_clkreq_disable_L1);
255 /* Sleep -> Awake Setting */ 266 /* Sleep -> Awake Setting */
256 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 267 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
257 ar9462_pciephy_clkreq_disable_L1_2p0); 268 ar9462_2p0_pciephy_clkreq_disable_L1);
258 269
259 /* Fast clock modal settings */ 270 /* Fast clock modal settings */
260 INIT_INI_ARRAY(&ah->iniModesFastClock, 271 INIT_INI_ARRAY(&ah->iniModesFastClock,
261 ar9462_modes_fast_clock_2p0); 272 ar9462_2p0_modes_fast_clock);
262 273
263 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 274 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
264 ar9462_2p0_baseband_core_txfir_coeff_japan_2484); 275 ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
@@ -298,6 +309,31 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
298 /* Fast clock modal settings */ 309 /* Fast clock modal settings */
299 INIT_INI_ARRAY(&ah->iniModesFastClock, 310 INIT_INI_ARRAY(&ah->iniModesFastClock,
300 ar955x_1p0_modes_fast_clock); 311 ar955x_1p0_modes_fast_clock);
312 } else if (AR_SREV_9531(ah)) {
313 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
314 qca953x_1p0_mac_core);
315 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
316 qca953x_1p0_mac_postamble);
317 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
318 qca953x_1p0_baseband_core);
319 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
320 qca953x_1p0_baseband_postamble);
321 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
322 qca953x_1p0_radio_core);
323 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
324 qca953x_1p0_radio_postamble);
325 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
326 qca953x_1p0_soc_preamble);
327 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
328 qca953x_1p0_soc_postamble);
329 INIT_INI_ARRAY(&ah->iniModesRxGain,
330 qca953x_1p0_common_wo_xlna_rx_gain_table);
331 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
332 qca953x_1p0_common_wo_xlna_rx_gain_bounds);
333 INIT_INI_ARRAY(&ah->iniModesTxGain,
334 qca953x_1p0_modes_no_xpa_tx_gain_table);
335 INIT_INI_ARRAY(&ah->iniModesFastClock,
336 qca953x_1p0_modes_fast_clock);
301 } else if (AR_SREV_9580(ah)) { 337 } else if (AR_SREV_9580(ah)) {
302 /* mac */ 338 /* mac */
303 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 339 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -330,7 +366,46 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
330 ar9580_1p0_low_ob_db_tx_gain_table); 366 ar9580_1p0_low_ob_db_tx_gain_table);
331 367
332 INIT_INI_ARRAY(&ah->iniModesFastClock, 368 INIT_INI_ARRAY(&ah->iniModesFastClock,
333 ar9580_1p0_modes_fast_clock); 369 ar9580_1p0_modes_fast_clock);
370 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
371 ar9580_1p0_baseband_core_txfir_coeff_japan_2484);
372 INIT_INI_ARRAY(&ah->ini_dfs,
373 ar9580_1p0_baseband_postamble_dfs_channel);
374 } else if (AR_SREV_9565_11_OR_LATER(ah)) {
375 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
376 ar9565_1p1_mac_core);
377 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
378 ar9565_1p1_mac_postamble);
379
380 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
381 ar9565_1p1_baseband_core);
382 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
383 ar9565_1p1_baseband_postamble);
384
385 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
386 ar9565_1p1_radio_core);
387 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
388 ar9565_1p1_radio_postamble);
389
390 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
391 ar9565_1p1_soc_preamble);
392 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
393 ar9565_1p1_soc_postamble);
394
395 INIT_INI_ARRAY(&ah->iniModesRxGain,
396 ar9565_1p1_Common_rx_gain_table);
397 INIT_INI_ARRAY(&ah->iniModesTxGain,
398 ar9565_1p1_Modes_lowest_ob_db_tx_gain_table);
399
400 INIT_INI_ARRAY(&ah->iniPcieSerdes,
401 ar9565_1p1_pciephy_clkreq_disable_L1);
402 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
403 ar9565_1p1_pciephy_clkreq_disable_L1);
404
405 INIT_INI_ARRAY(&ah->iniModesFastClock,
406 ar9565_1p1_modes_fast_clock);
407 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
408 ar9565_1p1_baseband_core_txfir_coeff_japan_2484);
334 } else if (AR_SREV_9565(ah)) { 409 } else if (AR_SREV_9565(ah)) {
335 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 410 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
336 ar9565_1p0_mac_core); 411 ar9565_1p0_mac_core);
@@ -411,7 +486,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
411 486
412 /* Fast clock modal settings */ 487 /* Fast clock modal settings */
413 INIT_INI_ARRAY(&ah->iniModesFastClock, 488 INIT_INI_ARRAY(&ah->iniModesFastClock,
414 ar9300Modes_fast_clock_2p2); 489 ar9300Modes_fast_clock_2p2);
490 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
491 ar9300_2p2_baseband_core_txfir_coeff_japan_2484);
492 INIT_INI_ARRAY(&ah->ini_dfs,
493 ar9300_2p2_baseband_postamble_dfs_channel);
415 } 494 }
416} 495}
417 496
@@ -432,6 +511,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
432 else if (AR_SREV_9550(ah)) 511 else if (AR_SREV_9550(ah))
433 INIT_INI_ARRAY(&ah->iniModesTxGain, 512 INIT_INI_ARRAY(&ah->iniModesTxGain,
434 ar955x_1p0_modes_xpa_tx_gain_table); 513 ar955x_1p0_modes_xpa_tx_gain_table);
514 else if (AR_SREV_9531(ah))
515 INIT_INI_ARRAY(&ah->iniModesTxGain,
516 qca953x_1p0_modes_xpa_tx_gain_table);
435 else if (AR_SREV_9580(ah)) 517 else if (AR_SREV_9580(ah))
436 INIT_INI_ARRAY(&ah->iniModesTxGain, 518 INIT_INI_ARRAY(&ah->iniModesTxGain,
437 ar9580_1p0_lowest_ob_db_tx_gain_table); 519 ar9580_1p0_lowest_ob_db_tx_gain_table);
@@ -440,7 +522,10 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
440 ar9462_2p1_modes_low_ob_db_tx_gain); 522 ar9462_2p1_modes_low_ob_db_tx_gain);
441 else if (AR_SREV_9462_20(ah)) 523 else if (AR_SREV_9462_20(ah))
442 INIT_INI_ARRAY(&ah->iniModesTxGain, 524 INIT_INI_ARRAY(&ah->iniModesTxGain,
443 ar9462_modes_low_ob_db_tx_gain_table_2p0); 525 ar9462_2p0_modes_low_ob_db_tx_gain);
526 else if (AR_SREV_9565_11(ah))
527 INIT_INI_ARRAY(&ah->iniModesTxGain,
528 ar9565_1p1_modes_low_ob_db_tx_gain_table);
444 else if (AR_SREV_9565(ah)) 529 else if (AR_SREV_9565(ah))
445 INIT_INI_ARRAY(&ah->iniModesTxGain, 530 INIT_INI_ARRAY(&ah->iniModesTxGain,
446 ar9565_1p0_modes_low_ob_db_tx_gain_table); 531 ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -469,12 +554,22 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
469 else if (AR_SREV_9550(ah)) 554 else if (AR_SREV_9550(ah))
470 INIT_INI_ARRAY(&ah->iniModesTxGain, 555 INIT_INI_ARRAY(&ah->iniModesTxGain,
471 ar955x_1p0_modes_no_xpa_tx_gain_table); 556 ar955x_1p0_modes_no_xpa_tx_gain_table);
472 else if (AR_SREV_9462_21(ah)) 557 else if (AR_SREV_9531(ah)) {
558 if (AR_SREV_9531_11(ah))
559 INIT_INI_ARRAY(&ah->iniModesTxGain,
560 qca953x_1p1_modes_no_xpa_tx_gain_table);
561 else
562 INIT_INI_ARRAY(&ah->iniModesTxGain,
563 qca953x_1p0_modes_no_xpa_tx_gain_table);
564 } else if (AR_SREV_9462_21(ah))
473 INIT_INI_ARRAY(&ah->iniModesTxGain, 565 INIT_INI_ARRAY(&ah->iniModesTxGain,
474 ar9462_2p1_modes_high_ob_db_tx_gain); 566 ar9462_2p1_modes_high_ob_db_tx_gain);
475 else if (AR_SREV_9462_20(ah)) 567 else if (AR_SREV_9462_20(ah))
476 INIT_INI_ARRAY(&ah->iniModesTxGain, 568 INIT_INI_ARRAY(&ah->iniModesTxGain,
477 ar9462_modes_high_ob_db_tx_gain_table_2p0); 569 ar9462_2p0_modes_high_ob_db_tx_gain);
570 else if (AR_SREV_9565_11(ah))
571 INIT_INI_ARRAY(&ah->iniModesTxGain,
572 ar9565_1p1_modes_high_ob_db_tx_gain_table);
478 else if (AR_SREV_9565(ah)) 573 else if (AR_SREV_9565(ah))
479 INIT_INI_ARRAY(&ah->iniModesTxGain, 574 INIT_INI_ARRAY(&ah->iniModesTxGain,
480 ar9565_1p0_modes_high_ob_db_tx_gain_table); 575 ar9565_1p0_modes_high_ob_db_tx_gain_table);
@@ -500,6 +595,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
500 else if (AR_SREV_9580(ah)) 595 else if (AR_SREV_9580(ah))
501 INIT_INI_ARRAY(&ah->iniModesTxGain, 596 INIT_INI_ARRAY(&ah->iniModesTxGain,
502 ar9580_1p0_low_ob_db_tx_gain_table); 597 ar9580_1p0_low_ob_db_tx_gain_table);
598 else if (AR_SREV_9565_11(ah))
599 INIT_INI_ARRAY(&ah->iniModesTxGain,
600 ar9565_1p1_modes_low_ob_db_tx_gain_table);
503 else if (AR_SREV_9565(ah)) 601 else if (AR_SREV_9565(ah))
504 INIT_INI_ARRAY(&ah->iniModesTxGain, 602 INIT_INI_ARRAY(&ah->iniModesTxGain,
505 ar9565_1p0_modes_low_ob_db_tx_gain_table); 603 ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -525,12 +623,20 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
525 else if (AR_SREV_9580(ah)) 623 else if (AR_SREV_9580(ah))
526 INIT_INI_ARRAY(&ah->iniModesTxGain, 624 INIT_INI_ARRAY(&ah->iniModesTxGain,
527 ar9580_1p0_high_power_tx_gain_table); 625 ar9580_1p0_high_power_tx_gain_table);
626 else if (AR_SREV_9565_11(ah))
627 INIT_INI_ARRAY(&ah->iniModesTxGain,
628 ar9565_1p1_modes_high_power_tx_gain_table);
528 else if (AR_SREV_9565(ah)) 629 else if (AR_SREV_9565(ah))
529 INIT_INI_ARRAY(&ah->iniModesTxGain, 630 INIT_INI_ARRAY(&ah->iniModesTxGain,
530 ar9565_1p0_modes_high_power_tx_gain_table); 631 ar9565_1p0_modes_high_power_tx_gain_table);
531 else 632 else {
532 INIT_INI_ARRAY(&ah->iniModesTxGain, 633 if (ah->config.tx_gain_buffalo)
533 ar9300Modes_high_power_tx_gain_table_2p2); 634 INIT_INI_ARRAY(&ah->iniModesTxGain,
635 ar9300Modes_high_power_tx_gain_table_buffalo);
636 else
637 INIT_INI_ARRAY(&ah->iniModesTxGain,
638 ar9300Modes_high_power_tx_gain_table_2p2);
639 }
534} 640}
535 641
536static void ar9003_tx_gain_table_mode4(struct ath_hw *ah) 642static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
@@ -546,7 +652,7 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
546 ar9462_2p1_modes_mix_ob_db_tx_gain); 652 ar9462_2p1_modes_mix_ob_db_tx_gain);
547 else if (AR_SREV_9462_20(ah)) 653 else if (AR_SREV_9462_20(ah))
548 INIT_INI_ARRAY(&ah->iniModesTxGain, 654 INIT_INI_ARRAY(&ah->iniModesTxGain,
549 ar9462_modes_mix_ob_db_tx_gain_table_2p0); 655 ar9462_2p0_modes_mix_ob_db_tx_gain);
550 else 656 else
551 INIT_INI_ARRAY(&ah->iniModesTxGain, 657 INIT_INI_ARRAY(&ah->iniModesTxGain,
552 ar9300Modes_mixed_ob_db_tx_gain_table_2p2); 658 ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -581,6 +687,13 @@ static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
581 ar9580_1p0_type6_tx_gain_table); 687 ar9580_1p0_type6_tx_gain_table);
582} 688}
583 689
690static void ar9003_tx_gain_table_mode7(struct ath_hw *ah)
691{
692 if (AR_SREV_9340(ah))
693 INIT_INI_ARRAY(&ah->iniModesTxGain,
694 ar9340_cus227_tx_gain_table_1p0);
695}
696
584typedef void (*ath_txgain_tab)(struct ath_hw *ah); 697typedef void (*ath_txgain_tab)(struct ath_hw *ah);
585 698
586static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 699static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -593,6 +706,7 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
593 ar9003_tx_gain_table_mode4, 706 ar9003_tx_gain_table_mode4,
594 ar9003_tx_gain_table_mode5, 707 ar9003_tx_gain_table_mode5,
595 ar9003_tx_gain_table_mode6, 708 ar9003_tx_gain_table_mode6,
709 ar9003_tx_gain_table_mode7,
596 }; 710 };
597 int idx = ar9003_hw_get_tx_gain_idx(ah); 711 int idx = ar9003_hw_get_tx_gain_idx(ah);
598 712
@@ -621,6 +735,11 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
621 ar955x_1p0_common_rx_gain_table); 735 ar955x_1p0_common_rx_gain_table);
622 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, 736 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
623 ar955x_1p0_common_rx_gain_bounds); 737 ar955x_1p0_common_rx_gain_bounds);
738 } else if (AR_SREV_9531(ah)) {
739 INIT_INI_ARRAY(&ah->iniModesRxGain,
740 qca953x_1p0_common_rx_gain_table);
741 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
742 qca953x_1p0_common_rx_gain_bounds);
624 } else if (AR_SREV_9580(ah)) 743 } else if (AR_SREV_9580(ah))
625 INIT_INI_ARRAY(&ah->iniModesRxGain, 744 INIT_INI_ARRAY(&ah->iniModesRxGain,
626 ar9580_1p0_rx_gain_table); 745 ar9580_1p0_rx_gain_table);
@@ -629,7 +748,10 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
629 ar9462_2p1_common_rx_gain); 748 ar9462_2p1_common_rx_gain);
630 else if (AR_SREV_9462_20(ah)) 749 else if (AR_SREV_9462_20(ah))
631 INIT_INI_ARRAY(&ah->iniModesRxGain, 750 INIT_INI_ARRAY(&ah->iniModesRxGain,
632 ar9462_common_rx_gain_table_2p0); 751 ar9462_2p0_common_rx_gain);
752 else if (AR_SREV_9565_11(ah))
753 INIT_INI_ARRAY(&ah->iniModesRxGain,
754 ar9565_1p1_Common_rx_gain_table);
633 else if (AR_SREV_9565(ah)) 755 else if (AR_SREV_9565(ah))
634 INIT_INI_ARRAY(&ah->iniModesRxGain, 756 INIT_INI_ARRAY(&ah->iniModesRxGain,
635 ar9565_1p0_Common_rx_gain_table); 757 ar9565_1p0_Common_rx_gain_table);
@@ -657,15 +779,23 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
657 ar9462_2p1_common_wo_xlna_rx_gain); 779 ar9462_2p1_common_wo_xlna_rx_gain);
658 else if (AR_SREV_9462_20(ah)) 780 else if (AR_SREV_9462_20(ah))
659 INIT_INI_ARRAY(&ah->iniModesRxGain, 781 INIT_INI_ARRAY(&ah->iniModesRxGain,
660 ar9462_common_wo_xlna_rx_gain_table_2p0); 782 ar9462_2p0_common_wo_xlna_rx_gain);
661 else if (AR_SREV_9550(ah)) { 783 else if (AR_SREV_9550(ah)) {
662 INIT_INI_ARRAY(&ah->iniModesRxGain, 784 INIT_INI_ARRAY(&ah->iniModesRxGain,
663 ar955x_1p0_common_wo_xlna_rx_gain_table); 785 ar955x_1p0_common_wo_xlna_rx_gain_table);
664 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, 786 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
665 ar955x_1p0_common_wo_xlna_rx_gain_bounds); 787 ar955x_1p0_common_wo_xlna_rx_gain_bounds);
788 } else if (AR_SREV_9531(ah)) {
789 INIT_INI_ARRAY(&ah->iniModesRxGain,
790 qca953x_1p0_common_wo_xlna_rx_gain_table);
791 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
792 qca953x_1p0_common_wo_xlna_rx_gain_bounds);
666 } else if (AR_SREV_9580(ah)) 793 } else if (AR_SREV_9580(ah))
667 INIT_INI_ARRAY(&ah->iniModesRxGain, 794 INIT_INI_ARRAY(&ah->iniModesRxGain,
668 ar9580_1p0_wo_xlna_rx_gain_table); 795 ar9580_1p0_wo_xlna_rx_gain_table);
796 else if (AR_SREV_9565_11(ah))
797 INIT_INI_ARRAY(&ah->iniModesRxGain,
798 ar9565_1p1_common_wo_xlna_rx_gain_table);
669 else if (AR_SREV_9565(ah)) 799 else if (AR_SREV_9565(ah))
670 INIT_INI_ARRAY(&ah->iniModesRxGain, 800 INIT_INI_ARRAY(&ah->iniModesRxGain,
671 ar9565_1p0_common_wo_xlna_rx_gain_table); 801 ar9565_1p0_common_wo_xlna_rx_gain_table);
@@ -687,7 +817,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
687 ar9462_2p1_baseband_postamble_5g_xlna); 817 ar9462_2p1_baseband_postamble_5g_xlna);
688 } else if (AR_SREV_9462_20(ah)) { 818 } else if (AR_SREV_9462_20(ah)) {
689 INIT_INI_ARRAY(&ah->iniModesRxGain, 819 INIT_INI_ARRAY(&ah->iniModesRxGain,
690 ar9462_common_mixed_rx_gain_table_2p0); 820 ar9462_2p0_common_mixed_rx_gain);
691 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, 821 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
692 ar9462_2p0_baseband_core_mix_rxgain); 822 ar9462_2p0_baseband_core_mix_rxgain);
693 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble, 823 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
@@ -701,12 +831,12 @@ static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
701{ 831{
702 if (AR_SREV_9462_21(ah)) { 832 if (AR_SREV_9462_21(ah)) {
703 INIT_INI_ARRAY(&ah->iniModesRxGain, 833 INIT_INI_ARRAY(&ah->iniModesRxGain,
704 ar9462_2p1_common_5g_xlna_only_rx_gain); 834 ar9462_2p1_common_5g_xlna_only_rxgain);
705 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 835 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
706 ar9462_2p1_baseband_postamble_5g_xlna); 836 ar9462_2p1_baseband_postamble_5g_xlna);
707 } else if (AR_SREV_9462_20(ah)) { 837 } else if (AR_SREV_9462_20(ah)) {
708 INIT_INI_ARRAY(&ah->iniModesRxGain, 838 INIT_INI_ARRAY(&ah->iniModesRxGain,
709 ar9462_2p0_5g_xlna_only_rxgain); 839 ar9462_2p0_common_5g_xlna_only_rxgain);
710 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 840 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
711 ar9462_2p0_baseband_postamble_5g_xlna); 841 ar9462_2p0_baseband_postamble_5g_xlna);
712 } 842 }
@@ -750,6 +880,9 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
750static void ar9003_hw_configpcipowersave(struct ath_hw *ah, 880static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
751 bool power_off) 881 bool power_off)
752{ 882{
883 unsigned int i;
884 struct ar5416IniArray *array;
885
753 /* 886 /*
754 * Increase L1 Entry Latency. Some WB222 boards don't have 887 * Increase L1 Entry Latency. Some WB222 boards don't have
755 * this change in eeprom/OTP. 888 * this change in eeprom/OTP.
@@ -775,19 +908,125 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
775 * Configire PCIE after Ini init. SERDES values now come from ini file 908 * Configire PCIE after Ini init. SERDES values now come from ini file
776 * This enables PCIe low power mode. 909 * This enables PCIe low power mode.
777 */ 910 */
778 if (ah->config.pcieSerDesWrite) { 911 array = power_off ? &ah->iniPcieSerdes :
779 unsigned int i; 912 &ah->iniPcieSerdesLowPower;
780 struct ar5416IniArray *array; 913
914 for (i = 0; i < array->ia_rows; i++) {
915 REG_WRITE(ah,
916 INI_RA(array, i, 0),
917 INI_RA(array, i, 1));
918 }
919}
920
921static void ar9003_hw_init_hang_checks(struct ath_hw *ah)
922{
923 /*
924 * All chips support detection of BB/MAC hangs.
925 */
926 ah->config.hw_hang_checks |= HW_BB_WATCHDOG;
927 ah->config.hw_hang_checks |= HW_MAC_HANG;
928
929 /*
930 * This is not required for AR9580 1.0
931 */
932 if (AR_SREV_9300_22(ah))
933 ah->config.hw_hang_checks |= HW_PHYRESTART_CLC_WAR;
934
935 if (AR_SREV_9330(ah))
936 ah->bb_watchdog_timeout_ms = 85;
937 else
938 ah->bb_watchdog_timeout_ms = 25;
939}
781 940
782 array = power_off ? &ah->iniPcieSerdes : 941/*
783 &ah->iniPcieSerdesLowPower; 942 * MAC HW hang check
943 * =================
944 *
945 * Signature: dcu_chain_state is 0x6 and dcu_complete_state is 0x1.
946 *
947 * The state of each DCU chain (mapped to TX queues) is available from these
948 * DMA debug registers:
949 *
950 * Chain 0 state : Bits 4:0 of AR_DMADBG_4
951 * Chain 1 state : Bits 9:5 of AR_DMADBG_4
952 * Chain 2 state : Bits 14:10 of AR_DMADBG_4
953 * Chain 3 state : Bits 19:15 of AR_DMADBG_4
954 * Chain 4 state : Bits 24:20 of AR_DMADBG_4
955 * Chain 5 state : Bits 29:25 of AR_DMADBG_4
956 * Chain 6 state : Bits 4:0 of AR_DMADBG_5
957 * Chain 7 state : Bits 9:5 of AR_DMADBG_5
958 * Chain 8 state : Bits 14:10 of AR_DMADBG_5
959 * Chain 9 state : Bits 19:15 of AR_DMADBG_5
960 *
961 * The DCU chain state "0x6" means "WAIT_FRDONE" - wait for TX frame to be done.
962 */
963
964#define NUM_STATUS_READS 50
965
966static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue)
967{
968 u32 dma_dbg_chain, dma_dbg_complete;
969 u8 dcu_chain_state, dcu_complete_state;
970 int i;
971
972 for (i = 0; i < NUM_STATUS_READS; i++) {
973 if (queue < 6)
974 dma_dbg_chain = REG_READ(ah, AR_DMADBG_4);
975 else
976 dma_dbg_chain = REG_READ(ah, AR_DMADBG_5);
977
978 dma_dbg_complete = REG_READ(ah, AR_DMADBG_6);
979
980 dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f;
981 dcu_complete_state = dma_dbg_complete & 0x3;
982
983 if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1))
984 return false;
985 }
986
987 ath_dbg(ath9k_hw_common(ah), RESET,
988 "MAC Hang signature found for queue: %d\n", queue);
989
990 return true;
991}
992
993static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah)
994{
995 u32 dma_dbg_4, dma_dbg_5, dma_dbg_6, chk_dbg;
996 u8 dcu_chain_state, dcu_complete_state;
997 bool dcu_wait_frdone = false;
998 unsigned long chk_dcu = 0;
999 unsigned int i = 0;
1000
1001 dma_dbg_4 = REG_READ(ah, AR_DMADBG_4);
1002 dma_dbg_5 = REG_READ(ah, AR_DMADBG_5);
1003 dma_dbg_6 = REG_READ(ah, AR_DMADBG_6);
1004
1005 dcu_complete_state = dma_dbg_6 & 0x3;
1006 if (dcu_complete_state != 0x1)
1007 goto exit;
1008
1009 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1010 if (i < 6)
1011 chk_dbg = dma_dbg_4;
1012 else
1013 chk_dbg = dma_dbg_5;
1014
1015 dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f;
1016 if (dcu_chain_state == 0x6) {
1017 dcu_wait_frdone = true;
1018 chk_dcu |= BIT(i);
1019 }
1020 }
784 1021
785 for (i = 0; i < array->ia_rows; i++) { 1022 if ((dcu_complete_state == 0x1) && dcu_wait_frdone) {
786 REG_WRITE(ah, 1023 for_each_set_bit(i, &chk_dcu, ATH9K_NUM_TX_QUEUES) {
787 INI_RA(array, i, 0), 1024 if (ath9k_hw_verify_hang(ah, i))
788 INI_RA(array, i, 1)); 1025 return true;
789 } 1026 }
790 } 1027 }
1028exit:
1029 return false;
791} 1030}
792 1031
793/* Sets up the AR9003 hardware familiy callbacks */ 1032/* Sets up the AR9003 hardware familiy callbacks */
@@ -798,6 +1037,8 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
798 1037
799 ar9003_hw_init_mode_regs(ah); 1038 ar9003_hw_init_mode_regs(ah);
800 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; 1039 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
1040 priv_ops->init_hang_checks = ar9003_hw_init_hang_checks;
1041 priv_ops->detect_mac_hang = ar9003_hw_detect_mac_hang;
801 1042
802 ops->config_pci_powersave = ar9003_hw_configpcipowersave; 1043 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
803 1044
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index f6c5c1b50471..729ffbf07343 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -175,7 +175,8 @@ static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
175 ads->ctl10 |= ar9003_calc_ptr_chksum(ads); 175 ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
176} 176}
177 177
178static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) 178static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked,
179 u32 *sync_cause_p)
179{ 180{
180 u32 isr = 0; 181 u32 isr = 0;
181 u32 mask2 = 0; 182 u32 mask2 = 0;
@@ -310,7 +311,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
310 ar9003_mci_get_isr(ah, masked); 311 ar9003_mci_get_isr(ah, masked);
311 312
312 if (sync_cause) { 313 if (sync_cause) {
313 ath9k_debug_sync_cause(common, sync_cause); 314 if (sync_cause_p)
315 *sync_cause_p = sync_cause;
314 fatal_int = 316 fatal_int =
315 (sync_cause & 317 (sync_cause &
316 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) 318 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
@@ -476,12 +478,12 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
476 478
477 /* XXX: Keycache */ 479 /* XXX: Keycache */
478 rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); 480 rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
479 rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00); 481 rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
480 rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01); 482 rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
481 rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02); 483 rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
482 rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10); 484 rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
483 rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11); 485 rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
484 rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12); 486 rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
485 487
486 if (rxsp->status11 & AR_RxKeyIdxValid) 488 if (rxsp->status11 & AR_RxKeyIdxValid)
487 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx); 489 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index d39b79f5e841..09facba1dc6d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -103,7 +103,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
103 } else { 103 } else {
104 channelSel = CHANSEL_2G(freq) >> 1; 104 channelSel = CHANSEL_2G(freq) >> 1;
105 } 105 }
106 } else if (AR_SREV_9550(ah)) { 106 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
107 if (ah->is_clk_25mhz) 107 if (ah->is_clk_25mhz)
108 div = 75; 108 div = 75;
109 else 109 else
@@ -118,7 +118,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
118 /* Set to 2G mode */ 118 /* Set to 2G mode */
119 bMode = 1; 119 bMode = 1;
120 } else { 120 } else {
121 if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) && 121 if ((AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) &&
122 ah->is_clk_25mhz) { 122 ah->is_clk_25mhz) {
123 channelSel = freq / 75; 123 channelSel = freq / 75;
124 chan_frac = ((freq % 75) * 0x20000) / 75; 124 chan_frac = ((freq % 75) * 0x20000) / 75;
@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
641 else 641 else
642 ah->enabled_cals &= ~TX_IQ_CAL; 642 ah->enabled_cals &= ~TX_IQ_CAL;
643 643
644 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
645 ah->enabled_cals |= TX_CL_CAL;
646 else
647 ah->enabled_cals &= ~TX_CL_CAL;
648 } 644 }
645
646 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
647 ah->enabled_cals |= TX_CL_CAL;
648 else
649 ah->enabled_cals &= ~TX_CL_CAL;
649} 650}
650 651
651static void ar9003_hw_prog_ini(struct ath_hw *ah, 652static void ar9003_hw_prog_ini(struct ath_hw *ah,
@@ -809,10 +810,12 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
809 /* 810 /*
810 * TXGAIN initvals. 811 * TXGAIN initvals.
811 */ 812 */
812 if (AR_SREV_9550(ah)) { 813 if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
813 int modes_txgain_index; 814 int modes_txgain_index = 1;
815
816 if (AR_SREV_9550(ah))
817 modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan);
814 818
815 modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan);
816 if (modes_txgain_index < 0) 819 if (modes_txgain_index < 0)
817 return -EINVAL; 820 return -EINVAL;
818 821
@@ -1331,6 +1334,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1331static void ar9003_hw_set_radar_params(struct ath_hw *ah, 1334static void ar9003_hw_set_radar_params(struct ath_hw *ah,
1332 struct ath_hw_radar_conf *conf) 1335 struct ath_hw_radar_conf *conf)
1333{ 1336{
1337 unsigned int regWrites = 0;
1334 u32 radar_0 = 0, radar_1 = 0; 1338 u32 radar_0 = 0, radar_1 = 0;
1335 1339
1336 if (!conf) { 1340 if (!conf) {
@@ -1357,6 +1361,11 @@ static void ar9003_hw_set_radar_params(struct ath_hw *ah,
1357 REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); 1361 REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
1358 else 1362 else
1359 REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); 1363 REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
1364
1365 if (AR_SREV_9300(ah) || AR_SREV_9340(ah) || AR_SREV_9580(ah)) {
1366 REG_WRITE_ARRAY(&ah->ini_dfs,
1367 IS_CHAN_HT40(ah->curchan) ? 2 : 1, regWrites);
1368 }
1360} 1369}
1361 1370
1362static void ar9003_hw_set_radar_conf(struct ath_hw *ah) 1371static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
@@ -1807,6 +1816,68 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1807 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); 1816 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
1808} 1817}
1809 1818
1819/*
1820 * Baseband Watchdog signatures:
1821 *
1822 * 0x04000539: BB hang when operating in HT40 DFS Channel.
1823 * Full chip reset is not required, but a recovery
1824 * mechanism is needed.
1825 *
1826 * 0x1300000a: Related to CAC deafness.
1827 * Chip reset is not required.
1828 *
1829 * 0x0400000a: Related to CAC deafness.
1830 * Full chip reset is required.
1831 *
1832 * 0x04000b09: RX state machine gets into an illegal state
1833 * when a packet with unsupported rate is received.
1834 * Full chip reset is required and PHY_RESTART has
1835 * to be disabled.
1836 *
1837 * 0x04000409: Packet stuck on receive.
1838 * Full chip reset is required for all chips except AR9340.
1839 */
1840
1841/*
1842 * ar9003_hw_bb_watchdog_check(): Returns true if a chip reset is required.
1843 */
1844bool ar9003_hw_bb_watchdog_check(struct ath_hw *ah)
1845{
1846 u32 val;
1847
1848 switch(ah->bb_watchdog_last_status) {
1849 case 0x04000539:
1850 val = REG_READ(ah, AR_PHY_RADAR_0);
1851 val &= (~AR_PHY_RADAR_0_FIRPWR);
1852 val |= SM(0x7f, AR_PHY_RADAR_0_FIRPWR);
1853 REG_WRITE(ah, AR_PHY_RADAR_0, val);
1854 udelay(1);
1855 val = REG_READ(ah, AR_PHY_RADAR_0);
1856 val &= ~AR_PHY_RADAR_0_FIRPWR;
1857 val |= SM(AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR);
1858 REG_WRITE(ah, AR_PHY_RADAR_0, val);
1859
1860 return false;
1861 case 0x1300000a:
1862 return false;
1863 case 0x0400000a:
1864 case 0x04000b09:
1865 return true;
1866 case 0x04000409:
1867 if (AR_SREV_9340(ah) || AR_SREV_9531(ah))
1868 return false;
1869 else
1870 return true;
1871 default:
1872 /*
1873 * For any other unknown signatures, do a
1874 * full chip reset.
1875 */
1876 return true;
1877 }
1878}
1879EXPORT_SYMBOL(ar9003_hw_bb_watchdog_check);
1880
1810void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1881void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
1811{ 1882{
1812 struct ath_common *common = ath9k_hw_common(ah); 1883 struct ath_common *common = ath9k_hw_common(ah);
@@ -1923,6 +1994,7 @@ EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
1923 1994
1924void ar9003_hw_disable_phy_restart(struct ath_hw *ah) 1995void ar9003_hw_disable_phy_restart(struct ath_hw *ah)
1925{ 1996{
1997 u8 result;
1926 u32 val; 1998 u32 val;
1927 1999
1928 /* While receiving unsupported rate frame rx state machine 2000 /* While receiving unsupported rate frame rx state machine
@@ -1930,15 +2002,13 @@ void ar9003_hw_disable_phy_restart(struct ath_hw *ah)
1930 * state, BB would go hang. If RXSM is in 0xb state after 2002 * state, BB would go hang. If RXSM is in 0xb state after
1931 * first bb panic, ensure to disable the phy_restart. 2003 * first bb panic, ensure to disable the phy_restart.
1932 */ 2004 */
1933 if (!((MS(ah->bb_watchdog_last_status, 2005 result = MS(ah->bb_watchdog_last_status, AR_PHY_WATCHDOG_RX_OFDM_SM);
1934 AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) ||
1935 ah->bb_hang_rx_ofdm))
1936 return;
1937 2006
1938 ah->bb_hang_rx_ofdm = true; 2007 if ((result == 0xb) || ah->bb_hang_rx_ofdm) {
1939 val = REG_READ(ah, AR_PHY_RESTART); 2008 ah->bb_hang_rx_ofdm = true;
1940 val &= ~AR_PHY_RESTART_ENA; 2009 val = REG_READ(ah, AR_PHY_RESTART);
1941 2010 val &= ~AR_PHY_RESTART_ENA;
1942 REG_WRITE(ah, AR_PHY_RESTART, val); 2011 REG_WRITE(ah, AR_PHY_RESTART, val);
2012 }
1943} 2013}
1944EXPORT_SYMBOL(ar9003_hw_disable_phy_restart); 2014EXPORT_SYMBOL(ar9003_hw_disable_phy_restart);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 2af667beb273..fd090b1f2d0f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -270,7 +270,7 @@
270#define AR_PHY_AGC (AR_AGC_BASE + 0x14) 270#define AR_PHY_AGC (AR_AGC_BASE + 0x14)
271#define AR_PHY_EXT_ATTEN_CTL_0 (AR_AGC_BASE + 0x18) 271#define AR_PHY_EXT_ATTEN_CTL_0 (AR_AGC_BASE + 0x18)
272#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c) 272#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c)
273#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) 273#define AR_PHY_CCA_CTRL_0 (AR_AGC_BASE + 0x20)
274#define AR_PHY_RESTART (AR_AGC_BASE + 0x24) 274#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
275 275
276/* 276/*
@@ -338,17 +338,17 @@
338#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 338#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
339#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 339#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125
340#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 340#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125
341#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 341#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -60
342#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 342#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -60
343#define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_2GHZ -95
344#define AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_5GHZ -100
343 345
344#define AR_PHY_CCA_NOM_VAL_9462_2GHZ -127 346#define AR_PHY_CCA_NOM_VAL_9462_2GHZ -127
345#define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ -127 347#define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ -127
346#define AR_PHY_CCA_MAX_GOOD_VAL_9462_2GHZ -60 348#define AR_PHY_CCA_MAX_GOOD_VAL_9462_2GHZ -60
347#define AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_2GHZ -95
348#define AR_PHY_CCA_NOM_VAL_9462_5GHZ -127 349#define AR_PHY_CCA_NOM_VAL_9462_5GHZ -127
349#define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ -127 350#define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ -127
350#define AR_PHY_CCA_MAX_GOOD_VAL_9462_5GHZ -60 351#define AR_PHY_CCA_MAX_GOOD_VAL_9462_5GHZ -60
351#define AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_5GHZ -100
352 352
353#define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 353#define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118
354 354
@@ -397,6 +397,8 @@
397#define AR9280_PHY_CCA_THRESH62_S 12 397#define AR9280_PHY_CCA_THRESH62_S 12
398#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF 398#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
399#define AR_PHY_EXT_CCA0_THRESH62_S 0 399#define AR_PHY_EXT_CCA0_THRESH62_S 0
400#define AR_PHY_EXT_CCA0_THRESH62_1 0x000001FF
401#define AR_PHY_EXT_CCA0_THRESH62_1_S 0
400#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F 402#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
401#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 403#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
402#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 404#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
@@ -667,6 +669,16 @@
667#define AR_PHY_65NM_CH1_RXTX4 0x1650c 669#define AR_PHY_65NM_CH1_RXTX4 0x1650c
668#define AR_PHY_65NM_CH2_RXTX4 0x1690c 670#define AR_PHY_65NM_CH2_RXTX4 0x1690c
669 671
672#define AR_PHY_65NM_CH0_BB1 0x16140
673#define AR_PHY_65NM_CH0_BB2 0x16144
674#define AR_PHY_65NM_CH0_BB3 0x16148
675#define AR_PHY_65NM_CH1_BB1 0x16540
676#define AR_PHY_65NM_CH1_BB2 0x16544
677#define AR_PHY_65NM_CH1_BB3 0x16548
678#define AR_PHY_65NM_CH2_BB1 0x16940
679#define AR_PHY_65NM_CH2_BB2 0x16944
680#define AR_PHY_65NM_CH2_BB3 0x16948
681
670#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000 682#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000
671#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19 683#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19
672#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004 684#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004
@@ -1331,4 +1343,6 @@
1331#define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 1343#define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004
1332#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 1344#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2
1333 1345
1346#define AR9300_DFS_FIRPWR -28
1347
1334#endif /* AR9003_PHY_H */ 1348#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
new file mode 100644
index 000000000000..81c88dd606dc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (c) 2012 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/export.h>
18#include "ath9k.h"
19#include "reg.h"
20#include "hw-ops.h"
21
22const char *ath9k_hw_wow_event_to_string(u32 wow_event)
23{
24 if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
25 return "Magic pattern";
26 if (wow_event & AH_WOW_USER_PATTERN_EN)
27 return "User pattern";
28 if (wow_event & AH_WOW_LINK_CHANGE)
29 return "Link change";
30 if (wow_event & AH_WOW_BEACON_MISS)
31 return "Beacon miss";
32
33 return "unknown reason";
34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36
37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
38{
39 struct ath_common *common = ath9k_hw_common(ah);
40
41 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
42
43 /* set rx disable bit */
44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
45
46 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
49 return;
50 }
51
52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
53}
54
55static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
56{
57 struct ath_common *common = ath9k_hw_common(ah);
58 u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
59 u32 ctl[13] = {0};
60 u32 data_word[KAL_NUM_DATA_WORDS];
61 u8 i;
62 u32 wow_ka_data_word0;
63
64 memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
65 memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
66
67 /* set the transmit buffer */
68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
69 ctl[1] = 0;
70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
71 ctl[4] = 0;
72 ctl[7] = (ah->txchainmask) << 2;
73 ctl[2] = 0xf << 16; /* tx_tries 0 */
74
75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
77
78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
79
80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
82 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
83 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
84 data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
85 (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
86 data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
87 (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
88 data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
89 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
90 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
91
92 if (AR_SREV_9462_20(ah)) {
93 /* AR9462 2.0 has an extra descriptor word (time based
94 * discard) compared to other chips */
95 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
96 wow_ka_data_word0 = AR_WOW_TXBUF(13);
97 } else {
98 wow_ka_data_word0 = AR_WOW_TXBUF(12);
99 }
100
101 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
102 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
103
104}
105
106void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
107 u8 *user_mask, int pattern_count,
108 int pattern_len)
109{
110 int i;
111 u32 pattern_val, mask_val;
112 u32 set, clr;
113
114 /* FIXME: should check count by querying the hardware capability */
115 if (pattern_count >= MAX_NUM_PATTERN)
116 return;
117
118 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
119
120 /* set the registers for pattern */
121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
122 memcpy(&pattern_val, user_pattern, 4);
123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
124 pattern_val);
125 user_pattern += 4;
126 }
127
128 /* set the registers for mask */
129 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
130 memcpy(&mask_val, user_mask, 4);
131 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
132 user_mask += 4;
133 }
134
135 /* set the pattern length to be matched
136 *
137 * AR_WOW_LENGTH1_REG1
138 * bit 31:24 pattern 0 length
139 * bit 23:16 pattern 1 length
140 * bit 15:8 pattern 2 length
141 * bit 7:0 pattern 3 length
142 *
143 * AR_WOW_LENGTH1_REG2
144 * bit 31:24 pattern 4 length
145 * bit 23:16 pattern 5 length
146 * bit 15:8 pattern 6 length
147 * bit 7:0 pattern 7 length
148 *
149 * the below logic writes out the new
150 * pattern length for the corresponding
151 * pattern_count, while masking out the
152 * other fields
153 */
154
155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
156
157 if (pattern_count < 4) {
158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
160 AR_WOW_LEN1_SHIFT(pattern_count);
161 clr = AR_WOW_LENGTH1_MASK(pattern_count);
162 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
163 } else {
164 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
165 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
166 AR_WOW_LEN2_SHIFT(pattern_count);
167 clr = AR_WOW_LENGTH2_MASK(pattern_count);
168 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
169 }
170
171}
172EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
173
174u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
175{
176 u32 wow_status = 0;
177 u32 val = 0, rval;
178
179 /*
180 * read the WoW status register to know
181 * the wakeup reason
182 */
183 rval = REG_READ(ah, AR_WOW_PATTERN);
184 val = AR_WOW_STATUS(rval);
185
186 /*
187 * mask only the WoW events that we have enabled. Sometimes
188 * we have spurious WoW events from the AR_WOW_PATTERN
189 * register. This mask will clean it up.
190 */
191
192 val &= ah->wow_event_mask;
193
194 if (val) {
195 if (val & AR_WOW_MAGIC_PAT_FOUND)
196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
197 if (AR_WOW_PATTERN_FOUND(val))
198 wow_status |= AH_WOW_USER_PATTERN_EN;
199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
200 wow_status |= AH_WOW_LINK_CHANGE;
201 if (val & AR_WOW_BEACON_FAIL)
202 wow_status |= AH_WOW_BEACON_MISS;
203 }
204
205 /*
206 * set and clear WOW_PME_CLEAR registers for the chip to
207 * generate next wow signal.
208 * disable D3 before accessing other registers ?
209 */
210
211 /* do we need to check the bit value 0x01000000 (7-10) ?? */
212 REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
213 AR_PMCTRL_PWR_STATE_D1D3);
214
215 /*
216 * clear all events
217 */
218 REG_WRITE(ah, AR_WOW_PATTERN,
219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
220
221 /*
222 * restore the beacon threshold to init value
223 */
224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
225
226 /*
227 * Restore the way the PCI-E reset, Power-On-Reset, external
228 * PCIE_POR_SHORT pins are tied to its original value.
229 * Previously just before WoW sleep, we untie the PCI-E
230 * reset to our Chip's Power On Reset so that any PCI-E
231 * reset from the bus will not reset our chip
232 */
233 if (ah->is_pciexpress)
234 ath9k_hw_configpcipowersave(ah, false);
235
236 ah->wow_event_mask = 0;
237
238 return wow_status;
239}
240EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
241
242void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
243{
244 u32 wow_event_mask;
245 u32 set, clr;
246
247 /*
248 * wow_event_mask is a mask to the AR_WOW_PATTERN register to
249 * indicate which WoW events we have enabled. The WoW events
250 * are from the 'pattern_enable' in this function and
251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
252 */
253 wow_event_mask = ah->wow_event_mask;
254
255 /*
256 * Untie Power-on-Reset from the PCI-E-Reset. When we are in
257 * WOW sleep, we do want the Reset from the PCI-E to disturb
258 * our hw state
259 */
260 if (ah->is_pciexpress) {
261 /*
262 * we need to untie the internal POR (power-on-reset)
263 * to the external PCI-E reset. We also need to tie
264 * the PCI-E Phy reset to the PCI-E reset.
265 */
266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
268 REG_RMW(ah, AR_WA, set, clr);
269 }
270
271 /*
272 * set the power states appropriately and enable PME
273 */
274 set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
275 AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
276
277 /*
278 * set and clear WOW_PME_CLEAR registers for the chip
279 * to generate next wow signal.
280 */
281 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
282 clr = AR_PMCTRL_WOW_PME_CLR;
283 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
284
285 /*
286 * Setup for:
287 * - beacon misses
288 * - magic pattern
289 * - keep alive timeout
290 * - pattern matching
291 */
292
293 /*
294 * Program default values for pattern backoff, aifs/slot/KAL count,
295 * beacon miss timeout, KAL timeout, etc.
296 */
297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
299
300 set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
301 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
302 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
303 REG_SET_BIT(ah, AR_WOW_COUNT, set);
304
305 if (pattern_enable & AH_WOW_BEACON_MISS)
306 set = AR_WOW_BEACON_TIMO;
307 /* We are not using beacon miss, program a large value */
308 else
309 set = AR_WOW_BEACON_TIMO_MAX;
310
311 REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
312
313 /*
314 * Keep alive timo in ms except AR9280
315 */
316 if (!pattern_enable)
317 set = AR_WOW_KEEP_ALIVE_NEVER;
318 else
319 set = KAL_TIMEOUT * 32;
320
321 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
322
323 /*
324 * Keep alive delay in us. based on 'power on clock',
325 * therefore in usec
326 */
327 set = KAL_DELAY * 1000;
328 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
329
330 /*
331 * Create keep alive pattern to respond to beacons
332 */
333 ath9k_wow_create_keep_alive_pattern(ah);
334
335 /*
336 * Configure MAC WoW Registers
337 */
338 set = 0;
339 /* Send keep alive timeouts anyway */
340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
341
342 if (pattern_enable & AH_WOW_LINK_CHANGE)
343 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
344 else
345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
346
347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
349
350 /*
351 * we are relying on a bmiss failure. ensure we have
352 * enough threshold to prevent false positives
353 */
354 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
355 AR_WOW_BMISSTHRESHOLD);
356
357 set = 0;
358 clr = 0;
359
360 if (pattern_enable & AH_WOW_BEACON_MISS) {
361 set = AR_WOW_BEACON_FAIL_EN;
362 wow_event_mask |= AR_WOW_BEACON_FAIL;
363 } else {
364 clr = AR_WOW_BEACON_FAIL_EN;
365 }
366
367 REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
368
369 set = 0;
370 clr = 0;
371 /*
372 * Enable the magic packet registers
373 */
374 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
375 set = AR_WOW_MAGIC_EN;
376 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
377 } else {
378 clr = AR_WOW_MAGIC_EN;
379 }
380 set |= AR_WOW_MAC_INTR_EN;
381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
382
383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
384 AR_WOW_PATTERN_SUPPORTED);
385
386 /*
387 * Set the power states appropriately and enable PME
388 */
389 clr = 0;
390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
391 AR_PMCTRL_PWR_PM_CTRL_ENA;
392
393 clr = AR_PCIE_PM_CTRL_ENA;
394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
395
396 /*
397 * this is needed to prevent the chip waking up
398 * the host within 3-4 seconds with certain
399 * platform/BIOS. The fix is to enable
400 * D1 & D3 to match original definition and
401 * also match the OTP value. Anyway this
402 * is more related to SW WOW.
403 */
404 clr = AR_PMCTRL_PWR_STATE_D1D3;
405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
406
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
409
410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
411
412 /* to bring down WOW power low margin */
413 set = BIT(13);
414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
415 /* HW WoW */
416 clr = BIT(5);
417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
418
419 ath9k_hw_set_powermode_wow_sleep(ah);
420 ah->wow_event_mask = wow_event_mask;
421}
422EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
index 6e1756bc3833..f76139bbb74f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
@@ -18,6 +18,10 @@
18#ifndef INITVALS_9330_1P1_H 18#ifndef INITVALS_9330_1P1_H
19#define INITVALS_9330_1P1_H 19#define INITVALS_9330_1P1_H
20 20
21#define ar9331_1p1_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
22
23#define ar9331_modes_high_power_tx_gain_1p1 ar9331_modes_lowest_ob_db_tx_gain_1p1
24
21static const u32 ar9331_1p1_baseband_postamble[][5] = { 25static const u32 ar9331_1p1_baseband_postamble[][5] = {
22 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 26 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
23 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, 27 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
@@ -55,7 +59,7 @@ static const u32 ar9331_1p1_baseband_postamble[][5] = {
55 {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 59 {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
56 {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 60 {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
57 {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 61 {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
58 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 62 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
59 {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, 63 {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982},
60 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, 64 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
61 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 65 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -252,7 +256,7 @@ static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = {
252 {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, 256 {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84},
253 {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, 257 {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000},
254 {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, 258 {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000},
255 {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, 259 {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d4, 0x000050d4},
256 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, 260 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
257 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, 261 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
258 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, 262 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
@@ -337,8 +341,6 @@ static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = {
337 {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, 341 {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000},
338}; 342};
339 343
340#define ar9331_1p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
341
342static const u32 ar9331_1p1_xtal_25M[][2] = { 344static const u32 ar9331_1p1_xtal_25M[][2] = {
343 /* Addr allmodes */ 345 /* Addr allmodes */
344 {0x00007038, 0x000002f8}, 346 {0x00007038, 0x000002f8},
@@ -373,17 +375,17 @@ static const u32 ar9331_1p1_radio_core[][2] = {
373 {0x000160b4, 0x92480040}, 375 {0x000160b4, 0x92480040},
374 {0x000160c0, 0x006db6db}, 376 {0x000160c0, 0x006db6db},
375 {0x000160c4, 0x0186db60}, 377 {0x000160c4, 0x0186db60},
376 {0x000160c8, 0x6db4db6c}, 378 {0x000160c8, 0x6db6db6c},
377 {0x000160cc, 0x6de6c300}, 379 {0x000160cc, 0x6de6c300},
378 {0x000160d0, 0x14500820}, 380 {0x000160d0, 0x14500820},
379 {0x00016100, 0x04cb0001}, 381 {0x00016100, 0x04cb0001},
380 {0x00016104, 0xfff80015}, 382 {0x00016104, 0xfff80015},
381 {0x00016108, 0x00080010}, 383 {0x00016108, 0x00080010},
382 {0x0001610c, 0x00170000}, 384 {0x0001610c, 0x00170000},
383 {0x00016140, 0x10800000}, 385 {0x00016140, 0x50804000},
384 {0x00016144, 0x01884080}, 386 {0x00016144, 0x01884080},
385 {0x00016148, 0x000080c0}, 387 {0x00016148, 0x000080c0},
386 {0x00016280, 0x01000015}, 388 {0x00016280, 0x01001015},
387 {0x00016284, 0x14d20000}, 389 {0x00016284, 0x14d20000},
388 {0x00016288, 0x00318000}, 390 {0x00016288, 0x00318000},
389 {0x0001628c, 0x50000000}, 391 {0x0001628c, 0x50000000},
@@ -622,12 +624,12 @@ static const u32 ar9331_1p1_baseband_core[][2] = {
622 {0x0000a370, 0x00000000}, 624 {0x0000a370, 0x00000000},
623 {0x0000a390, 0x00000001}, 625 {0x0000a390, 0x00000001},
624 {0x0000a394, 0x00000444}, 626 {0x0000a394, 0x00000444},
625 {0x0000a398, 0x001f0e0f}, 627 {0x0000a398, 0x00000000},
626 {0x0000a39c, 0x0075393f}, 628 {0x0000a39c, 0x210d0401},
627 {0x0000a3a0, 0xb79f6427}, 629 {0x0000a3a0, 0xab9a7144},
628 {0x0000a3a4, 0x00000000}, 630 {0x0000a3a4, 0x00000011},
629 {0x0000a3a8, 0xaaaaaaaa}, 631 {0x0000a3a8, 0x3c3c003d},
630 {0x0000a3ac, 0x3c466478}, 632 {0x0000a3ac, 0x30310030},
631 {0x0000a3c0, 0x20202020}, 633 {0x0000a3c0, 0x20202020},
632 {0x0000a3c4, 0x22222220}, 634 {0x0000a3c4, 0x22222220},
633 {0x0000a3c8, 0x20200020}, 635 {0x0000a3c8, 0x20200020},
@@ -686,100 +688,18 @@ static const u32 ar9331_1p1_baseband_core[][2] = {
686 {0x0000a7dc, 0x00000001}, 688 {0x0000a7dc, 0x00000001},
687}; 689};
688 690
689static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { 691static const u32 ar9331_1p1_mac_postamble[][5] = {
690 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 692 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
691 {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, 693 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
692 {0x0000a2dc, 0xffff2a52, 0xffff2a52, 0xffff2a52, 0xffff2a52}, 694 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
693 {0x0000a2e0, 0xffffcc84, 0xffffcc84, 0xffffcc84, 0xffffcc84}, 695 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
694 {0x0000a2e4, 0xfffff000, 0xfffff000, 0xfffff000, 0xfffff000}, 696 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
695 {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffe0000, 0xfffe0000}, 697 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
696 {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d0, 0x000050d0}, 698 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
697 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, 699 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
698 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, 700 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
699 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
700 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
701 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
702 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
703 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
704 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
705 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00},
706 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02},
707 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04},
708 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2d000a20, 0x2d000a20},
709 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000a22, 0x31000a22},
710 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000a24, 0x35000a24},
711 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000a43, 0x38000a43},
712 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3b000e42, 0x3b000e42},
713 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x3f000e44, 0x3f000e44},
714 {0x0000a544, 0x6502feca, 0x6502feca, 0x42000e64, 0x42000e64},
715 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46000e66, 0x46000e66},
716 {0x0000a54c, 0x7203feca, 0x7203feca, 0x4a000ea6, 0x4a000ea6},
717 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4a000ea6, 0x4a000ea6},
718 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4a000ea6, 0x4a000ea6},
719 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x4a000ea6, 0x4a000ea6},
720 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x4a000ea6, 0x4a000ea6},
721 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x4a000ea6, 0x4a000ea6},
722 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x4a000ea6, 0x4a000ea6},
723 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
724 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
725 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
726 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
727 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
728 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x4a000ea6, 0x4a000ea6},
729 {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
730 {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
731 {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
732 {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200},
733 {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202},
734 {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400},
735 {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402},
736 {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404},
737 {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603},
738 {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02},
739 {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04},
740 {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20},
741 {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20},
742 {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22},
743 {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24},
744 {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640},
745 {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660},
746 {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861},
747 {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81},
748 {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83},
749 {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84},
750 {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3},
751 {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5},
752 {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9},
753 {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb},
754 {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec},
755 {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
756 {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
757 {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
758 {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
759 {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
760 {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
761 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
762 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
763 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
764 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
765 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
766 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
767 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
768 {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802},
769 {0x0000a620, 0x0280c802, 0x0280c802, 0x0280c802, 0x0280c802},
770 {0x0000a624, 0x03010a03, 0x03010a03, 0x03010a03, 0x03010a03},
771 {0x0000a628, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
772 {0x0000a62c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
773 {0x0000a630, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
774 {0x0000a634, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
775 {0x0000a638, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
776 {0x0000a63c, 0x03010c04, 0x03010c04, 0x03010c04, 0x03010c04},
777 {0x00016044, 0x034922db, 0x034922db, 0x034922db, 0x034922db},
778 {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000},
779}; 701};
780 702
781#define ar9331_1p1_mac_postamble ar9300_2p2_mac_postamble
782
783static const u32 ar9331_1p1_soc_preamble[][2] = { 703static const u32 ar9331_1p1_soc_preamble[][2] = {
784 /* Addr allmodes */ 704 /* Addr allmodes */
785 {0x00007020, 0x00000000}, 705 {0x00007020, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
index 57ed8a112173..0ac8be96097f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
@@ -18,6 +18,28 @@
18#ifndef INITVALS_9330_1P2_H 18#ifndef INITVALS_9330_1P2_H
19#define INITVALS_9330_1P2_H 19#define INITVALS_9330_1P2_H
20 20
21#define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2
22
23#define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2
24
25#define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2
26
27#define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484
28
29#define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M
30
31#define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M
32
33#define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble
34
35#define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble
36
37#define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble
38
39#define ar9331_1p2_mac_core ar9331_1p1_mac_core
40
41#define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1
42
21static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { 43static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = {
22 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 44 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
23 {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, 45 {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7},
@@ -103,57 +125,6 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = {
103 {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, 125 {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
104}; 126};
105 127
106#define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2
107
108#define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_power_tx_gain_1p2
109
110#define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_low_ob_db_tx_gain_1p2
111
112static const u32 ar9331_1p2_baseband_postamble[][5] = {
113 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
114 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
115 {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
116 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
117 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
118 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
119 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
120 {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
121 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4},
122 {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
123 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
124 {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e},
125 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
126 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
127 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
128 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
129 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221},
130 {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222},
131 {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
132 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
133 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
134 {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
135 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
136 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
137 {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff},
138 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
139 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
140 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
141 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
142 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
143 {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
144 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
145 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
146 {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
147 {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
148 {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
149 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
150 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981},
151 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
152 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
153 {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
154 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
155};
156
157static const u32 ar9331_1p2_radio_core[][2] = { 128static const u32 ar9331_1p2_radio_core[][2] = {
158 /* Addr allmodes */ 129 /* Addr allmodes */
159 {0x00016000, 0x36db6db6}, 130 {0x00016000, 0x36db6db6},
@@ -219,24 +190,318 @@ static const u32 ar9331_1p2_radio_core[][2] = {
219 {0x000163d4, 0x00000000}, 190 {0x000163d4, 0x00000000},
220}; 191};
221 192
222#define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484 193static const u32 ar9331_1p2_baseband_core[][2] = {
223 194 /* Addr allmodes */
224#define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M 195 {0x00009800, 0xafe68e30},
225 196 {0x00009804, 0xfd14e000},
226#define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M 197 {0x00009808, 0x9c0a8f6b},
227 198 {0x0000980c, 0x04800000},
228#define ar9331_1p2_baseband_core ar9331_1p1_baseband_core 199 {0x00009814, 0x9280c00a},
229 200 {0x00009818, 0x00000000},
230#define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble 201 {0x0000981c, 0x00020028},
231 202 {0x00009834, 0x5f3ca3de},
232#define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble 203 {0x00009838, 0x0108ecff},
233 204 {0x0000983c, 0x14750600},
234#define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble 205 {0x00009880, 0x201fff00},
235 206 {0x00009884, 0x00001042},
236#define ar9331_1p2_mac_core ar9331_1p1_mac_core 207 {0x000098a4, 0x00200400},
208 {0x000098b0, 0x32840bbe},
209 {0x000098d0, 0x004b6a8e},
210 {0x000098d4, 0x00000820},
211 {0x000098dc, 0x00000000},
212 {0x000098f0, 0x00000000},
213 {0x000098f4, 0x00000000},
214 {0x00009c04, 0x00000000},
215 {0x00009c08, 0x03200000},
216 {0x00009c0c, 0x00000000},
217 {0x00009c10, 0x00000000},
218 {0x00009c14, 0x00046384},
219 {0x00009c18, 0x05b6b440},
220 {0x00009c1c, 0x00b6b440},
221 {0x00009d00, 0xc080a333},
222 {0x00009d04, 0x40206c10},
223 {0x00009d08, 0x009c4060},
224 {0x00009d0c, 0x1883800a},
225 {0x00009d10, 0x01834061},
226 {0x00009d14, 0x00c00400},
227 {0x00009d18, 0x00000000},
228 {0x00009e08, 0x0038233c},
229 {0x00009e24, 0x9927b515},
230 {0x00009e28, 0x12ef0200},
231 {0x00009e30, 0x06336f77},
232 {0x00009e34, 0x6af6532f},
233 {0x00009e38, 0x0cc80c00},
234 {0x00009e40, 0x0d261820},
235 {0x00009e4c, 0x00001004},
236 {0x00009e50, 0x00ff03f1},
237 {0x00009fc0, 0x803e4788},
238 {0x00009fc4, 0x0001efb5},
239 {0x00009fcc, 0x40000014},
240 {0x0000a20c, 0x00000000},
241 {0x0000a220, 0x00000000},
242 {0x0000a224, 0x00000000},
243 {0x0000a228, 0x10002310},
244 {0x0000a23c, 0x00000000},
245 {0x0000a244, 0x0c000000},
246 {0x0000a2a0, 0x00000001},
247 {0x0000a2c0, 0x00000001},
248 {0x0000a2c8, 0x00000000},
249 {0x0000a2cc, 0x18c43433},
250 {0x0000a2d4, 0x00000000},
251 {0x0000a2dc, 0x00000000},
252 {0x0000a2e0, 0x00000000},
253 {0x0000a2e4, 0x00000000},
254 {0x0000a2e8, 0x00000000},
255 {0x0000a2ec, 0x00000000},
256 {0x0000a2f0, 0x00000000},
257 {0x0000a2f4, 0x00000000},
258 {0x0000a2f8, 0x00000000},
259 {0x0000a344, 0x00000000},
260 {0x0000a34c, 0x00000000},
261 {0x0000a350, 0x0000a000},
262 {0x0000a364, 0x00000000},
263 {0x0000a370, 0x00000000},
264 {0x0000a390, 0x00000001},
265 {0x0000a394, 0x00000444},
266 {0x0000a398, 0x001f0e0f},
267 {0x0000a39c, 0x0075393f},
268 {0x0000a3a0, 0xb79f6427},
269 {0x0000a3a4, 0x00000000},
270 {0x0000a3a8, 0xaaaaaaaa},
271 {0x0000a3ac, 0x3c466478},
272 {0x0000a3c0, 0x20202020},
273 {0x0000a3c4, 0x22222220},
274 {0x0000a3c8, 0x20200020},
275 {0x0000a3cc, 0x20202020},
276 {0x0000a3d0, 0x20202020},
277 {0x0000a3d4, 0x20202020},
278 {0x0000a3d8, 0x20202020},
279 {0x0000a3dc, 0x20202020},
280 {0x0000a3e0, 0x20202020},
281 {0x0000a3e4, 0x20202020},
282 {0x0000a3e8, 0x20202020},
283 {0x0000a3ec, 0x20202020},
284 {0x0000a3f0, 0x00000000},
285 {0x0000a3f4, 0x00000006},
286 {0x0000a3f8, 0x0cdbd380},
287 {0x0000a3fc, 0x000f0f01},
288 {0x0000a400, 0x8fa91f01},
289 {0x0000a404, 0x00000000},
290 {0x0000a408, 0x0e79e5c6},
291 {0x0000a40c, 0x00820820},
292 {0x0000a414, 0x1ce739ce},
293 {0x0000a418, 0x2d001dce},
294 {0x0000a41c, 0x1ce739ce},
295 {0x0000a420, 0x000001ce},
296 {0x0000a424, 0x1ce739ce},
297 {0x0000a428, 0x000001ce},
298 {0x0000a42c, 0x1ce739ce},
299 {0x0000a430, 0x1ce739ce},
300 {0x0000a434, 0x00000000},
301 {0x0000a438, 0x00001801},
302 {0x0000a43c, 0x00000000},
303 {0x0000a440, 0x00000000},
304 {0x0000a444, 0x00000000},
305 {0x0000a448, 0x04000000},
306 {0x0000a44c, 0x00000001},
307 {0x0000a450, 0x00010000},
308 {0x0000a458, 0x00000000},
309 {0x0000a640, 0x00000000},
310 {0x0000a644, 0x3fad9d74},
311 {0x0000a648, 0x0048060a},
312 {0x0000a64c, 0x00003c37},
313 {0x0000a670, 0x03020100},
314 {0x0000a674, 0x09080504},
315 {0x0000a678, 0x0d0c0b0a},
316 {0x0000a67c, 0x13121110},
317 {0x0000a680, 0x31301514},
318 {0x0000a684, 0x35343332},
319 {0x0000a688, 0x00000036},
320 {0x0000a690, 0x00000838},
321 {0x0000a7c0, 0x00000000},
322 {0x0000a7c4, 0xfffffffc},
323 {0x0000a7c8, 0x00000000},
324 {0x0000a7cc, 0x00000000},
325 {0x0000a7d0, 0x00000000},
326 {0x0000a7d4, 0x00000004},
327 {0x0000a7dc, 0x00000001},
328};
237 329
238#define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1 330static const u32 ar9331_1p2_baseband_postamble[][5] = {
331 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
332 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
333 {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
334 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
335 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
336 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
337 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
338 {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
339 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a4, 0x037216a4},
340 {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
341 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
342 {0x00009e10, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e},
343 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
344 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
345 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
346 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
347 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00003221, 0x00003221},
348 {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222},
349 {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
350 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
351 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
352 {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
353 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
354 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
355 {0x0000a234, 0x00000fff, 0x00000fff, 0x10000fff, 0x00000fff},
356 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
357 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
358 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
359 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
360 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
361 {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
362 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
363 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
364 {0x0000a284, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
365 {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
366 {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
367 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
368 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071981},
369 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
370 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
371 {0x0000ae04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
372 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
373};
239 374
240#define ar9331_common_rx_gain_1p2 ar9485_common_rx_gain_1_1 375static const u32 ar9331_common_rx_gain_1p2[][2] = {
376 /* Addr allmodes */
377 {0x0000a000, 0x00010000},
378 {0x0000a004, 0x00030002},
379 {0x0000a008, 0x00050004},
380 {0x0000a00c, 0x00810080},
381 {0x0000a010, 0x01800082},
382 {0x0000a014, 0x01820181},
383 {0x0000a018, 0x01840183},
384 {0x0000a01c, 0x01880185},
385 {0x0000a020, 0x018a0189},
386 {0x0000a024, 0x02850284},
387 {0x0000a028, 0x02890288},
388 {0x0000a02c, 0x03850384},
389 {0x0000a030, 0x03890388},
390 {0x0000a034, 0x038b038a},
391 {0x0000a038, 0x038d038c},
392 {0x0000a03c, 0x03910390},
393 {0x0000a040, 0x03930392},
394 {0x0000a044, 0x03950394},
395 {0x0000a048, 0x00000396},
396 {0x0000a04c, 0x00000000},
397 {0x0000a050, 0x00000000},
398 {0x0000a054, 0x00000000},
399 {0x0000a058, 0x00000000},
400 {0x0000a05c, 0x00000000},
401 {0x0000a060, 0x00000000},
402 {0x0000a064, 0x00000000},
403 {0x0000a068, 0x00000000},
404 {0x0000a06c, 0x00000000},
405 {0x0000a070, 0x00000000},
406 {0x0000a074, 0x00000000},
407 {0x0000a078, 0x00000000},
408 {0x0000a07c, 0x00000000},
409 {0x0000a080, 0x28282828},
410 {0x0000a084, 0x28282828},
411 {0x0000a088, 0x28282828},
412 {0x0000a08c, 0x28282828},
413 {0x0000a090, 0x28282828},
414 {0x0000a094, 0x21212128},
415 {0x0000a098, 0x171c1c1c},
416 {0x0000a09c, 0x02020212},
417 {0x0000a0a0, 0x00000202},
418 {0x0000a0a4, 0x00000000},
419 {0x0000a0a8, 0x00000000},
420 {0x0000a0ac, 0x00000000},
421 {0x0000a0b0, 0x00000000},
422 {0x0000a0b4, 0x00000000},
423 {0x0000a0b8, 0x00000000},
424 {0x0000a0bc, 0x00000000},
425 {0x0000a0c0, 0x001f0000},
426 {0x0000a0c4, 0x111f1100},
427 {0x0000a0c8, 0x111d111e},
428 {0x0000a0cc, 0x111b111c},
429 {0x0000a0d0, 0x22032204},
430 {0x0000a0d4, 0x22012202},
431 {0x0000a0d8, 0x221f2200},
432 {0x0000a0dc, 0x221d221e},
433 {0x0000a0e0, 0x33013302},
434 {0x0000a0e4, 0x331f3300},
435 {0x0000a0e8, 0x4402331e},
436 {0x0000a0ec, 0x44004401},
437 {0x0000a0f0, 0x441e441f},
438 {0x0000a0f4, 0x55015502},
439 {0x0000a0f8, 0x551f5500},
440 {0x0000a0fc, 0x6602551e},
441 {0x0000a100, 0x66006601},
442 {0x0000a104, 0x661e661f},
443 {0x0000a108, 0x7703661d},
444 {0x0000a10c, 0x77017702},
445 {0x0000a110, 0x00007700},
446 {0x0000a114, 0x00000000},
447 {0x0000a118, 0x00000000},
448 {0x0000a11c, 0x00000000},
449 {0x0000a120, 0x00000000},
450 {0x0000a124, 0x00000000},
451 {0x0000a128, 0x00000000},
452 {0x0000a12c, 0x00000000},
453 {0x0000a130, 0x00000000},
454 {0x0000a134, 0x00000000},
455 {0x0000a138, 0x00000000},
456 {0x0000a13c, 0x00000000},
457 {0x0000a140, 0x001f0000},
458 {0x0000a144, 0x111f1100},
459 {0x0000a148, 0x111d111e},
460 {0x0000a14c, 0x111b111c},
461 {0x0000a150, 0x22032204},
462 {0x0000a154, 0x22012202},
463 {0x0000a158, 0x221f2200},
464 {0x0000a15c, 0x221d221e},
465 {0x0000a160, 0x33013302},
466 {0x0000a164, 0x331f3300},
467 {0x0000a168, 0x4402331e},
468 {0x0000a16c, 0x44004401},
469 {0x0000a170, 0x441e441f},
470 {0x0000a174, 0x55015502},
471 {0x0000a178, 0x551f5500},
472 {0x0000a17c, 0x6602551e},
473 {0x0000a180, 0x66006601},
474 {0x0000a184, 0x661e661f},
475 {0x0000a188, 0x7703661d},
476 {0x0000a18c, 0x77017702},
477 {0x0000a190, 0x00007700},
478 {0x0000a194, 0x00000000},
479 {0x0000a198, 0x00000000},
480 {0x0000a19c, 0x00000000},
481 {0x0000a1a0, 0x00000000},
482 {0x0000a1a4, 0x00000000},
483 {0x0000a1a8, 0x00000000},
484 {0x0000a1ac, 0x00000000},
485 {0x0000a1b0, 0x00000000},
486 {0x0000a1b4, 0x00000000},
487 {0x0000a1b8, 0x00000000},
488 {0x0000a1bc, 0x00000000},
489 {0x0000a1c0, 0x00000000},
490 {0x0000a1c4, 0x00000000},
491 {0x0000a1c8, 0x00000000},
492 {0x0000a1cc, 0x00000000},
493 {0x0000a1d0, 0x00000000},
494 {0x0000a1d4, 0x00000000},
495 {0x0000a1d8, 0x00000000},
496 {0x0000a1dc, 0x00000000},
497 {0x0000a1e0, 0x00000000},
498 {0x0000a1e4, 0x00000000},
499 {0x0000a1e8, 0x00000000},
500 {0x0000a1ec, 0x00000000},
501 {0x0000a1f0, 0x00000396},
502 {0x0000a1f4, 0x00000396},
503 {0x0000a1f8, 0x00000396},
504 {0x0000a1fc, 0x00000296},
505};
241 506
242#endif /* INITVALS_9330_1P2_H */ 507#endif /* INITVALS_9330_1P2_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
index 25db9215985a..a01f0edb6518 100644
--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
@@ -18,6 +18,20 @@
18#ifndef INITVALS_9340_H 18#ifndef INITVALS_9340_H
19#define INITVALS_9340_H 19#define INITVALS_9340_H
20 20
21#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
22
23#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
24
25#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
26
27#define ar9340Common_rx_gain_table_1p0 ar9300Common_rx_gain_table_2p2
28
29#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
30
31#define ar9340_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
32
33#define ar9340_1p0_baseband_postamble_dfs_channel ar9300_2p2_baseband_postamble_dfs_channel
34
21static const u32 ar9340_1p0_radio_postamble[][5] = { 35static const u32 ar9340_1p0_radio_postamble[][5] = {
22 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
23 {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, 37 {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
@@ -100,8 +114,6 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
100 {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, 114 {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
101}; 115};
102 116
103#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
104
105static const u32 ar9340_1p0_radio_core[][2] = { 117static const u32 ar9340_1p0_radio_core[][2] = {
106 /* Addr allmodes */ 118 /* Addr allmodes */
107 {0x00016000, 0x36db6db6}, 119 {0x00016000, 0x36db6db6},
@@ -215,16 +227,12 @@ static const u32 ar9340_1p0_radio_core_40M[][2] = {
215 {0x0000824c, 0x0001e800}, 227 {0x0000824c, 0x0001e800},
216}; 228};
217 229
218#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
219
220#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
221
222static const u32 ar9340_1p0_baseband_postamble[][5] = { 230static const u32 ar9340_1p0_baseband_postamble[][5] = {
223 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 231 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
224 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 232 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
225 {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, 233 {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
226 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 234 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
227 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 235 {0x00009828, 0x06903081, 0x06903081, 0x09103881, 0x09103881},
228 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 236 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
229 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, 237 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
230 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, 238 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
@@ -340,9 +348,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
340 {0x0000a370, 0x00000000}, 348 {0x0000a370, 0x00000000},
341 {0x0000a390, 0x00000001}, 349 {0x0000a390, 0x00000001},
342 {0x0000a394, 0x00000444}, 350 {0x0000a394, 0x00000444},
343 {0x0000a398, 0x001f0e0f}, 351 {0x0000a398, 0x00000000},
344 {0x0000a39c, 0x0075393f}, 352 {0x0000a39c, 0x210d0401},
345 {0x0000a3a0, 0xb79f6427}, 353 {0x0000a3a0, 0xab9a7144},
346 {0x0000a3a4, 0x00000000}, 354 {0x0000a3a4, 0x00000000},
347 {0x0000a3a8, 0xaaaaaaaa}, 355 {0x0000a3a8, 0xaaaaaaaa},
348 {0x0000a3ac, 0x3c466478}, 356 {0x0000a3ac, 0x3c466478},
@@ -714,266 +722,6 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
714 {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, 722 {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000},
715}; 723};
716 724
717static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
718 /* Addr allmodes */
719 {0x0000a000, 0x00010000},
720 {0x0000a004, 0x00030002},
721 {0x0000a008, 0x00050004},
722 {0x0000a00c, 0x00810080},
723 {0x0000a010, 0x00830082},
724 {0x0000a014, 0x01810180},
725 {0x0000a018, 0x01830182},
726 {0x0000a01c, 0x01850184},
727 {0x0000a020, 0x01890188},
728 {0x0000a024, 0x018b018a},
729 {0x0000a028, 0x018d018c},
730 {0x0000a02c, 0x01910190},
731 {0x0000a030, 0x01930192},
732 {0x0000a034, 0x01950194},
733 {0x0000a038, 0x038a0196},
734 {0x0000a03c, 0x038c038b},
735 {0x0000a040, 0x0390038d},
736 {0x0000a044, 0x03920391},
737 {0x0000a048, 0x03940393},
738 {0x0000a04c, 0x03960395},
739 {0x0000a050, 0x00000000},
740 {0x0000a054, 0x00000000},
741 {0x0000a058, 0x00000000},
742 {0x0000a05c, 0x00000000},
743 {0x0000a060, 0x00000000},
744 {0x0000a064, 0x00000000},
745 {0x0000a068, 0x00000000},
746 {0x0000a06c, 0x00000000},
747 {0x0000a070, 0x00000000},
748 {0x0000a074, 0x00000000},
749 {0x0000a078, 0x00000000},
750 {0x0000a07c, 0x00000000},
751 {0x0000a080, 0x22222229},
752 {0x0000a084, 0x1d1d1d1d},
753 {0x0000a088, 0x1d1d1d1d},
754 {0x0000a08c, 0x1d1d1d1d},
755 {0x0000a090, 0x171d1d1d},
756 {0x0000a094, 0x11111717},
757 {0x0000a098, 0x00030311},
758 {0x0000a09c, 0x00000000},
759 {0x0000a0a0, 0x00000000},
760 {0x0000a0a4, 0x00000000},
761 {0x0000a0a8, 0x00000000},
762 {0x0000a0ac, 0x00000000},
763 {0x0000a0b0, 0x00000000},
764 {0x0000a0b4, 0x00000000},
765 {0x0000a0b8, 0x00000000},
766 {0x0000a0bc, 0x00000000},
767 {0x0000a0c0, 0x001f0000},
768 {0x0000a0c4, 0x01000101},
769 {0x0000a0c8, 0x011e011f},
770 {0x0000a0cc, 0x011c011d},
771 {0x0000a0d0, 0x02030204},
772 {0x0000a0d4, 0x02010202},
773 {0x0000a0d8, 0x021f0200},
774 {0x0000a0dc, 0x0302021e},
775 {0x0000a0e0, 0x03000301},
776 {0x0000a0e4, 0x031e031f},
777 {0x0000a0e8, 0x0402031d},
778 {0x0000a0ec, 0x04000401},
779 {0x0000a0f0, 0x041e041f},
780 {0x0000a0f4, 0x0502041d},
781 {0x0000a0f8, 0x05000501},
782 {0x0000a0fc, 0x051e051f},
783 {0x0000a100, 0x06010602},
784 {0x0000a104, 0x061f0600},
785 {0x0000a108, 0x061d061e},
786 {0x0000a10c, 0x07020703},
787 {0x0000a110, 0x07000701},
788 {0x0000a114, 0x00000000},
789 {0x0000a118, 0x00000000},
790 {0x0000a11c, 0x00000000},
791 {0x0000a120, 0x00000000},
792 {0x0000a124, 0x00000000},
793 {0x0000a128, 0x00000000},
794 {0x0000a12c, 0x00000000},
795 {0x0000a130, 0x00000000},
796 {0x0000a134, 0x00000000},
797 {0x0000a138, 0x00000000},
798 {0x0000a13c, 0x00000000},
799 {0x0000a140, 0x001f0000},
800 {0x0000a144, 0x01000101},
801 {0x0000a148, 0x011e011f},
802 {0x0000a14c, 0x011c011d},
803 {0x0000a150, 0x02030204},
804 {0x0000a154, 0x02010202},
805 {0x0000a158, 0x021f0200},
806 {0x0000a15c, 0x0302021e},
807 {0x0000a160, 0x03000301},
808 {0x0000a164, 0x031e031f},
809 {0x0000a168, 0x0402031d},
810 {0x0000a16c, 0x04000401},
811 {0x0000a170, 0x041e041f},
812 {0x0000a174, 0x0502041d},
813 {0x0000a178, 0x05000501},
814 {0x0000a17c, 0x051e051f},
815 {0x0000a180, 0x06010602},
816 {0x0000a184, 0x061f0600},
817 {0x0000a188, 0x061d061e},
818 {0x0000a18c, 0x07020703},
819 {0x0000a190, 0x07000701},
820 {0x0000a194, 0x00000000},
821 {0x0000a198, 0x00000000},
822 {0x0000a19c, 0x00000000},
823 {0x0000a1a0, 0x00000000},
824 {0x0000a1a4, 0x00000000},
825 {0x0000a1a8, 0x00000000},
826 {0x0000a1ac, 0x00000000},
827 {0x0000a1b0, 0x00000000},
828 {0x0000a1b4, 0x00000000},
829 {0x0000a1b8, 0x00000000},
830 {0x0000a1bc, 0x00000000},
831 {0x0000a1c0, 0x00000000},
832 {0x0000a1c4, 0x00000000},
833 {0x0000a1c8, 0x00000000},
834 {0x0000a1cc, 0x00000000},
835 {0x0000a1d0, 0x00000000},
836 {0x0000a1d4, 0x00000000},
837 {0x0000a1d8, 0x00000000},
838 {0x0000a1dc, 0x00000000},
839 {0x0000a1e0, 0x00000000},
840 {0x0000a1e4, 0x00000000},
841 {0x0000a1e8, 0x00000000},
842 {0x0000a1ec, 0x00000000},
843 {0x0000a1f0, 0x00000396},
844 {0x0000a1f4, 0x00000396},
845 {0x0000a1f8, 0x00000396},
846 {0x0000a1fc, 0x00000196},
847 {0x0000b000, 0x00010000},
848 {0x0000b004, 0x00030002},
849 {0x0000b008, 0x00050004},
850 {0x0000b00c, 0x00810080},
851 {0x0000b010, 0x00830082},
852 {0x0000b014, 0x01810180},
853 {0x0000b018, 0x01830182},
854 {0x0000b01c, 0x01850184},
855 {0x0000b020, 0x02810280},
856 {0x0000b024, 0x02830282},
857 {0x0000b028, 0x02850284},
858 {0x0000b02c, 0x02890288},
859 {0x0000b030, 0x028b028a},
860 {0x0000b034, 0x0388028c},
861 {0x0000b038, 0x038a0389},
862 {0x0000b03c, 0x038c038b},
863 {0x0000b040, 0x0390038d},
864 {0x0000b044, 0x03920391},
865 {0x0000b048, 0x03940393},
866 {0x0000b04c, 0x03960395},
867 {0x0000b050, 0x00000000},
868 {0x0000b054, 0x00000000},
869 {0x0000b058, 0x00000000},
870 {0x0000b05c, 0x00000000},
871 {0x0000b060, 0x00000000},
872 {0x0000b064, 0x00000000},
873 {0x0000b068, 0x00000000},
874 {0x0000b06c, 0x00000000},
875 {0x0000b070, 0x00000000},
876 {0x0000b074, 0x00000000},
877 {0x0000b078, 0x00000000},
878 {0x0000b07c, 0x00000000},
879 {0x0000b080, 0x23232323},
880 {0x0000b084, 0x21232323},
881 {0x0000b088, 0x19191c1e},
882 {0x0000b08c, 0x12141417},
883 {0x0000b090, 0x07070e0e},
884 {0x0000b094, 0x03030305},
885 {0x0000b098, 0x00000003},
886 {0x0000b09c, 0x00000000},
887 {0x0000b0a0, 0x00000000},
888 {0x0000b0a4, 0x00000000},
889 {0x0000b0a8, 0x00000000},
890 {0x0000b0ac, 0x00000000},
891 {0x0000b0b0, 0x00000000},
892 {0x0000b0b4, 0x00000000},
893 {0x0000b0b8, 0x00000000},
894 {0x0000b0bc, 0x00000000},
895 {0x0000b0c0, 0x003f0020},
896 {0x0000b0c4, 0x00400041},
897 {0x0000b0c8, 0x0140005f},
898 {0x0000b0cc, 0x0160015f},
899 {0x0000b0d0, 0x017e017f},
900 {0x0000b0d4, 0x02410242},
901 {0x0000b0d8, 0x025f0240},
902 {0x0000b0dc, 0x027f0260},
903 {0x0000b0e0, 0x0341027e},
904 {0x0000b0e4, 0x035f0340},
905 {0x0000b0e8, 0x037f0360},
906 {0x0000b0ec, 0x04400441},
907 {0x0000b0f0, 0x0460045f},
908 {0x0000b0f4, 0x0541047f},
909 {0x0000b0f8, 0x055f0540},
910 {0x0000b0fc, 0x057f0560},
911 {0x0000b100, 0x06400641},
912 {0x0000b104, 0x0660065f},
913 {0x0000b108, 0x067e067f},
914 {0x0000b10c, 0x07410742},
915 {0x0000b110, 0x075f0740},
916 {0x0000b114, 0x077f0760},
917 {0x0000b118, 0x07800781},
918 {0x0000b11c, 0x07a0079f},
919 {0x0000b120, 0x07c107bf},
920 {0x0000b124, 0x000007c0},
921 {0x0000b128, 0x00000000},
922 {0x0000b12c, 0x00000000},
923 {0x0000b130, 0x00000000},
924 {0x0000b134, 0x00000000},
925 {0x0000b138, 0x00000000},
926 {0x0000b13c, 0x00000000},
927 {0x0000b140, 0x003f0020},
928 {0x0000b144, 0x00400041},
929 {0x0000b148, 0x0140005f},
930 {0x0000b14c, 0x0160015f},
931 {0x0000b150, 0x017e017f},
932 {0x0000b154, 0x02410242},
933 {0x0000b158, 0x025f0240},
934 {0x0000b15c, 0x027f0260},
935 {0x0000b160, 0x0341027e},
936 {0x0000b164, 0x035f0340},
937 {0x0000b168, 0x037f0360},
938 {0x0000b16c, 0x04400441},
939 {0x0000b170, 0x0460045f},
940 {0x0000b174, 0x0541047f},
941 {0x0000b178, 0x055f0540},
942 {0x0000b17c, 0x057f0560},
943 {0x0000b180, 0x06400641},
944 {0x0000b184, 0x0660065f},
945 {0x0000b188, 0x067e067f},
946 {0x0000b18c, 0x07410742},
947 {0x0000b190, 0x075f0740},
948 {0x0000b194, 0x077f0760},
949 {0x0000b198, 0x07800781},
950 {0x0000b19c, 0x07a0079f},
951 {0x0000b1a0, 0x07c107bf},
952 {0x0000b1a4, 0x000007c0},
953 {0x0000b1a8, 0x00000000},
954 {0x0000b1ac, 0x00000000},
955 {0x0000b1b0, 0x00000000},
956 {0x0000b1b4, 0x00000000},
957 {0x0000b1b8, 0x00000000},
958 {0x0000b1bc, 0x00000000},
959 {0x0000b1c0, 0x00000000},
960 {0x0000b1c4, 0x00000000},
961 {0x0000b1c8, 0x00000000},
962 {0x0000b1cc, 0x00000000},
963 {0x0000b1d0, 0x00000000},
964 {0x0000b1d4, 0x00000000},
965 {0x0000b1d8, 0x00000000},
966 {0x0000b1dc, 0x00000000},
967 {0x0000b1e0, 0x00000000},
968 {0x0000b1e4, 0x00000000},
969 {0x0000b1e8, 0x00000000},
970 {0x0000b1ec, 0x00000000},
971 {0x0000b1f0, 0x00000396},
972 {0x0000b1f4, 0x00000396},
973 {0x0000b1f8, 0x00000396},
974 {0x0000b1fc, 0x00000196},
975};
976
977static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { 725static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
978 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 726 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
979 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 727 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -1437,8 +1185,6 @@ static const u32 ar9340_1p0_mac_core[][2] = {
1437 {0x000083d0, 0x000101ff}, 1185 {0x000083d0, 0x000101ff},
1438}; 1186};
1439 1187
1440#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
1441
1442static const u32 ar9340_1p0_soc_preamble[][2] = { 1188static const u32 ar9340_1p0_soc_preamble[][2] = {
1443 /* Addr allmodes */ 1189 /* Addr allmodes */
1444 {0x00007008, 0x00000000}, 1190 {0x00007008, 0x00000000},
@@ -1447,4 +1193,106 @@ static const u32 ar9340_1p0_soc_preamble[][2] = {
1447 {0x00007038, 0x000004c2}, 1193 {0x00007038, 0x000004c2},
1448}; 1194};
1449 1195
1196static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = {
1197 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1198 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1199 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1200 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1201 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1202 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1203 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1204 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1205 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1206 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1207 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1208 {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
1209 {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
1210 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
1211 {0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603},
1212 {0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02},
1213 {0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04},
1214 {0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20},
1215 {0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20},
1216 {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
1217 {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
1218 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
1219 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
1220 {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
1221 {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
1222 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83},
1223 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84},
1224 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3},
1225 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5},
1226 {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9},
1227 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb},
1228 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1229 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1230 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1231 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1232 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1233 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1234 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1235 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1236 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1237 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
1238 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
1239 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
1240 {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
1241 {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
1242 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
1243 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
1244 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
1245 {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
1246 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
1247 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
1248 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
1249 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
1250 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
1251 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
1252 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
1253 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
1254 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
1255 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
1256 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
1257 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
1258 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
1259 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
1260 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1261 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1262 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1263 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1264 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1265 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1266 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1267 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1268 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1269 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1270 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1271 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1272 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1273 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1274 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1275 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1276 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1277 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1278 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1279 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1280 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1281 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1282 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1283 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1284 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1285 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1286 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1287 {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
1288 {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
1289 {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
1290 {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000},
1291 {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
1292 {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
1293 {0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011},
1294 {0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c},
1295 {0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030},
1296};
1297
1450#endif /* INITVALS_9340_H */ 1298#endif /* INITVALS_9340_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 092b9d412e7f..1cc13569b17b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -20,7 +20,15 @@
20 20
21/* AR9462 2.0 */ 21/* AR9462 2.0 */
22 22
23static const u32 ar9462_modes_fast_clock_2p0[][3] = { 23#define ar9462_2p0_mac_postamble ar9331_1p1_mac_postamble
24
25#define ar9462_2p0_common_wo_xlna_rx_gain ar9300Common_wo_xlna_rx_gain_table_2p2
26
27#define ar9462_2p0_common_5g_xlna_only_rxgain ar9462_2p0_common_mixed_rx_gain
28
29#define ar9462_2p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
30
31static const u32 ar9462_2p0_modes_fast_clock[][3] = {
24 /* Addr 5G_HT20 5G_HT40 */ 32 /* Addr 5G_HT20 5G_HT40 */
25 {0x00001030, 0x00000268, 0x000004d0}, 33 {0x00001030, 0x00000268, 0x000004d0},
26 {0x00001070, 0x0000018c, 0x00000318}, 34 {0x00001070, 0x0000018c, 0x00000318},
@@ -33,13 +41,6 @@ static const u32 ar9462_modes_fast_clock_2p0[][3] = {
33 {0x0000a254, 0x00000898, 0x00001130}, 41 {0x0000a254, 0x00000898, 0x00001130},
34}; 42};
35 43
36static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
37 /* Addr allmodes */
38 {0x00018c00, 0x18253ede},
39 {0x00018c04, 0x000801d8},
40 {0x00018c08, 0x0003780c},
41};
42
43static const u32 ar9462_2p0_baseband_postamble[][5] = { 44static const u32 ar9462_2p0_baseband_postamble[][5] = {
44 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 45 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
45 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, 46 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -99,7 +100,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
99 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 100 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
100}; 101};
101 102
102static const u32 ar9462_common_rx_gain_table_2p0[][2] = { 103static const u32 ar9462_2p0_common_rx_gain[][2] = {
103 /* Addr allmodes */ 104 /* Addr allmodes */
104 {0x0000a000, 0x00010000}, 105 {0x0000a000, 0x00010000},
105 {0x0000a004, 0x00030002}, 106 {0x0000a004, 0x00030002},
@@ -359,20 +360,13 @@ static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
359 {0x0000b1fc, 0x00000196}, 360 {0x0000b1fc, 0x00000196},
360}; 361};
361 362
362static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = { 363static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = {
363 /* Addr allmodes */ 364 /* Addr allmodes */
364 {0x00018c00, 0x18213ede}, 365 {0x00018c00, 0x18213ede},
365 {0x00018c04, 0x000801d8}, 366 {0x00018c04, 0x000801d8},
366 {0x00018c08, 0x0003780c}, 367 {0x00018c08, 0x0003780c},
367}; 368};
368 369
369static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
370 /* Addr allmodes */
371 {0x00018c00, 0x18212ede},
372 {0x00018c04, 0x000801d8},
373 {0x00018c08, 0x0003780c},
374};
375
376static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { 370static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
377 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 371 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
378 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 372 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@@ -380,274 +374,7 @@ static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
380 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 374 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
381}; 375};
382 376
383static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { 377static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = {
384 /* Addr allmodes */
385 {0x0000a000, 0x00010000},
386 {0x0000a004, 0x00030002},
387 {0x0000a008, 0x00050004},
388 {0x0000a00c, 0x00810080},
389 {0x0000a010, 0x00830082},
390 {0x0000a014, 0x01810180},
391 {0x0000a018, 0x01830182},
392 {0x0000a01c, 0x01850184},
393 {0x0000a020, 0x01890188},
394 {0x0000a024, 0x018b018a},
395 {0x0000a028, 0x018d018c},
396 {0x0000a02c, 0x03820190},
397 {0x0000a030, 0x03840383},
398 {0x0000a034, 0x03880385},
399 {0x0000a038, 0x038a0389},
400 {0x0000a03c, 0x038c038b},
401 {0x0000a040, 0x0390038d},
402 {0x0000a044, 0x03920391},
403 {0x0000a048, 0x03940393},
404 {0x0000a04c, 0x03960395},
405 {0x0000a050, 0x00000000},
406 {0x0000a054, 0x00000000},
407 {0x0000a058, 0x00000000},
408 {0x0000a05c, 0x00000000},
409 {0x0000a060, 0x00000000},
410 {0x0000a064, 0x00000000},
411 {0x0000a068, 0x00000000},
412 {0x0000a06c, 0x00000000},
413 {0x0000a070, 0x00000000},
414 {0x0000a074, 0x00000000},
415 {0x0000a078, 0x00000000},
416 {0x0000a07c, 0x00000000},
417 {0x0000a080, 0x29292929},
418 {0x0000a084, 0x29292929},
419 {0x0000a088, 0x29292929},
420 {0x0000a08c, 0x29292929},
421 {0x0000a090, 0x22292929},
422 {0x0000a094, 0x1d1d2222},
423 {0x0000a098, 0x0c111117},
424 {0x0000a09c, 0x00030303},
425 {0x0000a0a0, 0x00000000},
426 {0x0000a0a4, 0x00000000},
427 {0x0000a0a8, 0x00000000},
428 {0x0000a0ac, 0x00000000},
429 {0x0000a0b0, 0x00000000},
430 {0x0000a0b4, 0x00000000},
431 {0x0000a0b8, 0x00000000},
432 {0x0000a0bc, 0x00000000},
433 {0x0000a0c0, 0x001f0000},
434 {0x0000a0c4, 0x01000101},
435 {0x0000a0c8, 0x011e011f},
436 {0x0000a0cc, 0x011c011d},
437 {0x0000a0d0, 0x02030204},
438 {0x0000a0d4, 0x02010202},
439 {0x0000a0d8, 0x021f0200},
440 {0x0000a0dc, 0x0302021e},
441 {0x0000a0e0, 0x03000301},
442 {0x0000a0e4, 0x031e031f},
443 {0x0000a0e8, 0x0402031d},
444 {0x0000a0ec, 0x04000401},
445 {0x0000a0f0, 0x041e041f},
446 {0x0000a0f4, 0x0502041d},
447 {0x0000a0f8, 0x05000501},
448 {0x0000a0fc, 0x051e051f},
449 {0x0000a100, 0x06010602},
450 {0x0000a104, 0x061f0600},
451 {0x0000a108, 0x061d061e},
452 {0x0000a10c, 0x07020703},
453 {0x0000a110, 0x07000701},
454 {0x0000a114, 0x00000000},
455 {0x0000a118, 0x00000000},
456 {0x0000a11c, 0x00000000},
457 {0x0000a120, 0x00000000},
458 {0x0000a124, 0x00000000},
459 {0x0000a128, 0x00000000},
460 {0x0000a12c, 0x00000000},
461 {0x0000a130, 0x00000000},
462 {0x0000a134, 0x00000000},
463 {0x0000a138, 0x00000000},
464 {0x0000a13c, 0x00000000},
465 {0x0000a140, 0x001f0000},
466 {0x0000a144, 0x01000101},
467 {0x0000a148, 0x011e011f},
468 {0x0000a14c, 0x011c011d},
469 {0x0000a150, 0x02030204},
470 {0x0000a154, 0x02010202},
471 {0x0000a158, 0x021f0200},
472 {0x0000a15c, 0x0302021e},
473 {0x0000a160, 0x03000301},
474 {0x0000a164, 0x031e031f},
475 {0x0000a168, 0x0402031d},
476 {0x0000a16c, 0x04000401},
477 {0x0000a170, 0x041e041f},
478 {0x0000a174, 0x0502041d},
479 {0x0000a178, 0x05000501},
480 {0x0000a17c, 0x051e051f},
481 {0x0000a180, 0x06010602},
482 {0x0000a184, 0x061f0600},
483 {0x0000a188, 0x061d061e},
484 {0x0000a18c, 0x07020703},
485 {0x0000a190, 0x07000701},
486 {0x0000a194, 0x00000000},
487 {0x0000a198, 0x00000000},
488 {0x0000a19c, 0x00000000},
489 {0x0000a1a0, 0x00000000},
490 {0x0000a1a4, 0x00000000},
491 {0x0000a1a8, 0x00000000},
492 {0x0000a1ac, 0x00000000},
493 {0x0000a1b0, 0x00000000},
494 {0x0000a1b4, 0x00000000},
495 {0x0000a1b8, 0x00000000},
496 {0x0000a1bc, 0x00000000},
497 {0x0000a1c0, 0x00000000},
498 {0x0000a1c4, 0x00000000},
499 {0x0000a1c8, 0x00000000},
500 {0x0000a1cc, 0x00000000},
501 {0x0000a1d0, 0x00000000},
502 {0x0000a1d4, 0x00000000},
503 {0x0000a1d8, 0x00000000},
504 {0x0000a1dc, 0x00000000},
505 {0x0000a1e0, 0x00000000},
506 {0x0000a1e4, 0x00000000},
507 {0x0000a1e8, 0x00000000},
508 {0x0000a1ec, 0x00000000},
509 {0x0000a1f0, 0x00000396},
510 {0x0000a1f4, 0x00000396},
511 {0x0000a1f8, 0x00000396},
512 {0x0000a1fc, 0x00000196},
513 {0x0000b000, 0x00010000},
514 {0x0000b004, 0x00030002},
515 {0x0000b008, 0x00050004},
516 {0x0000b00c, 0x00810080},
517 {0x0000b010, 0x00830082},
518 {0x0000b014, 0x01810180},
519 {0x0000b018, 0x01830182},
520 {0x0000b01c, 0x01850184},
521 {0x0000b020, 0x02810280},
522 {0x0000b024, 0x02830282},
523 {0x0000b028, 0x02850284},
524 {0x0000b02c, 0x02890288},
525 {0x0000b030, 0x028b028a},
526 {0x0000b034, 0x0388028c},
527 {0x0000b038, 0x038a0389},
528 {0x0000b03c, 0x038c038b},
529 {0x0000b040, 0x0390038d},
530 {0x0000b044, 0x03920391},
531 {0x0000b048, 0x03940393},
532 {0x0000b04c, 0x03960395},
533 {0x0000b050, 0x00000000},
534 {0x0000b054, 0x00000000},
535 {0x0000b058, 0x00000000},
536 {0x0000b05c, 0x00000000},
537 {0x0000b060, 0x00000000},
538 {0x0000b064, 0x00000000},
539 {0x0000b068, 0x00000000},
540 {0x0000b06c, 0x00000000},
541 {0x0000b070, 0x00000000},
542 {0x0000b074, 0x00000000},
543 {0x0000b078, 0x00000000},
544 {0x0000b07c, 0x00000000},
545 {0x0000b080, 0x32323232},
546 {0x0000b084, 0x2f2f3232},
547 {0x0000b088, 0x23282a2d},
548 {0x0000b08c, 0x1c1e2123},
549 {0x0000b090, 0x14171919},
550 {0x0000b094, 0x0e0e1214},
551 {0x0000b098, 0x03050707},
552 {0x0000b09c, 0x00030303},
553 {0x0000b0a0, 0x00000000},
554 {0x0000b0a4, 0x00000000},
555 {0x0000b0a8, 0x00000000},
556 {0x0000b0ac, 0x00000000},
557 {0x0000b0b0, 0x00000000},
558 {0x0000b0b4, 0x00000000},
559 {0x0000b0b8, 0x00000000},
560 {0x0000b0bc, 0x00000000},
561 {0x0000b0c0, 0x003f0020},
562 {0x0000b0c4, 0x00400041},
563 {0x0000b0c8, 0x0140005f},
564 {0x0000b0cc, 0x0160015f},
565 {0x0000b0d0, 0x017e017f},
566 {0x0000b0d4, 0x02410242},
567 {0x0000b0d8, 0x025f0240},
568 {0x0000b0dc, 0x027f0260},
569 {0x0000b0e0, 0x0341027e},
570 {0x0000b0e4, 0x035f0340},
571 {0x0000b0e8, 0x037f0360},
572 {0x0000b0ec, 0x04400441},
573 {0x0000b0f0, 0x0460045f},
574 {0x0000b0f4, 0x0541047f},
575 {0x0000b0f8, 0x055f0540},
576 {0x0000b0fc, 0x057f0560},
577 {0x0000b100, 0x06400641},
578 {0x0000b104, 0x0660065f},
579 {0x0000b108, 0x067e067f},
580 {0x0000b10c, 0x07410742},
581 {0x0000b110, 0x075f0740},
582 {0x0000b114, 0x077f0760},
583 {0x0000b118, 0x07800781},
584 {0x0000b11c, 0x07a0079f},
585 {0x0000b120, 0x07c107bf},
586 {0x0000b124, 0x000007c0},
587 {0x0000b128, 0x00000000},
588 {0x0000b12c, 0x00000000},
589 {0x0000b130, 0x00000000},
590 {0x0000b134, 0x00000000},
591 {0x0000b138, 0x00000000},
592 {0x0000b13c, 0x00000000},
593 {0x0000b140, 0x003f0020},
594 {0x0000b144, 0x00400041},
595 {0x0000b148, 0x0140005f},
596 {0x0000b14c, 0x0160015f},
597 {0x0000b150, 0x017e017f},
598 {0x0000b154, 0x02410242},
599 {0x0000b158, 0x025f0240},
600 {0x0000b15c, 0x027f0260},
601 {0x0000b160, 0x0341027e},
602 {0x0000b164, 0x035f0340},
603 {0x0000b168, 0x037f0360},
604 {0x0000b16c, 0x04400441},
605 {0x0000b170, 0x0460045f},
606 {0x0000b174, 0x0541047f},
607 {0x0000b178, 0x055f0540},
608 {0x0000b17c, 0x057f0560},
609 {0x0000b180, 0x06400641},
610 {0x0000b184, 0x0660065f},
611 {0x0000b188, 0x067e067f},
612 {0x0000b18c, 0x07410742},
613 {0x0000b190, 0x075f0740},
614 {0x0000b194, 0x077f0760},
615 {0x0000b198, 0x07800781},
616 {0x0000b19c, 0x07a0079f},
617 {0x0000b1a0, 0x07c107bf},
618 {0x0000b1a4, 0x000007c0},
619 {0x0000b1a8, 0x00000000},
620 {0x0000b1ac, 0x00000000},
621 {0x0000b1b0, 0x00000000},
622 {0x0000b1b4, 0x00000000},
623 {0x0000b1b8, 0x00000000},
624 {0x0000b1bc, 0x00000000},
625 {0x0000b1c0, 0x00000000},
626 {0x0000b1c4, 0x00000000},
627 {0x0000b1c8, 0x00000000},
628 {0x0000b1cc, 0x00000000},
629 {0x0000b1d0, 0x00000000},
630 {0x0000b1d4, 0x00000000},
631 {0x0000b1d8, 0x00000000},
632 {0x0000b1dc, 0x00000000},
633 {0x0000b1e0, 0x00000000},
634 {0x0000b1e4, 0x00000000},
635 {0x0000b1e8, 0x00000000},
636 {0x0000b1ec, 0x00000000},
637 {0x0000b1f0, 0x00000396},
638 {0x0000b1f4, 0x00000396},
639 {0x0000b1f8, 0x00000396},
640 {0x0000b1fc, 0x00000196},
641};
642
643static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
644 /* Addr allmodes */
645 {0x0000a398, 0x00000000},
646 {0x0000a39c, 0x6f7f0301},
647 {0x0000a3a0, 0xca9228ee},
648};
649
650static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
651 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 378 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
652 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 379 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
653 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 380 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -879,7 +606,7 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 606 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
880}; 607};
881 608
882static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = { 609static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 610 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 611 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
885 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 612 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -942,7 +669,7 @@ static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
942 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 669 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
943}; 670};
944 671
945static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { 672static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = {
946 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 673 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
947 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 674 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
948 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 675 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -1240,19 +967,7 @@ static const u32 ar9462_2p0_mac_core[][2] = {
1240 {0x000083d0, 0x000301ff}, 967 {0x000083d0, 0x000301ff},
1241}; 968};
1242 969
1243static const u32 ar9462_2p0_mac_postamble[][5] = { 970static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = {
1244 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1245 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
1246 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
1247 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
1248 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
1249 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
1250 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
1251 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
1252 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
1253};
1254
1255static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
1256 /* Addr allmodes */ 971 /* Addr allmodes */
1257 {0x0000a000, 0x00010000}, 972 {0x0000a000, 0x00010000},
1258 {0x0000a004, 0x00030002}, 973 {0x0000a004, 0x00030002},
@@ -1517,266 +1232,6 @@ static const u32 ar9462_2p0_baseband_postamble_5g_xlna[][5] = {
1517 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, 1232 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1518}; 1233};
1519 1234
1520static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
1521 /* Addr allmodes */
1522 {0x0000a000, 0x00010000},
1523 {0x0000a004, 0x00030002},
1524 {0x0000a008, 0x00050004},
1525 {0x0000a00c, 0x00810080},
1526 {0x0000a010, 0x00830082},
1527 {0x0000a014, 0x01810180},
1528 {0x0000a018, 0x01830182},
1529 {0x0000a01c, 0x01850184},
1530 {0x0000a020, 0x01890188},
1531 {0x0000a024, 0x018b018a},
1532 {0x0000a028, 0x018d018c},
1533 {0x0000a02c, 0x03820190},
1534 {0x0000a030, 0x03840383},
1535 {0x0000a034, 0x03880385},
1536 {0x0000a038, 0x038a0389},
1537 {0x0000a03c, 0x038c038b},
1538 {0x0000a040, 0x0390038d},
1539 {0x0000a044, 0x03920391},
1540 {0x0000a048, 0x03940393},
1541 {0x0000a04c, 0x03960395},
1542 {0x0000a050, 0x00000000},
1543 {0x0000a054, 0x00000000},
1544 {0x0000a058, 0x00000000},
1545 {0x0000a05c, 0x00000000},
1546 {0x0000a060, 0x00000000},
1547 {0x0000a064, 0x00000000},
1548 {0x0000a068, 0x00000000},
1549 {0x0000a06c, 0x00000000},
1550 {0x0000a070, 0x00000000},
1551 {0x0000a074, 0x00000000},
1552 {0x0000a078, 0x00000000},
1553 {0x0000a07c, 0x00000000},
1554 {0x0000a080, 0x29292929},
1555 {0x0000a084, 0x29292929},
1556 {0x0000a088, 0x29292929},
1557 {0x0000a08c, 0x29292929},
1558 {0x0000a090, 0x22292929},
1559 {0x0000a094, 0x1d1d2222},
1560 {0x0000a098, 0x0c111117},
1561 {0x0000a09c, 0x00030303},
1562 {0x0000a0a0, 0x00000000},
1563 {0x0000a0a4, 0x00000000},
1564 {0x0000a0a8, 0x00000000},
1565 {0x0000a0ac, 0x00000000},
1566 {0x0000a0b0, 0x00000000},
1567 {0x0000a0b4, 0x00000000},
1568 {0x0000a0b8, 0x00000000},
1569 {0x0000a0bc, 0x00000000},
1570 {0x0000a0c0, 0x001f0000},
1571 {0x0000a0c4, 0x01000101},
1572 {0x0000a0c8, 0x011e011f},
1573 {0x0000a0cc, 0x011c011d},
1574 {0x0000a0d0, 0x02030204},
1575 {0x0000a0d4, 0x02010202},
1576 {0x0000a0d8, 0x021f0200},
1577 {0x0000a0dc, 0x0302021e},
1578 {0x0000a0e0, 0x03000301},
1579 {0x0000a0e4, 0x031e031f},
1580 {0x0000a0e8, 0x0402031d},
1581 {0x0000a0ec, 0x04000401},
1582 {0x0000a0f0, 0x041e041f},
1583 {0x0000a0f4, 0x0502041d},
1584 {0x0000a0f8, 0x05000501},
1585 {0x0000a0fc, 0x051e051f},
1586 {0x0000a100, 0x06010602},
1587 {0x0000a104, 0x061f0600},
1588 {0x0000a108, 0x061d061e},
1589 {0x0000a10c, 0x07020703},
1590 {0x0000a110, 0x07000701},
1591 {0x0000a114, 0x00000000},
1592 {0x0000a118, 0x00000000},
1593 {0x0000a11c, 0x00000000},
1594 {0x0000a120, 0x00000000},
1595 {0x0000a124, 0x00000000},
1596 {0x0000a128, 0x00000000},
1597 {0x0000a12c, 0x00000000},
1598 {0x0000a130, 0x00000000},
1599 {0x0000a134, 0x00000000},
1600 {0x0000a138, 0x00000000},
1601 {0x0000a13c, 0x00000000},
1602 {0x0000a140, 0x001f0000},
1603 {0x0000a144, 0x01000101},
1604 {0x0000a148, 0x011e011f},
1605 {0x0000a14c, 0x011c011d},
1606 {0x0000a150, 0x02030204},
1607 {0x0000a154, 0x02010202},
1608 {0x0000a158, 0x021f0200},
1609 {0x0000a15c, 0x0302021e},
1610 {0x0000a160, 0x03000301},
1611 {0x0000a164, 0x031e031f},
1612 {0x0000a168, 0x0402031d},
1613 {0x0000a16c, 0x04000401},
1614 {0x0000a170, 0x041e041f},
1615 {0x0000a174, 0x0502041d},
1616 {0x0000a178, 0x05000501},
1617 {0x0000a17c, 0x051e051f},
1618 {0x0000a180, 0x06010602},
1619 {0x0000a184, 0x061f0600},
1620 {0x0000a188, 0x061d061e},
1621 {0x0000a18c, 0x07020703},
1622 {0x0000a190, 0x07000701},
1623 {0x0000a194, 0x00000000},
1624 {0x0000a198, 0x00000000},
1625 {0x0000a19c, 0x00000000},
1626 {0x0000a1a0, 0x00000000},
1627 {0x0000a1a4, 0x00000000},
1628 {0x0000a1a8, 0x00000000},
1629 {0x0000a1ac, 0x00000000},
1630 {0x0000a1b0, 0x00000000},
1631 {0x0000a1b4, 0x00000000},
1632 {0x0000a1b8, 0x00000000},
1633 {0x0000a1bc, 0x00000000},
1634 {0x0000a1c0, 0x00000000},
1635 {0x0000a1c4, 0x00000000},
1636 {0x0000a1c8, 0x00000000},
1637 {0x0000a1cc, 0x00000000},
1638 {0x0000a1d0, 0x00000000},
1639 {0x0000a1d4, 0x00000000},
1640 {0x0000a1d8, 0x00000000},
1641 {0x0000a1dc, 0x00000000},
1642 {0x0000a1e0, 0x00000000},
1643 {0x0000a1e4, 0x00000000},
1644 {0x0000a1e8, 0x00000000},
1645 {0x0000a1ec, 0x00000000},
1646 {0x0000a1f0, 0x00000396},
1647 {0x0000a1f4, 0x00000396},
1648 {0x0000a1f8, 0x00000396},
1649 {0x0000a1fc, 0x00000196},
1650 {0x0000b000, 0x00010000},
1651 {0x0000b004, 0x00030002},
1652 {0x0000b008, 0x00050004},
1653 {0x0000b00c, 0x00810080},
1654 {0x0000b010, 0x00830082},
1655 {0x0000b014, 0x01810180},
1656 {0x0000b018, 0x01830182},
1657 {0x0000b01c, 0x01850184},
1658 {0x0000b020, 0x02810280},
1659 {0x0000b024, 0x02830282},
1660 {0x0000b028, 0x02850284},
1661 {0x0000b02c, 0x02890288},
1662 {0x0000b030, 0x028b028a},
1663 {0x0000b034, 0x0388028c},
1664 {0x0000b038, 0x038a0389},
1665 {0x0000b03c, 0x038c038b},
1666 {0x0000b040, 0x0390038d},
1667 {0x0000b044, 0x03920391},
1668 {0x0000b048, 0x03940393},
1669 {0x0000b04c, 0x03960395},
1670 {0x0000b050, 0x00000000},
1671 {0x0000b054, 0x00000000},
1672 {0x0000b058, 0x00000000},
1673 {0x0000b05c, 0x00000000},
1674 {0x0000b060, 0x00000000},
1675 {0x0000b064, 0x00000000},
1676 {0x0000b068, 0x00000000},
1677 {0x0000b06c, 0x00000000},
1678 {0x0000b070, 0x00000000},
1679 {0x0000b074, 0x00000000},
1680 {0x0000b078, 0x00000000},
1681 {0x0000b07c, 0x00000000},
1682 {0x0000b080, 0x2a2d2f32},
1683 {0x0000b084, 0x21232328},
1684 {0x0000b088, 0x19191c1e},
1685 {0x0000b08c, 0x12141417},
1686 {0x0000b090, 0x07070e0e},
1687 {0x0000b094, 0x03030305},
1688 {0x0000b098, 0x00000003},
1689 {0x0000b09c, 0x00000000},
1690 {0x0000b0a0, 0x00000000},
1691 {0x0000b0a4, 0x00000000},
1692 {0x0000b0a8, 0x00000000},
1693 {0x0000b0ac, 0x00000000},
1694 {0x0000b0b0, 0x00000000},
1695 {0x0000b0b4, 0x00000000},
1696 {0x0000b0b8, 0x00000000},
1697 {0x0000b0bc, 0x00000000},
1698 {0x0000b0c0, 0x003f0020},
1699 {0x0000b0c4, 0x00400041},
1700 {0x0000b0c8, 0x0140005f},
1701 {0x0000b0cc, 0x0160015f},
1702 {0x0000b0d0, 0x017e017f},
1703 {0x0000b0d4, 0x02410242},
1704 {0x0000b0d8, 0x025f0240},
1705 {0x0000b0dc, 0x027f0260},
1706 {0x0000b0e0, 0x0341027e},
1707 {0x0000b0e4, 0x035f0340},
1708 {0x0000b0e8, 0x037f0360},
1709 {0x0000b0ec, 0x04400441},
1710 {0x0000b0f0, 0x0460045f},
1711 {0x0000b0f4, 0x0541047f},
1712 {0x0000b0f8, 0x055f0540},
1713 {0x0000b0fc, 0x057f0560},
1714 {0x0000b100, 0x06400641},
1715 {0x0000b104, 0x0660065f},
1716 {0x0000b108, 0x067e067f},
1717 {0x0000b10c, 0x07410742},
1718 {0x0000b110, 0x075f0740},
1719 {0x0000b114, 0x077f0760},
1720 {0x0000b118, 0x07800781},
1721 {0x0000b11c, 0x07a0079f},
1722 {0x0000b120, 0x07c107bf},
1723 {0x0000b124, 0x000007c0},
1724 {0x0000b128, 0x00000000},
1725 {0x0000b12c, 0x00000000},
1726 {0x0000b130, 0x00000000},
1727 {0x0000b134, 0x00000000},
1728 {0x0000b138, 0x00000000},
1729 {0x0000b13c, 0x00000000},
1730 {0x0000b140, 0x003f0020},
1731 {0x0000b144, 0x00400041},
1732 {0x0000b148, 0x0140005f},
1733 {0x0000b14c, 0x0160015f},
1734 {0x0000b150, 0x017e017f},
1735 {0x0000b154, 0x02410242},
1736 {0x0000b158, 0x025f0240},
1737 {0x0000b15c, 0x027f0260},
1738 {0x0000b160, 0x0341027e},
1739 {0x0000b164, 0x035f0340},
1740 {0x0000b168, 0x037f0360},
1741 {0x0000b16c, 0x04400441},
1742 {0x0000b170, 0x0460045f},
1743 {0x0000b174, 0x0541047f},
1744 {0x0000b178, 0x055f0540},
1745 {0x0000b17c, 0x057f0560},
1746 {0x0000b180, 0x06400641},
1747 {0x0000b184, 0x0660065f},
1748 {0x0000b188, 0x067e067f},
1749 {0x0000b18c, 0x07410742},
1750 {0x0000b190, 0x075f0740},
1751 {0x0000b194, 0x077f0760},
1752 {0x0000b198, 0x07800781},
1753 {0x0000b19c, 0x07a0079f},
1754 {0x0000b1a0, 0x07c107bf},
1755 {0x0000b1a4, 0x000007c0},
1756 {0x0000b1a8, 0x00000000},
1757 {0x0000b1ac, 0x00000000},
1758 {0x0000b1b0, 0x00000000},
1759 {0x0000b1b4, 0x00000000},
1760 {0x0000b1b8, 0x00000000},
1761 {0x0000b1bc, 0x00000000},
1762 {0x0000b1c0, 0x00000000},
1763 {0x0000b1c4, 0x00000000},
1764 {0x0000b1c8, 0x00000000},
1765 {0x0000b1cc, 0x00000000},
1766 {0x0000b1d0, 0x00000000},
1767 {0x0000b1d4, 0x00000000},
1768 {0x0000b1d8, 0x00000000},
1769 {0x0000b1dc, 0x00000000},
1770 {0x0000b1e0, 0x00000000},
1771 {0x0000b1e4, 0x00000000},
1772 {0x0000b1e8, 0x00000000},
1773 {0x0000b1ec, 0x00000000},
1774 {0x0000b1f0, 0x00000396},
1775 {0x0000b1f4, 0x00000396},
1776 {0x0000b1f8, 0x00000396},
1777 {0x0000b1fc, 0x00000196},
1778};
1779
1780static const u32 ar9462_2p0_baseband_core_mix_rxgain[][2] = { 1235static const u32 ar9462_2p0_baseband_core_mix_rxgain[][2] = {
1781 /* Addr allmodes */ 1236 /* Addr allmodes */
1782 {0x00009fd0, 0x0a2d6b93}, 1237 {0x00009fd0, 0x0a2d6b93},
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
index 57fc5f459d0a..dc3adda46e8b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
@@ -20,6 +20,44 @@
20 20
21/* AR9462 2.1 */ 21/* AR9462 2.1 */
22 22
23#define ar9462_2p1_mac_postamble ar9462_2p0_mac_postamble
24
25#define ar9462_2p1_baseband_core ar9462_2p0_baseband_core
26
27#define ar9462_2p1_radio_core ar9462_2p0_radio_core
28
29#define ar9462_2p1_radio_postamble ar9462_2p0_radio_postamble
30
31#define ar9462_2p1_soc_postamble ar9462_2p0_soc_postamble
32
33#define ar9462_2p1_radio_postamble_sys2ant ar9462_2p0_radio_postamble_sys2ant
34
35#define ar9462_2p1_common_rx_gain ar9462_2p0_common_rx_gain
36
37#define ar9462_2p1_common_mixed_rx_gain ar9462_2p0_common_mixed_rx_gain
38
39#define ar9462_2p1_common_5g_xlna_only_rxgain ar9462_2p0_common_5g_xlna_only_rxgain
40
41#define ar9462_2p1_baseband_core_mix_rxgain ar9462_2p0_baseband_core_mix_rxgain
42
43#define ar9462_2p1_baseband_postamble_mix_rxgain ar9462_2p0_baseband_postamble_mix_rxgain
44
45#define ar9462_2p1_baseband_postamble_5g_xlna ar9462_2p0_baseband_postamble_5g_xlna
46
47#define ar9462_2p1_common_wo_xlna_rx_gain ar9462_2p0_common_wo_xlna_rx_gain
48
49#define ar9462_2p1_modes_low_ob_db_tx_gain ar9462_2p0_modes_low_ob_db_tx_gain
50
51#define ar9462_2p1_modes_high_ob_db_tx_gain ar9462_2p0_modes_high_ob_db_tx_gain
52
53#define ar9462_2p1_modes_mix_ob_db_tx_gain ar9462_2p0_modes_mix_ob_db_tx_gain
54
55#define ar9462_2p1_modes_fast_clock ar9462_2p0_modes_fast_clock
56
57#define ar9462_2p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
58
59#define ar9462_2p1_pciephy_clkreq_disable_L1 ar9462_2p0_pciephy_clkreq_disable_L1
60
23static const u32 ar9462_2p1_mac_core[][2] = { 61static const u32 ar9462_2p1_mac_core[][2] = {
24 /* Addr allmodes */ 62 /* Addr allmodes */
25 {0x00000008, 0x00000000}, 63 {0x00000008, 0x00000000},
@@ -183,168 +221,6 @@ static const u32 ar9462_2p1_mac_core[][2] = {
183 {0x000083d0, 0x000301ff}, 221 {0x000083d0, 0x000301ff},
184}; 222};
185 223
186static const u32 ar9462_2p1_mac_postamble[][5] = {
187 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
188 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
189 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
190 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
191 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
192 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
193 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
194 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
195 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
196};
197
198static const u32 ar9462_2p1_baseband_core[][2] = {
199 /* Addr allmodes */
200 {0x00009800, 0xafe68e30},
201 {0x00009804, 0xfd14e000},
202 {0x00009808, 0x9c0a9f6b},
203 {0x0000980c, 0x04900000},
204 {0x00009814, 0x9280c00a},
205 {0x00009818, 0x00000000},
206 {0x0000981c, 0x00020028},
207 {0x00009834, 0x6400a290},
208 {0x00009838, 0x0108ecff},
209 {0x0000983c, 0x0d000600},
210 {0x00009880, 0x201fff00},
211 {0x00009884, 0x00001042},
212 {0x000098a4, 0x00200400},
213 {0x000098b0, 0x32440bbe},
214 {0x000098d0, 0x004b6a8e},
215 {0x000098d4, 0x00000820},
216 {0x000098dc, 0x00000000},
217 {0x000098e4, 0x01ffffff},
218 {0x000098e8, 0x01ffffff},
219 {0x000098ec, 0x01ffffff},
220 {0x000098f0, 0x00000000},
221 {0x000098f4, 0x00000000},
222 {0x00009bf0, 0x80000000},
223 {0x00009c04, 0xff55ff55},
224 {0x00009c08, 0x0320ff55},
225 {0x00009c0c, 0x00000000},
226 {0x00009c10, 0x00000000},
227 {0x00009c14, 0x00046384},
228 {0x00009c18, 0x05b6b440},
229 {0x00009c1c, 0x00b6b440},
230 {0x00009d00, 0xc080a333},
231 {0x00009d04, 0x40206c10},
232 {0x00009d08, 0x009c4060},
233 {0x00009d0c, 0x9883800a},
234 {0x00009d10, 0x01834061},
235 {0x00009d14, 0x00c0040b},
236 {0x00009d18, 0x00000000},
237 {0x00009e08, 0x0038230c},
238 {0x00009e24, 0x990bb515},
239 {0x00009e28, 0x0c6f0000},
240 {0x00009e30, 0x06336f77},
241 {0x00009e34, 0x6af6532f},
242 {0x00009e38, 0x0cc80c00},
243 {0x00009e40, 0x15262820},
244 {0x00009e4c, 0x00001004},
245 {0x00009e50, 0x00ff03f1},
246 {0x00009e54, 0xe4c555c2},
247 {0x00009e58, 0xfd857722},
248 {0x00009e5c, 0xe9198724},
249 {0x00009fc0, 0x803e4788},
250 {0x00009fc4, 0x0001efb5},
251 {0x00009fcc, 0x40000014},
252 {0x00009fd0, 0x0a193b93},
253 {0x0000a20c, 0x00000000},
254 {0x0000a220, 0x00000000},
255 {0x0000a224, 0x00000000},
256 {0x0000a228, 0x10002310},
257 {0x0000a23c, 0x00000000},
258 {0x0000a244, 0x0c000000},
259 {0x0000a2a0, 0x00000001},
260 {0x0000a2c0, 0x00000001},
261 {0x0000a2c8, 0x00000000},
262 {0x0000a2cc, 0x18c43433},
263 {0x0000a2d4, 0x00000000},
264 {0x0000a2ec, 0x00000000},
265 {0x0000a2f0, 0x00000000},
266 {0x0000a2f4, 0x00000000},
267 {0x0000a2f8, 0x00000000},
268 {0x0000a344, 0x00000000},
269 {0x0000a34c, 0x00000000},
270 {0x0000a350, 0x0000a000},
271 {0x0000a364, 0x00000000},
272 {0x0000a370, 0x00000000},
273 {0x0000a390, 0x00000001},
274 {0x0000a394, 0x00000444},
275 {0x0000a398, 0x001f0e0f},
276 {0x0000a39c, 0x0075393f},
277 {0x0000a3a0, 0xb79f6427},
278 {0x0000a3c0, 0x20202020},
279 {0x0000a3c4, 0x22222220},
280 {0x0000a3c8, 0x20200020},
281 {0x0000a3cc, 0x20202020},
282 {0x0000a3d0, 0x20202020},
283 {0x0000a3d4, 0x20202020},
284 {0x0000a3d8, 0x20202020},
285 {0x0000a3dc, 0x20202020},
286 {0x0000a3e0, 0x20202020},
287 {0x0000a3e4, 0x20202020},
288 {0x0000a3e8, 0x20202020},
289 {0x0000a3ec, 0x20202020},
290 {0x0000a3f0, 0x00000000},
291 {0x0000a3f4, 0x00000006},
292 {0x0000a3f8, 0x0c9bd380},
293 {0x0000a3fc, 0x000f0f01},
294 {0x0000a400, 0x8fa91f01},
295 {0x0000a404, 0x00000000},
296 {0x0000a408, 0x0e79e5c6},
297 {0x0000a40c, 0x00820820},
298 {0x0000a414, 0x1ce739ce},
299 {0x0000a418, 0x2d001dce},
300 {0x0000a434, 0x00000000},
301 {0x0000a438, 0x00001801},
302 {0x0000a43c, 0x00100000},
303 {0x0000a444, 0x00000000},
304 {0x0000a448, 0x05000080},
305 {0x0000a44c, 0x00000001},
306 {0x0000a450, 0x00010000},
307 {0x0000a454, 0x07000000},
308 {0x0000a644, 0xbfad9d74},
309 {0x0000a648, 0x0048060a},
310 {0x0000a64c, 0x00002037},
311 {0x0000a670, 0x03020100},
312 {0x0000a674, 0x09080504},
313 {0x0000a678, 0x0d0c0b0a},
314 {0x0000a67c, 0x13121110},
315 {0x0000a680, 0x31301514},
316 {0x0000a684, 0x35343332},
317 {0x0000a688, 0x00000036},
318 {0x0000a690, 0x00000838},
319 {0x0000a6b0, 0x0000000a},
320 {0x0000a6b4, 0x00512c01},
321 {0x0000a7c0, 0x00000000},
322 {0x0000a7c4, 0xfffffffc},
323 {0x0000a7c8, 0x00000000},
324 {0x0000a7cc, 0x00000000},
325 {0x0000a7d0, 0x00000000},
326 {0x0000a7d4, 0x00000004},
327 {0x0000a7dc, 0x00000000},
328 {0x0000a7f0, 0x80000000},
329 {0x0000a8d0, 0x004b6a8e},
330 {0x0000a8d4, 0x00000820},
331 {0x0000a8dc, 0x00000000},
332 {0x0000a8f0, 0x00000000},
333 {0x0000a8f4, 0x00000000},
334 {0x0000abf0, 0x80000000},
335 {0x0000b2d0, 0x00000080},
336 {0x0000b2d4, 0x00000000},
337 {0x0000b2ec, 0x00000000},
338 {0x0000b2f0, 0x00000000},
339 {0x0000b2f4, 0x00000000},
340 {0x0000b2f8, 0x00000000},
341 {0x0000b408, 0x0e79e5c0},
342 {0x0000b40c, 0x00820820},
343 {0x0000b420, 0x00000000},
344 {0x0000b6b0, 0x0000000a},
345 {0x0000b6b4, 0x00000001},
346};
347
348static const u32 ar9462_2p1_baseband_postamble[][5] = { 224static const u32 ar9462_2p1_baseband_postamble[][5] = {
349 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 225 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
350 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, 226 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -404,72 +280,6 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
404 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 280 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
405}; 281};
406 282
407static const u32 ar9462_2p1_radio_core[][2] = {
408 /* Addr allmodes */
409 {0x00016000, 0x36db6db6},
410 {0x00016004, 0x6db6db40},
411 {0x00016008, 0x73f00000},
412 {0x0001600c, 0x00000000},
413 {0x00016010, 0x6d820001},
414 {0x00016040, 0x7f80fff8},
415 {0x0001604c, 0x2699e04f},
416 {0x00016050, 0x6db6db6c},
417 {0x00016058, 0x6c200000},
418 {0x00016080, 0x000c0000},
419 {0x00016084, 0x9a68048c},
420 {0x00016088, 0x54214514},
421 {0x0001608c, 0x1203040b},
422 {0x00016090, 0x24926490},
423 {0x00016098, 0xd2888888},
424 {0x000160a0, 0x0a108ffe},
425 {0x000160a4, 0x812fc491},
426 {0x000160a8, 0x423c8000},
427 {0x000160b4, 0x92000000},
428 {0x000160b8, 0x0285dddc},
429 {0x000160bc, 0x02908888},
430 {0x000160c0, 0x00adb6d0},
431 {0x000160c4, 0x6db6db60},
432 {0x000160c8, 0x6db6db6c},
433 {0x000160cc, 0x0de6c1b0},
434 {0x00016100, 0x3fffbe04},
435 {0x00016104, 0xfff80000},
436 {0x00016108, 0x00200400},
437 {0x00016110, 0x00000000},
438 {0x00016144, 0x02084080},
439 {0x00016148, 0x000080c0},
440 {0x00016280, 0x050a0001},
441 {0x00016284, 0x3d841418},
442 {0x00016288, 0x00000000},
443 {0x0001628c, 0xe3000000},
444 {0x00016290, 0xa1005080},
445 {0x00016294, 0x00000020},
446 {0x00016298, 0x54a82900},
447 {0x00016340, 0x121e4276},
448 {0x00016344, 0x00300000},
449 {0x00016400, 0x36db6db6},
450 {0x00016404, 0x6db6db40},
451 {0x00016408, 0x73f00000},
452 {0x0001640c, 0x00000000},
453 {0x00016410, 0x6c800001},
454 {0x00016440, 0x7f80fff8},
455 {0x0001644c, 0x4699e04f},
456 {0x00016450, 0x6db6db6c},
457 {0x00016500, 0x3fffbe04},
458 {0x00016504, 0xfff80000},
459 {0x00016508, 0x00200400},
460 {0x00016510, 0x00000000},
461 {0x00016544, 0x02084080},
462 {0x00016548, 0x000080c0},
463};
464
465static const u32 ar9462_2p1_radio_postamble[][5] = {
466 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
467 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
468 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
469 {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
470 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
471};
472
473static const u32 ar9462_2p1_soc_preamble[][2] = { 283static const u32 ar9462_2p1_soc_preamble[][2] = {
474 /* Addr allmodes */ 284 /* Addr allmodes */
475 {0x000040a4, 0x00a0c9c9}, 285 {0x000040a4, 0x00a0c9c9},
@@ -478,1297 +288,4 @@ static const u32 ar9462_2p1_soc_preamble[][2] = {
478 {0x00007038, 0x000004c2}, 288 {0x00007038, 0x000004c2},
479}; 289};
480 290
481static const u32 ar9462_2p1_soc_postamble[][5] = {
482 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
483 {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
484};
485
486static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
487 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
488 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
489 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
490 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
491};
492
493static const u32 ar9462_2p1_common_rx_gain[][2] = {
494 /* Addr allmodes */
495 {0x0000a000, 0x00010000},
496 {0x0000a004, 0x00030002},
497 {0x0000a008, 0x00050004},
498 {0x0000a00c, 0x00810080},
499 {0x0000a010, 0x00830082},
500 {0x0000a014, 0x01810180},
501 {0x0000a018, 0x01830182},
502 {0x0000a01c, 0x01850184},
503 {0x0000a020, 0x01890188},
504 {0x0000a024, 0x018b018a},
505 {0x0000a028, 0x018d018c},
506 {0x0000a02c, 0x01910190},
507 {0x0000a030, 0x01930192},
508 {0x0000a034, 0x01950194},
509 {0x0000a038, 0x038a0196},
510 {0x0000a03c, 0x038c038b},
511 {0x0000a040, 0x0390038d},
512 {0x0000a044, 0x03920391},
513 {0x0000a048, 0x03940393},
514 {0x0000a04c, 0x03960395},
515 {0x0000a050, 0x00000000},
516 {0x0000a054, 0x00000000},
517 {0x0000a058, 0x00000000},
518 {0x0000a05c, 0x00000000},
519 {0x0000a060, 0x00000000},
520 {0x0000a064, 0x00000000},
521 {0x0000a068, 0x00000000},
522 {0x0000a06c, 0x00000000},
523 {0x0000a070, 0x00000000},
524 {0x0000a074, 0x00000000},
525 {0x0000a078, 0x00000000},
526 {0x0000a07c, 0x00000000},
527 {0x0000a080, 0x22222229},
528 {0x0000a084, 0x1d1d1d1d},
529 {0x0000a088, 0x1d1d1d1d},
530 {0x0000a08c, 0x1d1d1d1d},
531 {0x0000a090, 0x171d1d1d},
532 {0x0000a094, 0x11111717},
533 {0x0000a098, 0x00030311},
534 {0x0000a09c, 0x00000000},
535 {0x0000a0a0, 0x00000000},
536 {0x0000a0a4, 0x00000000},
537 {0x0000a0a8, 0x00000000},
538 {0x0000a0ac, 0x00000000},
539 {0x0000a0b0, 0x00000000},
540 {0x0000a0b4, 0x00000000},
541 {0x0000a0b8, 0x00000000},
542 {0x0000a0bc, 0x00000000},
543 {0x0000a0c0, 0x001f0000},
544 {0x0000a0c4, 0x01000101},
545 {0x0000a0c8, 0x011e011f},
546 {0x0000a0cc, 0x011c011d},
547 {0x0000a0d0, 0x02030204},
548 {0x0000a0d4, 0x02010202},
549 {0x0000a0d8, 0x021f0200},
550 {0x0000a0dc, 0x0302021e},
551 {0x0000a0e0, 0x03000301},
552 {0x0000a0e4, 0x031e031f},
553 {0x0000a0e8, 0x0402031d},
554 {0x0000a0ec, 0x04000401},
555 {0x0000a0f0, 0x041e041f},
556 {0x0000a0f4, 0x0502041d},
557 {0x0000a0f8, 0x05000501},
558 {0x0000a0fc, 0x051e051f},
559 {0x0000a100, 0x06010602},
560 {0x0000a104, 0x061f0600},
561 {0x0000a108, 0x061d061e},
562 {0x0000a10c, 0x07020703},
563 {0x0000a110, 0x07000701},
564 {0x0000a114, 0x00000000},
565 {0x0000a118, 0x00000000},
566 {0x0000a11c, 0x00000000},
567 {0x0000a120, 0x00000000},
568 {0x0000a124, 0x00000000},
569 {0x0000a128, 0x00000000},
570 {0x0000a12c, 0x00000000},
571 {0x0000a130, 0x00000000},
572 {0x0000a134, 0x00000000},
573 {0x0000a138, 0x00000000},
574 {0x0000a13c, 0x00000000},
575 {0x0000a140, 0x001f0000},
576 {0x0000a144, 0x01000101},
577 {0x0000a148, 0x011e011f},
578 {0x0000a14c, 0x011c011d},
579 {0x0000a150, 0x02030204},
580 {0x0000a154, 0x02010202},
581 {0x0000a158, 0x021f0200},
582 {0x0000a15c, 0x0302021e},
583 {0x0000a160, 0x03000301},
584 {0x0000a164, 0x031e031f},
585 {0x0000a168, 0x0402031d},
586 {0x0000a16c, 0x04000401},
587 {0x0000a170, 0x041e041f},
588 {0x0000a174, 0x0502041d},
589 {0x0000a178, 0x05000501},
590 {0x0000a17c, 0x051e051f},
591 {0x0000a180, 0x06010602},
592 {0x0000a184, 0x061f0600},
593 {0x0000a188, 0x061d061e},
594 {0x0000a18c, 0x07020703},
595 {0x0000a190, 0x07000701},
596 {0x0000a194, 0x00000000},
597 {0x0000a198, 0x00000000},
598 {0x0000a19c, 0x00000000},
599 {0x0000a1a0, 0x00000000},
600 {0x0000a1a4, 0x00000000},
601 {0x0000a1a8, 0x00000000},
602 {0x0000a1ac, 0x00000000},
603 {0x0000a1b0, 0x00000000},
604 {0x0000a1b4, 0x00000000},
605 {0x0000a1b8, 0x00000000},
606 {0x0000a1bc, 0x00000000},
607 {0x0000a1c0, 0x00000000},
608 {0x0000a1c4, 0x00000000},
609 {0x0000a1c8, 0x00000000},
610 {0x0000a1cc, 0x00000000},
611 {0x0000a1d0, 0x00000000},
612 {0x0000a1d4, 0x00000000},
613 {0x0000a1d8, 0x00000000},
614 {0x0000a1dc, 0x00000000},
615 {0x0000a1e0, 0x00000000},
616 {0x0000a1e4, 0x00000000},
617 {0x0000a1e8, 0x00000000},
618 {0x0000a1ec, 0x00000000},
619 {0x0000a1f0, 0x00000396},
620 {0x0000a1f4, 0x00000396},
621 {0x0000a1f8, 0x00000396},
622 {0x0000a1fc, 0x00000196},
623 {0x0000b000, 0x00010000},
624 {0x0000b004, 0x00030002},
625 {0x0000b008, 0x00050004},
626 {0x0000b00c, 0x00810080},
627 {0x0000b010, 0x00830082},
628 {0x0000b014, 0x01810180},
629 {0x0000b018, 0x01830182},
630 {0x0000b01c, 0x01850184},
631 {0x0000b020, 0x02810280},
632 {0x0000b024, 0x02830282},
633 {0x0000b028, 0x02850284},
634 {0x0000b02c, 0x02890288},
635 {0x0000b030, 0x028b028a},
636 {0x0000b034, 0x0388028c},
637 {0x0000b038, 0x038a0389},
638 {0x0000b03c, 0x038c038b},
639 {0x0000b040, 0x0390038d},
640 {0x0000b044, 0x03920391},
641 {0x0000b048, 0x03940393},
642 {0x0000b04c, 0x03960395},
643 {0x0000b050, 0x00000000},
644 {0x0000b054, 0x00000000},
645 {0x0000b058, 0x00000000},
646 {0x0000b05c, 0x00000000},
647 {0x0000b060, 0x00000000},
648 {0x0000b064, 0x00000000},
649 {0x0000b068, 0x00000000},
650 {0x0000b06c, 0x00000000},
651 {0x0000b070, 0x00000000},
652 {0x0000b074, 0x00000000},
653 {0x0000b078, 0x00000000},
654 {0x0000b07c, 0x00000000},
655 {0x0000b080, 0x2a2d2f32},
656 {0x0000b084, 0x21232328},
657 {0x0000b088, 0x19191c1e},
658 {0x0000b08c, 0x12141417},
659 {0x0000b090, 0x07070e0e},
660 {0x0000b094, 0x03030305},
661 {0x0000b098, 0x00000003},
662 {0x0000b09c, 0x00000000},
663 {0x0000b0a0, 0x00000000},
664 {0x0000b0a4, 0x00000000},
665 {0x0000b0a8, 0x00000000},
666 {0x0000b0ac, 0x00000000},
667 {0x0000b0b0, 0x00000000},
668 {0x0000b0b4, 0x00000000},
669 {0x0000b0b8, 0x00000000},
670 {0x0000b0bc, 0x00000000},
671 {0x0000b0c0, 0x003f0020},
672 {0x0000b0c4, 0x00400041},
673 {0x0000b0c8, 0x0140005f},
674 {0x0000b0cc, 0x0160015f},
675 {0x0000b0d0, 0x017e017f},
676 {0x0000b0d4, 0x02410242},
677 {0x0000b0d8, 0x025f0240},
678 {0x0000b0dc, 0x027f0260},
679 {0x0000b0e0, 0x0341027e},
680 {0x0000b0e4, 0x035f0340},
681 {0x0000b0e8, 0x037f0360},
682 {0x0000b0ec, 0x04400441},
683 {0x0000b0f0, 0x0460045f},
684 {0x0000b0f4, 0x0541047f},
685 {0x0000b0f8, 0x055f0540},
686 {0x0000b0fc, 0x057f0560},
687 {0x0000b100, 0x06400641},
688 {0x0000b104, 0x0660065f},
689 {0x0000b108, 0x067e067f},
690 {0x0000b10c, 0x07410742},
691 {0x0000b110, 0x075f0740},
692 {0x0000b114, 0x077f0760},
693 {0x0000b118, 0x07800781},
694 {0x0000b11c, 0x07a0079f},
695 {0x0000b120, 0x07c107bf},
696 {0x0000b124, 0x000007c0},
697 {0x0000b128, 0x00000000},
698 {0x0000b12c, 0x00000000},
699 {0x0000b130, 0x00000000},
700 {0x0000b134, 0x00000000},
701 {0x0000b138, 0x00000000},
702 {0x0000b13c, 0x00000000},
703 {0x0000b140, 0x003f0020},
704 {0x0000b144, 0x00400041},
705 {0x0000b148, 0x0140005f},
706 {0x0000b14c, 0x0160015f},
707 {0x0000b150, 0x017e017f},
708 {0x0000b154, 0x02410242},
709 {0x0000b158, 0x025f0240},
710 {0x0000b15c, 0x027f0260},
711 {0x0000b160, 0x0341027e},
712 {0x0000b164, 0x035f0340},
713 {0x0000b168, 0x037f0360},
714 {0x0000b16c, 0x04400441},
715 {0x0000b170, 0x0460045f},
716 {0x0000b174, 0x0541047f},
717 {0x0000b178, 0x055f0540},
718 {0x0000b17c, 0x057f0560},
719 {0x0000b180, 0x06400641},
720 {0x0000b184, 0x0660065f},
721 {0x0000b188, 0x067e067f},
722 {0x0000b18c, 0x07410742},
723 {0x0000b190, 0x075f0740},
724 {0x0000b194, 0x077f0760},
725 {0x0000b198, 0x07800781},
726 {0x0000b19c, 0x07a0079f},
727 {0x0000b1a0, 0x07c107bf},
728 {0x0000b1a4, 0x000007c0},
729 {0x0000b1a8, 0x00000000},
730 {0x0000b1ac, 0x00000000},
731 {0x0000b1b0, 0x00000000},
732 {0x0000b1b4, 0x00000000},
733 {0x0000b1b8, 0x00000000},
734 {0x0000b1bc, 0x00000000},
735 {0x0000b1c0, 0x00000000},
736 {0x0000b1c4, 0x00000000},
737 {0x0000b1c8, 0x00000000},
738 {0x0000b1cc, 0x00000000},
739 {0x0000b1d0, 0x00000000},
740 {0x0000b1d4, 0x00000000},
741 {0x0000b1d8, 0x00000000},
742 {0x0000b1dc, 0x00000000},
743 {0x0000b1e0, 0x00000000},
744 {0x0000b1e4, 0x00000000},
745 {0x0000b1e8, 0x00000000},
746 {0x0000b1ec, 0x00000000},
747 {0x0000b1f0, 0x00000396},
748 {0x0000b1f4, 0x00000396},
749 {0x0000b1f8, 0x00000396},
750 {0x0000b1fc, 0x00000196},
751};
752
753static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
754 /* Addr allmodes */
755 {0x0000a000, 0x00010000},
756 {0x0000a004, 0x00030002},
757 {0x0000a008, 0x00050004},
758 {0x0000a00c, 0x00810080},
759 {0x0000a010, 0x00830082},
760 {0x0000a014, 0x01810180},
761 {0x0000a018, 0x01830182},
762 {0x0000a01c, 0x01850184},
763 {0x0000a020, 0x01890188},
764 {0x0000a024, 0x018b018a},
765 {0x0000a028, 0x018d018c},
766 {0x0000a02c, 0x03820190},
767 {0x0000a030, 0x03840383},
768 {0x0000a034, 0x03880385},
769 {0x0000a038, 0x038a0389},
770 {0x0000a03c, 0x038c038b},
771 {0x0000a040, 0x0390038d},
772 {0x0000a044, 0x03920391},
773 {0x0000a048, 0x03940393},
774 {0x0000a04c, 0x03960395},
775 {0x0000a050, 0x00000000},
776 {0x0000a054, 0x00000000},
777 {0x0000a058, 0x00000000},
778 {0x0000a05c, 0x00000000},
779 {0x0000a060, 0x00000000},
780 {0x0000a064, 0x00000000},
781 {0x0000a068, 0x00000000},
782 {0x0000a06c, 0x00000000},
783 {0x0000a070, 0x00000000},
784 {0x0000a074, 0x00000000},
785 {0x0000a078, 0x00000000},
786 {0x0000a07c, 0x00000000},
787 {0x0000a080, 0x29292929},
788 {0x0000a084, 0x29292929},
789 {0x0000a088, 0x29292929},
790 {0x0000a08c, 0x29292929},
791 {0x0000a090, 0x22292929},
792 {0x0000a094, 0x1d1d2222},
793 {0x0000a098, 0x0c111117},
794 {0x0000a09c, 0x00030303},
795 {0x0000a0a0, 0x00000000},
796 {0x0000a0a4, 0x00000000},
797 {0x0000a0a8, 0x00000000},
798 {0x0000a0ac, 0x00000000},
799 {0x0000a0b0, 0x00000000},
800 {0x0000a0b4, 0x00000000},
801 {0x0000a0b8, 0x00000000},
802 {0x0000a0bc, 0x00000000},
803 {0x0000a0c0, 0x001f0000},
804 {0x0000a0c4, 0x01000101},
805 {0x0000a0c8, 0x011e011f},
806 {0x0000a0cc, 0x011c011d},
807 {0x0000a0d0, 0x02030204},
808 {0x0000a0d4, 0x02010202},
809 {0x0000a0d8, 0x021f0200},
810 {0x0000a0dc, 0x0302021e},
811 {0x0000a0e0, 0x03000301},
812 {0x0000a0e4, 0x031e031f},
813 {0x0000a0e8, 0x0402031d},
814 {0x0000a0ec, 0x04000401},
815 {0x0000a0f0, 0x041e041f},
816 {0x0000a0f4, 0x0502041d},
817 {0x0000a0f8, 0x05000501},
818 {0x0000a0fc, 0x051e051f},
819 {0x0000a100, 0x06010602},
820 {0x0000a104, 0x061f0600},
821 {0x0000a108, 0x061d061e},
822 {0x0000a10c, 0x07020703},
823 {0x0000a110, 0x07000701},
824 {0x0000a114, 0x00000000},
825 {0x0000a118, 0x00000000},
826 {0x0000a11c, 0x00000000},
827 {0x0000a120, 0x00000000},
828 {0x0000a124, 0x00000000},
829 {0x0000a128, 0x00000000},
830 {0x0000a12c, 0x00000000},
831 {0x0000a130, 0x00000000},
832 {0x0000a134, 0x00000000},
833 {0x0000a138, 0x00000000},
834 {0x0000a13c, 0x00000000},
835 {0x0000a140, 0x001f0000},
836 {0x0000a144, 0x01000101},
837 {0x0000a148, 0x011e011f},
838 {0x0000a14c, 0x011c011d},
839 {0x0000a150, 0x02030204},
840 {0x0000a154, 0x02010202},
841 {0x0000a158, 0x021f0200},
842 {0x0000a15c, 0x0302021e},
843 {0x0000a160, 0x03000301},
844 {0x0000a164, 0x031e031f},
845 {0x0000a168, 0x0402031d},
846 {0x0000a16c, 0x04000401},
847 {0x0000a170, 0x041e041f},
848 {0x0000a174, 0x0502041d},
849 {0x0000a178, 0x05000501},
850 {0x0000a17c, 0x051e051f},
851 {0x0000a180, 0x06010602},
852 {0x0000a184, 0x061f0600},
853 {0x0000a188, 0x061d061e},
854 {0x0000a18c, 0x07020703},
855 {0x0000a190, 0x07000701},
856 {0x0000a194, 0x00000000},
857 {0x0000a198, 0x00000000},
858 {0x0000a19c, 0x00000000},
859 {0x0000a1a0, 0x00000000},
860 {0x0000a1a4, 0x00000000},
861 {0x0000a1a8, 0x00000000},
862 {0x0000a1ac, 0x00000000},
863 {0x0000a1b0, 0x00000000},
864 {0x0000a1b4, 0x00000000},
865 {0x0000a1b8, 0x00000000},
866 {0x0000a1bc, 0x00000000},
867 {0x0000a1c0, 0x00000000},
868 {0x0000a1c4, 0x00000000},
869 {0x0000a1c8, 0x00000000},
870 {0x0000a1cc, 0x00000000},
871 {0x0000a1d0, 0x00000000},
872 {0x0000a1d4, 0x00000000},
873 {0x0000a1d8, 0x00000000},
874 {0x0000a1dc, 0x00000000},
875 {0x0000a1e0, 0x00000000},
876 {0x0000a1e4, 0x00000000},
877 {0x0000a1e8, 0x00000000},
878 {0x0000a1ec, 0x00000000},
879 {0x0000a1f0, 0x00000396},
880 {0x0000a1f4, 0x00000396},
881 {0x0000a1f8, 0x00000396},
882 {0x0000a1fc, 0x00000196},
883 {0x0000b000, 0x00010000},
884 {0x0000b004, 0x00030002},
885 {0x0000b008, 0x00050004},
886 {0x0000b00c, 0x00810080},
887 {0x0000b010, 0x00830082},
888 {0x0000b014, 0x01810180},
889 {0x0000b018, 0x01830182},
890 {0x0000b01c, 0x01850184},
891 {0x0000b020, 0x02810280},
892 {0x0000b024, 0x02830282},
893 {0x0000b028, 0x02850284},
894 {0x0000b02c, 0x02890288},
895 {0x0000b030, 0x028b028a},
896 {0x0000b034, 0x0388028c},
897 {0x0000b038, 0x038a0389},
898 {0x0000b03c, 0x038c038b},
899 {0x0000b040, 0x0390038d},
900 {0x0000b044, 0x03920391},
901 {0x0000b048, 0x03940393},
902 {0x0000b04c, 0x03960395},
903 {0x0000b050, 0x00000000},
904 {0x0000b054, 0x00000000},
905 {0x0000b058, 0x00000000},
906 {0x0000b05c, 0x00000000},
907 {0x0000b060, 0x00000000},
908 {0x0000b064, 0x00000000},
909 {0x0000b068, 0x00000000},
910 {0x0000b06c, 0x00000000},
911 {0x0000b070, 0x00000000},
912 {0x0000b074, 0x00000000},
913 {0x0000b078, 0x00000000},
914 {0x0000b07c, 0x00000000},
915 {0x0000b080, 0x2a2d2f32},
916 {0x0000b084, 0x21232328},
917 {0x0000b088, 0x19191c1e},
918 {0x0000b08c, 0x12141417},
919 {0x0000b090, 0x07070e0e},
920 {0x0000b094, 0x03030305},
921 {0x0000b098, 0x00000003},
922 {0x0000b09c, 0x00000000},
923 {0x0000b0a0, 0x00000000},
924 {0x0000b0a4, 0x00000000},
925 {0x0000b0a8, 0x00000000},
926 {0x0000b0ac, 0x00000000},
927 {0x0000b0b0, 0x00000000},
928 {0x0000b0b4, 0x00000000},
929 {0x0000b0b8, 0x00000000},
930 {0x0000b0bc, 0x00000000},
931 {0x0000b0c0, 0x003f0020},
932 {0x0000b0c4, 0x00400041},
933 {0x0000b0c8, 0x0140005f},
934 {0x0000b0cc, 0x0160015f},
935 {0x0000b0d0, 0x017e017f},
936 {0x0000b0d4, 0x02410242},
937 {0x0000b0d8, 0x025f0240},
938 {0x0000b0dc, 0x027f0260},
939 {0x0000b0e0, 0x0341027e},
940 {0x0000b0e4, 0x035f0340},
941 {0x0000b0e8, 0x037f0360},
942 {0x0000b0ec, 0x04400441},
943 {0x0000b0f0, 0x0460045f},
944 {0x0000b0f4, 0x0541047f},
945 {0x0000b0f8, 0x055f0540},
946 {0x0000b0fc, 0x057f0560},
947 {0x0000b100, 0x06400641},
948 {0x0000b104, 0x0660065f},
949 {0x0000b108, 0x067e067f},
950 {0x0000b10c, 0x07410742},
951 {0x0000b110, 0x075f0740},
952 {0x0000b114, 0x077f0760},
953 {0x0000b118, 0x07800781},
954 {0x0000b11c, 0x07a0079f},
955 {0x0000b120, 0x07c107bf},
956 {0x0000b124, 0x000007c0},
957 {0x0000b128, 0x00000000},
958 {0x0000b12c, 0x00000000},
959 {0x0000b130, 0x00000000},
960 {0x0000b134, 0x00000000},
961 {0x0000b138, 0x00000000},
962 {0x0000b13c, 0x00000000},
963 {0x0000b140, 0x003f0020},
964 {0x0000b144, 0x00400041},
965 {0x0000b148, 0x0140005f},
966 {0x0000b14c, 0x0160015f},
967 {0x0000b150, 0x017e017f},
968 {0x0000b154, 0x02410242},
969 {0x0000b158, 0x025f0240},
970 {0x0000b15c, 0x027f0260},
971 {0x0000b160, 0x0341027e},
972 {0x0000b164, 0x035f0340},
973 {0x0000b168, 0x037f0360},
974 {0x0000b16c, 0x04400441},
975 {0x0000b170, 0x0460045f},
976 {0x0000b174, 0x0541047f},
977 {0x0000b178, 0x055f0540},
978 {0x0000b17c, 0x057f0560},
979 {0x0000b180, 0x06400641},
980 {0x0000b184, 0x0660065f},
981 {0x0000b188, 0x067e067f},
982 {0x0000b18c, 0x07410742},
983 {0x0000b190, 0x075f0740},
984 {0x0000b194, 0x077f0760},
985 {0x0000b198, 0x07800781},
986 {0x0000b19c, 0x07a0079f},
987 {0x0000b1a0, 0x07c107bf},
988 {0x0000b1a4, 0x000007c0},
989 {0x0000b1a8, 0x00000000},
990 {0x0000b1ac, 0x00000000},
991 {0x0000b1b0, 0x00000000},
992 {0x0000b1b4, 0x00000000},
993 {0x0000b1b8, 0x00000000},
994 {0x0000b1bc, 0x00000000},
995 {0x0000b1c0, 0x00000000},
996 {0x0000b1c4, 0x00000000},
997 {0x0000b1c8, 0x00000000},
998 {0x0000b1cc, 0x00000000},
999 {0x0000b1d0, 0x00000000},
1000 {0x0000b1d4, 0x00000000},
1001 {0x0000b1d8, 0x00000000},
1002 {0x0000b1dc, 0x00000000},
1003 {0x0000b1e0, 0x00000000},
1004 {0x0000b1e4, 0x00000000},
1005 {0x0000b1e8, 0x00000000},
1006 {0x0000b1ec, 0x00000000},
1007 {0x0000b1f0, 0x00000396},
1008 {0x0000b1f4, 0x00000396},
1009 {0x0000b1f8, 0x00000396},
1010 {0x0000b1fc, 0x00000196},
1011};
1012
1013static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
1014 /* Addr allmodes */
1015 {0x00009fd0, 0x0a2d6b93},
1016};
1017
1018static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
1019 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1020 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
1021 {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
1022 {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
1023 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
1024 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
1025 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
1026};
1027
1028static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
1029 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1030 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1031};
1032
1033static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
1034 /* Addr allmodes */
1035 {0x0000a000, 0x00010000},
1036 {0x0000a004, 0x00030002},
1037 {0x0000a008, 0x00050004},
1038 {0x0000a00c, 0x00810080},
1039 {0x0000a010, 0x00830082},
1040 {0x0000a014, 0x01810180},
1041 {0x0000a018, 0x01830182},
1042 {0x0000a01c, 0x01850184},
1043 {0x0000a020, 0x01890188},
1044 {0x0000a024, 0x018b018a},
1045 {0x0000a028, 0x018d018c},
1046 {0x0000a02c, 0x03820190},
1047 {0x0000a030, 0x03840383},
1048 {0x0000a034, 0x03880385},
1049 {0x0000a038, 0x038a0389},
1050 {0x0000a03c, 0x038c038b},
1051 {0x0000a040, 0x0390038d},
1052 {0x0000a044, 0x03920391},
1053 {0x0000a048, 0x03940393},
1054 {0x0000a04c, 0x03960395},
1055 {0x0000a050, 0x00000000},
1056 {0x0000a054, 0x00000000},
1057 {0x0000a058, 0x00000000},
1058 {0x0000a05c, 0x00000000},
1059 {0x0000a060, 0x00000000},
1060 {0x0000a064, 0x00000000},
1061 {0x0000a068, 0x00000000},
1062 {0x0000a06c, 0x00000000},
1063 {0x0000a070, 0x00000000},
1064 {0x0000a074, 0x00000000},
1065 {0x0000a078, 0x00000000},
1066 {0x0000a07c, 0x00000000},
1067 {0x0000a080, 0x29292929},
1068 {0x0000a084, 0x29292929},
1069 {0x0000a088, 0x29292929},
1070 {0x0000a08c, 0x29292929},
1071 {0x0000a090, 0x22292929},
1072 {0x0000a094, 0x1d1d2222},
1073 {0x0000a098, 0x0c111117},
1074 {0x0000a09c, 0x00030303},
1075 {0x0000a0a0, 0x00000000},
1076 {0x0000a0a4, 0x00000000},
1077 {0x0000a0a8, 0x00000000},
1078 {0x0000a0ac, 0x00000000},
1079 {0x0000a0b0, 0x00000000},
1080 {0x0000a0b4, 0x00000000},
1081 {0x0000a0b8, 0x00000000},
1082 {0x0000a0bc, 0x00000000},
1083 {0x0000a0c0, 0x001f0000},
1084 {0x0000a0c4, 0x01000101},
1085 {0x0000a0c8, 0x011e011f},
1086 {0x0000a0cc, 0x011c011d},
1087 {0x0000a0d0, 0x02030204},
1088 {0x0000a0d4, 0x02010202},
1089 {0x0000a0d8, 0x021f0200},
1090 {0x0000a0dc, 0x0302021e},
1091 {0x0000a0e0, 0x03000301},
1092 {0x0000a0e4, 0x031e031f},
1093 {0x0000a0e8, 0x0402031d},
1094 {0x0000a0ec, 0x04000401},
1095 {0x0000a0f0, 0x041e041f},
1096 {0x0000a0f4, 0x0502041d},
1097 {0x0000a0f8, 0x05000501},
1098 {0x0000a0fc, 0x051e051f},
1099 {0x0000a100, 0x06010602},
1100 {0x0000a104, 0x061f0600},
1101 {0x0000a108, 0x061d061e},
1102 {0x0000a10c, 0x07020703},
1103 {0x0000a110, 0x07000701},
1104 {0x0000a114, 0x00000000},
1105 {0x0000a118, 0x00000000},
1106 {0x0000a11c, 0x00000000},
1107 {0x0000a120, 0x00000000},
1108 {0x0000a124, 0x00000000},
1109 {0x0000a128, 0x00000000},
1110 {0x0000a12c, 0x00000000},
1111 {0x0000a130, 0x00000000},
1112 {0x0000a134, 0x00000000},
1113 {0x0000a138, 0x00000000},
1114 {0x0000a13c, 0x00000000},
1115 {0x0000a140, 0x001f0000},
1116 {0x0000a144, 0x01000101},
1117 {0x0000a148, 0x011e011f},
1118 {0x0000a14c, 0x011c011d},
1119 {0x0000a150, 0x02030204},
1120 {0x0000a154, 0x02010202},
1121 {0x0000a158, 0x021f0200},
1122 {0x0000a15c, 0x0302021e},
1123 {0x0000a160, 0x03000301},
1124 {0x0000a164, 0x031e031f},
1125 {0x0000a168, 0x0402031d},
1126 {0x0000a16c, 0x04000401},
1127 {0x0000a170, 0x041e041f},
1128 {0x0000a174, 0x0502041d},
1129 {0x0000a178, 0x05000501},
1130 {0x0000a17c, 0x051e051f},
1131 {0x0000a180, 0x06010602},
1132 {0x0000a184, 0x061f0600},
1133 {0x0000a188, 0x061d061e},
1134 {0x0000a18c, 0x07020703},
1135 {0x0000a190, 0x07000701},
1136 {0x0000a194, 0x00000000},
1137 {0x0000a198, 0x00000000},
1138 {0x0000a19c, 0x00000000},
1139 {0x0000a1a0, 0x00000000},
1140 {0x0000a1a4, 0x00000000},
1141 {0x0000a1a8, 0x00000000},
1142 {0x0000a1ac, 0x00000000},
1143 {0x0000a1b0, 0x00000000},
1144 {0x0000a1b4, 0x00000000},
1145 {0x0000a1b8, 0x00000000},
1146 {0x0000a1bc, 0x00000000},
1147 {0x0000a1c0, 0x00000000},
1148 {0x0000a1c4, 0x00000000},
1149 {0x0000a1c8, 0x00000000},
1150 {0x0000a1cc, 0x00000000},
1151 {0x0000a1d0, 0x00000000},
1152 {0x0000a1d4, 0x00000000},
1153 {0x0000a1d8, 0x00000000},
1154 {0x0000a1dc, 0x00000000},
1155 {0x0000a1e0, 0x00000000},
1156 {0x0000a1e4, 0x00000000},
1157 {0x0000a1e8, 0x00000000},
1158 {0x0000a1ec, 0x00000000},
1159 {0x0000a1f0, 0x00000396},
1160 {0x0000a1f4, 0x00000396},
1161 {0x0000a1f8, 0x00000396},
1162 {0x0000a1fc, 0x00000196},
1163 {0x0000b000, 0x00010000},
1164 {0x0000b004, 0x00030002},
1165 {0x0000b008, 0x00050004},
1166 {0x0000b00c, 0x00810080},
1167 {0x0000b010, 0x00830082},
1168 {0x0000b014, 0x01810180},
1169 {0x0000b018, 0x01830182},
1170 {0x0000b01c, 0x01850184},
1171 {0x0000b020, 0x02810280},
1172 {0x0000b024, 0x02830282},
1173 {0x0000b028, 0x02850284},
1174 {0x0000b02c, 0x02890288},
1175 {0x0000b030, 0x028b028a},
1176 {0x0000b034, 0x0388028c},
1177 {0x0000b038, 0x038a0389},
1178 {0x0000b03c, 0x038c038b},
1179 {0x0000b040, 0x0390038d},
1180 {0x0000b044, 0x03920391},
1181 {0x0000b048, 0x03940393},
1182 {0x0000b04c, 0x03960395},
1183 {0x0000b050, 0x00000000},
1184 {0x0000b054, 0x00000000},
1185 {0x0000b058, 0x00000000},
1186 {0x0000b05c, 0x00000000},
1187 {0x0000b060, 0x00000000},
1188 {0x0000b064, 0x00000000},
1189 {0x0000b068, 0x00000000},
1190 {0x0000b06c, 0x00000000},
1191 {0x0000b070, 0x00000000},
1192 {0x0000b074, 0x00000000},
1193 {0x0000b078, 0x00000000},
1194 {0x0000b07c, 0x00000000},
1195 {0x0000b080, 0x32323232},
1196 {0x0000b084, 0x2f2f3232},
1197 {0x0000b088, 0x23282a2d},
1198 {0x0000b08c, 0x1c1e2123},
1199 {0x0000b090, 0x14171919},
1200 {0x0000b094, 0x0e0e1214},
1201 {0x0000b098, 0x03050707},
1202 {0x0000b09c, 0x00030303},
1203 {0x0000b0a0, 0x00000000},
1204 {0x0000b0a4, 0x00000000},
1205 {0x0000b0a8, 0x00000000},
1206 {0x0000b0ac, 0x00000000},
1207 {0x0000b0b0, 0x00000000},
1208 {0x0000b0b4, 0x00000000},
1209 {0x0000b0b8, 0x00000000},
1210 {0x0000b0bc, 0x00000000},
1211 {0x0000b0c0, 0x003f0020},
1212 {0x0000b0c4, 0x00400041},
1213 {0x0000b0c8, 0x0140005f},
1214 {0x0000b0cc, 0x0160015f},
1215 {0x0000b0d0, 0x017e017f},
1216 {0x0000b0d4, 0x02410242},
1217 {0x0000b0d8, 0x025f0240},
1218 {0x0000b0dc, 0x027f0260},
1219 {0x0000b0e0, 0x0341027e},
1220 {0x0000b0e4, 0x035f0340},
1221 {0x0000b0e8, 0x037f0360},
1222 {0x0000b0ec, 0x04400441},
1223 {0x0000b0f0, 0x0460045f},
1224 {0x0000b0f4, 0x0541047f},
1225 {0x0000b0f8, 0x055f0540},
1226 {0x0000b0fc, 0x057f0560},
1227 {0x0000b100, 0x06400641},
1228 {0x0000b104, 0x0660065f},
1229 {0x0000b108, 0x067e067f},
1230 {0x0000b10c, 0x07410742},
1231 {0x0000b110, 0x075f0740},
1232 {0x0000b114, 0x077f0760},
1233 {0x0000b118, 0x07800781},
1234 {0x0000b11c, 0x07a0079f},
1235 {0x0000b120, 0x07c107bf},
1236 {0x0000b124, 0x000007c0},
1237 {0x0000b128, 0x00000000},
1238 {0x0000b12c, 0x00000000},
1239 {0x0000b130, 0x00000000},
1240 {0x0000b134, 0x00000000},
1241 {0x0000b138, 0x00000000},
1242 {0x0000b13c, 0x00000000},
1243 {0x0000b140, 0x003f0020},
1244 {0x0000b144, 0x00400041},
1245 {0x0000b148, 0x0140005f},
1246 {0x0000b14c, 0x0160015f},
1247 {0x0000b150, 0x017e017f},
1248 {0x0000b154, 0x02410242},
1249 {0x0000b158, 0x025f0240},
1250 {0x0000b15c, 0x027f0260},
1251 {0x0000b160, 0x0341027e},
1252 {0x0000b164, 0x035f0340},
1253 {0x0000b168, 0x037f0360},
1254 {0x0000b16c, 0x04400441},
1255 {0x0000b170, 0x0460045f},
1256 {0x0000b174, 0x0541047f},
1257 {0x0000b178, 0x055f0540},
1258 {0x0000b17c, 0x057f0560},
1259 {0x0000b180, 0x06400641},
1260 {0x0000b184, 0x0660065f},
1261 {0x0000b188, 0x067e067f},
1262 {0x0000b18c, 0x07410742},
1263 {0x0000b190, 0x075f0740},
1264 {0x0000b194, 0x077f0760},
1265 {0x0000b198, 0x07800781},
1266 {0x0000b19c, 0x07a0079f},
1267 {0x0000b1a0, 0x07c107bf},
1268 {0x0000b1a4, 0x000007c0},
1269 {0x0000b1a8, 0x00000000},
1270 {0x0000b1ac, 0x00000000},
1271 {0x0000b1b0, 0x00000000},
1272 {0x0000b1b4, 0x00000000},
1273 {0x0000b1b8, 0x00000000},
1274 {0x0000b1bc, 0x00000000},
1275 {0x0000b1c0, 0x00000000},
1276 {0x0000b1c4, 0x00000000},
1277 {0x0000b1c8, 0x00000000},
1278 {0x0000b1cc, 0x00000000},
1279 {0x0000b1d0, 0x00000000},
1280 {0x0000b1d4, 0x00000000},
1281 {0x0000b1d8, 0x00000000},
1282 {0x0000b1dc, 0x00000000},
1283 {0x0000b1e0, 0x00000000},
1284 {0x0000b1e4, 0x00000000},
1285 {0x0000b1e8, 0x00000000},
1286 {0x0000b1ec, 0x00000000},
1287 {0x0000b1f0, 0x00000396},
1288 {0x0000b1f4, 0x00000396},
1289 {0x0000b1f8, 0x00000396},
1290 {0x0000b1fc, 0x00000196},
1291};
1292
1293static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
1294 /* Addr allmodes */
1295 {0x0000a000, 0x00010000},
1296 {0x0000a004, 0x00030002},
1297 {0x0000a008, 0x00050004},
1298 {0x0000a00c, 0x00810080},
1299 {0x0000a010, 0x00830082},
1300 {0x0000a014, 0x01810180},
1301 {0x0000a018, 0x01830182},
1302 {0x0000a01c, 0x01850184},
1303 {0x0000a020, 0x01890188},
1304 {0x0000a024, 0x018b018a},
1305 {0x0000a028, 0x018d018c},
1306 {0x0000a02c, 0x03820190},
1307 {0x0000a030, 0x03840383},
1308 {0x0000a034, 0x03880385},
1309 {0x0000a038, 0x038a0389},
1310 {0x0000a03c, 0x038c038b},
1311 {0x0000a040, 0x0390038d},
1312 {0x0000a044, 0x03920391},
1313 {0x0000a048, 0x03940393},
1314 {0x0000a04c, 0x03960395},
1315 {0x0000a050, 0x00000000},
1316 {0x0000a054, 0x00000000},
1317 {0x0000a058, 0x00000000},
1318 {0x0000a05c, 0x00000000},
1319 {0x0000a060, 0x00000000},
1320 {0x0000a064, 0x00000000},
1321 {0x0000a068, 0x00000000},
1322 {0x0000a06c, 0x00000000},
1323 {0x0000a070, 0x00000000},
1324 {0x0000a074, 0x00000000},
1325 {0x0000a078, 0x00000000},
1326 {0x0000a07c, 0x00000000},
1327 {0x0000a080, 0x29292929},
1328 {0x0000a084, 0x29292929},
1329 {0x0000a088, 0x29292929},
1330 {0x0000a08c, 0x29292929},
1331 {0x0000a090, 0x22292929},
1332 {0x0000a094, 0x1d1d2222},
1333 {0x0000a098, 0x0c111117},
1334 {0x0000a09c, 0x00030303},
1335 {0x0000a0a0, 0x00000000},
1336 {0x0000a0a4, 0x00000000},
1337 {0x0000a0a8, 0x00000000},
1338 {0x0000a0ac, 0x00000000},
1339 {0x0000a0b0, 0x00000000},
1340 {0x0000a0b4, 0x00000000},
1341 {0x0000a0b8, 0x00000000},
1342 {0x0000a0bc, 0x00000000},
1343 {0x0000a0c0, 0x001f0000},
1344 {0x0000a0c4, 0x01000101},
1345 {0x0000a0c8, 0x011e011f},
1346 {0x0000a0cc, 0x011c011d},
1347 {0x0000a0d0, 0x02030204},
1348 {0x0000a0d4, 0x02010202},
1349 {0x0000a0d8, 0x021f0200},
1350 {0x0000a0dc, 0x0302021e},
1351 {0x0000a0e0, 0x03000301},
1352 {0x0000a0e4, 0x031e031f},
1353 {0x0000a0e8, 0x0402031d},
1354 {0x0000a0ec, 0x04000401},
1355 {0x0000a0f0, 0x041e041f},
1356 {0x0000a0f4, 0x0502041d},
1357 {0x0000a0f8, 0x05000501},
1358 {0x0000a0fc, 0x051e051f},
1359 {0x0000a100, 0x06010602},
1360 {0x0000a104, 0x061f0600},
1361 {0x0000a108, 0x061d061e},
1362 {0x0000a10c, 0x07020703},
1363 {0x0000a110, 0x07000701},
1364 {0x0000a114, 0x00000000},
1365 {0x0000a118, 0x00000000},
1366 {0x0000a11c, 0x00000000},
1367 {0x0000a120, 0x00000000},
1368 {0x0000a124, 0x00000000},
1369 {0x0000a128, 0x00000000},
1370 {0x0000a12c, 0x00000000},
1371 {0x0000a130, 0x00000000},
1372 {0x0000a134, 0x00000000},
1373 {0x0000a138, 0x00000000},
1374 {0x0000a13c, 0x00000000},
1375 {0x0000a140, 0x001f0000},
1376 {0x0000a144, 0x01000101},
1377 {0x0000a148, 0x011e011f},
1378 {0x0000a14c, 0x011c011d},
1379 {0x0000a150, 0x02030204},
1380 {0x0000a154, 0x02010202},
1381 {0x0000a158, 0x021f0200},
1382 {0x0000a15c, 0x0302021e},
1383 {0x0000a160, 0x03000301},
1384 {0x0000a164, 0x031e031f},
1385 {0x0000a168, 0x0402031d},
1386 {0x0000a16c, 0x04000401},
1387 {0x0000a170, 0x041e041f},
1388 {0x0000a174, 0x0502041d},
1389 {0x0000a178, 0x05000501},
1390 {0x0000a17c, 0x051e051f},
1391 {0x0000a180, 0x06010602},
1392 {0x0000a184, 0x061f0600},
1393 {0x0000a188, 0x061d061e},
1394 {0x0000a18c, 0x07020703},
1395 {0x0000a190, 0x07000701},
1396 {0x0000a194, 0x00000000},
1397 {0x0000a198, 0x00000000},
1398 {0x0000a19c, 0x00000000},
1399 {0x0000a1a0, 0x00000000},
1400 {0x0000a1a4, 0x00000000},
1401 {0x0000a1a8, 0x00000000},
1402 {0x0000a1ac, 0x00000000},
1403 {0x0000a1b0, 0x00000000},
1404 {0x0000a1b4, 0x00000000},
1405 {0x0000a1b8, 0x00000000},
1406 {0x0000a1bc, 0x00000000},
1407 {0x0000a1c0, 0x00000000},
1408 {0x0000a1c4, 0x00000000},
1409 {0x0000a1c8, 0x00000000},
1410 {0x0000a1cc, 0x00000000},
1411 {0x0000a1d0, 0x00000000},
1412 {0x0000a1d4, 0x00000000},
1413 {0x0000a1d8, 0x00000000},
1414 {0x0000a1dc, 0x00000000},
1415 {0x0000a1e0, 0x00000000},
1416 {0x0000a1e4, 0x00000000},
1417 {0x0000a1e8, 0x00000000},
1418 {0x0000a1ec, 0x00000000},
1419 {0x0000a1f0, 0x00000396},
1420 {0x0000a1f4, 0x00000396},
1421 {0x0000a1f8, 0x00000396},
1422 {0x0000a1fc, 0x00000196},
1423 {0x0000b000, 0x00010000},
1424 {0x0000b004, 0x00030002},
1425 {0x0000b008, 0x00050004},
1426 {0x0000b00c, 0x00810080},
1427 {0x0000b010, 0x00830082},
1428 {0x0000b014, 0x01810180},
1429 {0x0000b018, 0x01830182},
1430 {0x0000b01c, 0x01850184},
1431 {0x0000b020, 0x02810280},
1432 {0x0000b024, 0x02830282},
1433 {0x0000b028, 0x02850284},
1434 {0x0000b02c, 0x02890288},
1435 {0x0000b030, 0x028b028a},
1436 {0x0000b034, 0x0388028c},
1437 {0x0000b038, 0x038a0389},
1438 {0x0000b03c, 0x038c038b},
1439 {0x0000b040, 0x0390038d},
1440 {0x0000b044, 0x03920391},
1441 {0x0000b048, 0x03940393},
1442 {0x0000b04c, 0x03960395},
1443 {0x0000b050, 0x00000000},
1444 {0x0000b054, 0x00000000},
1445 {0x0000b058, 0x00000000},
1446 {0x0000b05c, 0x00000000},
1447 {0x0000b060, 0x00000000},
1448 {0x0000b064, 0x00000000},
1449 {0x0000b068, 0x00000000},
1450 {0x0000b06c, 0x00000000},
1451 {0x0000b070, 0x00000000},
1452 {0x0000b074, 0x00000000},
1453 {0x0000b078, 0x00000000},
1454 {0x0000b07c, 0x00000000},
1455 {0x0000b080, 0x2a2d2f32},
1456 {0x0000b084, 0x21232328},
1457 {0x0000b088, 0x19191c1e},
1458 {0x0000b08c, 0x12141417},
1459 {0x0000b090, 0x07070e0e},
1460 {0x0000b094, 0x03030305},
1461 {0x0000b098, 0x00000003},
1462 {0x0000b09c, 0x00000000},
1463 {0x0000b0a0, 0x00000000},
1464 {0x0000b0a4, 0x00000000},
1465 {0x0000b0a8, 0x00000000},
1466 {0x0000b0ac, 0x00000000},
1467 {0x0000b0b0, 0x00000000},
1468 {0x0000b0b4, 0x00000000},
1469 {0x0000b0b8, 0x00000000},
1470 {0x0000b0bc, 0x00000000},
1471 {0x0000b0c0, 0x003f0020},
1472 {0x0000b0c4, 0x00400041},
1473 {0x0000b0c8, 0x0140005f},
1474 {0x0000b0cc, 0x0160015f},
1475 {0x0000b0d0, 0x017e017f},
1476 {0x0000b0d4, 0x02410242},
1477 {0x0000b0d8, 0x025f0240},
1478 {0x0000b0dc, 0x027f0260},
1479 {0x0000b0e0, 0x0341027e},
1480 {0x0000b0e4, 0x035f0340},
1481 {0x0000b0e8, 0x037f0360},
1482 {0x0000b0ec, 0x04400441},
1483 {0x0000b0f0, 0x0460045f},
1484 {0x0000b0f4, 0x0541047f},
1485 {0x0000b0f8, 0x055f0540},
1486 {0x0000b0fc, 0x057f0560},
1487 {0x0000b100, 0x06400641},
1488 {0x0000b104, 0x0660065f},
1489 {0x0000b108, 0x067e067f},
1490 {0x0000b10c, 0x07410742},
1491 {0x0000b110, 0x075f0740},
1492 {0x0000b114, 0x077f0760},
1493 {0x0000b118, 0x07800781},
1494 {0x0000b11c, 0x07a0079f},
1495 {0x0000b120, 0x07c107bf},
1496 {0x0000b124, 0x000007c0},
1497 {0x0000b128, 0x00000000},
1498 {0x0000b12c, 0x00000000},
1499 {0x0000b130, 0x00000000},
1500 {0x0000b134, 0x00000000},
1501 {0x0000b138, 0x00000000},
1502 {0x0000b13c, 0x00000000},
1503 {0x0000b140, 0x003f0020},
1504 {0x0000b144, 0x00400041},
1505 {0x0000b148, 0x0140005f},
1506 {0x0000b14c, 0x0160015f},
1507 {0x0000b150, 0x017e017f},
1508 {0x0000b154, 0x02410242},
1509 {0x0000b158, 0x025f0240},
1510 {0x0000b15c, 0x027f0260},
1511 {0x0000b160, 0x0341027e},
1512 {0x0000b164, 0x035f0340},
1513 {0x0000b168, 0x037f0360},
1514 {0x0000b16c, 0x04400441},
1515 {0x0000b170, 0x0460045f},
1516 {0x0000b174, 0x0541047f},
1517 {0x0000b178, 0x055f0540},
1518 {0x0000b17c, 0x057f0560},
1519 {0x0000b180, 0x06400641},
1520 {0x0000b184, 0x0660065f},
1521 {0x0000b188, 0x067e067f},
1522 {0x0000b18c, 0x07410742},
1523 {0x0000b190, 0x075f0740},
1524 {0x0000b194, 0x077f0760},
1525 {0x0000b198, 0x07800781},
1526 {0x0000b19c, 0x07a0079f},
1527 {0x0000b1a0, 0x07c107bf},
1528 {0x0000b1a4, 0x000007c0},
1529 {0x0000b1a8, 0x00000000},
1530 {0x0000b1ac, 0x00000000},
1531 {0x0000b1b0, 0x00000000},
1532 {0x0000b1b4, 0x00000000},
1533 {0x0000b1b8, 0x00000000},
1534 {0x0000b1bc, 0x00000000},
1535 {0x0000b1c0, 0x00000000},
1536 {0x0000b1c4, 0x00000000},
1537 {0x0000b1c8, 0x00000000},
1538 {0x0000b1cc, 0x00000000},
1539 {0x0000b1d0, 0x00000000},
1540 {0x0000b1d4, 0x00000000},
1541 {0x0000b1d8, 0x00000000},
1542 {0x0000b1dc, 0x00000000},
1543 {0x0000b1e0, 0x00000000},
1544 {0x0000b1e4, 0x00000000},
1545 {0x0000b1e8, 0x00000000},
1546 {0x0000b1ec, 0x00000000},
1547 {0x0000b1f0, 0x00000396},
1548 {0x0000b1f4, 0x00000396},
1549 {0x0000b1f8, 0x00000396},
1550 {0x0000b1fc, 0x00000196},
1551};
1552
1553static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1555 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1556 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1557 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1558 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1559 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1560 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1561 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1562 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1563 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1564 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1565 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1566 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1567 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1568 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1569 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1570 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1571 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1572 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1573 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1574 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1575 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1576 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1577 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1578 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1579 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1580 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1581 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1582 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1583 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1584 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1585 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1586 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1587 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1588 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1589 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1590 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1591 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1592 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1593 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1594 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1595 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1596 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1597 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1598 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1599 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1600 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1601 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1602 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1603 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1604 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1605 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1606 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1607 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1608 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1609 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1610 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1611 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1612 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1613 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1614 {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1615 {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
1616 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1617 {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1618 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
1619 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1620};
1621
1622static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
1623 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1624 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1625 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1626 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1627 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1628 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1629 {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
1630 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1631 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1632 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1633 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1634 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1635 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1636 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
1637 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
1638 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1639 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
1640 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
1641 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
1642 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
1643 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
1644 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
1645 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
1646 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
1647 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1648 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1649 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
1650 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
1651 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
1652 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1653 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1654 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
1655 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
1656 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
1657 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
1658 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
1659 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1660 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1661 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1662 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1663 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1664 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1665 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1666 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1667 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1668 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1669 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1670 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1671 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1672 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1673 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1674 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1675 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1676 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1677 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1678 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1679 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1680 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1681 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1682 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1683 {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1684 {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
1685 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1686 {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1687 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
1688 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1689};
1690
1691static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
1692 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1693 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1694 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1695 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1696 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1697 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1698 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
1699 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1700 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1701 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1702 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1703 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1704 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1705 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
1706 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
1707 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1708 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
1709 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
1710 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
1711 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
1712 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
1713 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
1714 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
1715 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
1716 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
1717 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
1718 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
1719 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
1720 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
1721 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
1722 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
1723 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
1724 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
1725 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
1726 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
1727 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
1728 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1729 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1730 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1731 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1732 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1733 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1734 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1735 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1736 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1737 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1738 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1739 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1740 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1741 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1742 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1743 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1744 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1745 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1746 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1747 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1748 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1749 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1750 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1751 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1752};
1753
1754static const u32 ar9462_2p1_modes_fast_clock[][3] = {
1755 /* Addr 5G_HT20 5G_HT40 */
1756 {0x00001030, 0x00000268, 0x000004d0},
1757 {0x00001070, 0x0000018c, 0x00000318},
1758 {0x000010b0, 0x00000fd0, 0x00001fa0},
1759 {0x00008014, 0x044c044c, 0x08980898},
1760 {0x0000801c, 0x148ec02b, 0x148ec057},
1761 {0x00008318, 0x000044c0, 0x00008980},
1762 {0x00009e00, 0x0372131c, 0x0372131c},
1763 {0x0000a230, 0x0000400b, 0x00004016},
1764 {0x0000a254, 0x00000898, 0x00001130},
1765};
1766
1767static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
1768 /* Addr allmodes */
1769 {0x0000a398, 0x00000000},
1770 {0x0000a39c, 0x6f7f0301},
1771 {0x0000a3a0, 0xca9228ee},
1772};
1773
1774#endif /* INITVALS_9462_2P1_H */ 291#endif /* INITVALS_9462_2P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index 7c1845221e1c..ce83ce47a1ca 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -20,17 +20,11 @@
20 20
21/* AR9485 1.1 */ 21/* AR9485 1.1 */
22 22
23static const u32 ar9485_1_1_mac_postamble[][5] = { 23#define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
24 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 24
25 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 25#define ar9485_1_1_mac_postamble ar9331_1p1_mac_postamble
26 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, 26
27 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, 27#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
28 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
29 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
30 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
31 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
32 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
33};
34 28
35static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { 29static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
36 /* Addr allmodes */ 30 /* Addr allmodes */
@@ -546,100 +540,6 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
546 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, 540 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
547}; 541};
548 542
549static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
550 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
551 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
552 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
553 {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
554 {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
555 {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
556 {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
557 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
558 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
559 {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
560 {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
561 {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
562 {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
563 {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
564 {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
565 {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
566 {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
567 {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
568 {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
569 {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
570 {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
571 {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
572 {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
573 {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
574 {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
575 {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
576 {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
577 {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
578 {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
579 {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
580 {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
581 {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
582 {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
583 {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
584 {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
585 {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
586 {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
587 {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
588 {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
589 {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
590 {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
591 {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
592 {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
593 {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
594 {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
595 {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
596 {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
597 {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
598 {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
599 {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
600 {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
601 {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
602 {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
603 {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
604 {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
605 {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
606 {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
607 {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
608 {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
609 {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
610 {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
611 {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
612 {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
613 {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
614 {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
615 {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
616 {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
617 {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
618 {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
619 {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
620 {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
621 {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
622 {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
623 {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
624 {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
625 {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
626 {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
627 {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
628 {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
629 {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
630 {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
631 {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
632 {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
633 {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
634 {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
635 {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
636 {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
637 {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
638 {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
639 {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
640 {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
641};
642
643static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = { 543static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = {
644 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 544 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
645 {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, 545 {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
@@ -1323,13 +1223,6 @@ static const u32 ar9485_1_1_mac_core[][2] = {
1323 {0x000083d0, 0x000301ff}, 1223 {0x000083d0, 0x000301ff},
1324}; 1224};
1325 1225
1326static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = {
1327 /* Addr allmodes */
1328 {0x0000a398, 0x00000000},
1329 {0x0000a39c, 0x6f7f0301},
1330 {0x0000a3a0, 0xca9228ee},
1331};
1332
1333static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { 1226static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
1334 /* Addr allmodes */ 1227 /* Addr allmodes */
1335 {0x00018c00, 0x18013e5e}, 1228 {0x00018c00, 0x18013e5e},
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
new file mode 100644
index 000000000000..3c9113d9b1bc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -0,0 +1,718 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef INITVALS_953X_H
19#define INITVALS_953X_H
20
21#define qca953x_1p0_mac_postamble ar9300_2p2_mac_postamble
22
23#define qca953x_1p0_soc_postamble ar9300_2p2_soc_postamble
24
25#define qca953x_1p0_common_rx_gain_table ar9300Common_rx_gain_table_2p2
26
27#define qca953x_1p0_common_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
28
29#define qca953x_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
30
31static const u32 qca953x_1p0_mac_core[][2] = {
32 /* Addr allmodes */
33 {0x00000008, 0x00000000},
34 {0x00000030, 0x00020085},
35 {0x00000034, 0x00000005},
36 {0x00000040, 0x00000000},
37 {0x00000044, 0x00000000},
38 {0x00000048, 0x00000008},
39 {0x0000004c, 0x00000010},
40 {0x00000050, 0x00000000},
41 {0x00001040, 0x002ffc0f},
42 {0x00001044, 0x002ffc0f},
43 {0x00001048, 0x002ffc0f},
44 {0x0000104c, 0x002ffc0f},
45 {0x00001050, 0x002ffc0f},
46 {0x00001054, 0x002ffc0f},
47 {0x00001058, 0x002ffc0f},
48 {0x0000105c, 0x002ffc0f},
49 {0x00001060, 0x002ffc0f},
50 {0x00001064, 0x002ffc0f},
51 {0x000010f0, 0x00000100},
52 {0x00001270, 0x00000000},
53 {0x000012b0, 0x00000000},
54 {0x000012f0, 0x00000000},
55 {0x0000143c, 0x00000000},
56 {0x0000147c, 0x00000000},
57 {0x00008000, 0x00000000},
58 {0x00008004, 0x00000000},
59 {0x00008008, 0x00000000},
60 {0x0000800c, 0x00000000},
61 {0x00008018, 0x00000000},
62 {0x00008020, 0x00000000},
63 {0x00008038, 0x00000000},
64 {0x0000803c, 0x00000000},
65 {0x00008040, 0x00000000},
66 {0x00008044, 0x00000000},
67 {0x00008048, 0x00000000},
68 {0x0000804c, 0xffffffff},
69 {0x00008054, 0x00000000},
70 {0x00008058, 0x00000000},
71 {0x0000805c, 0x000fc78f},
72 {0x00008060, 0x0000000f},
73 {0x00008064, 0x00000000},
74 {0x00008070, 0x00000310},
75 {0x00008074, 0x00000020},
76 {0x00008078, 0x00000000},
77 {0x0000809c, 0x0000000f},
78 {0x000080a0, 0x00000000},
79 {0x000080a4, 0x02ff0000},
80 {0x000080a8, 0x0e070605},
81 {0x000080ac, 0x0000000d},
82 {0x000080b0, 0x00000000},
83 {0x000080b4, 0x00000000},
84 {0x000080b8, 0x00000000},
85 {0x000080bc, 0x00000000},
86 {0x000080c0, 0x2a800000},
87 {0x000080c4, 0x06900168},
88 {0x000080c8, 0x13881c22},
89 {0x000080cc, 0x01f40000},
90 {0x000080d0, 0x00252500},
91 {0x000080d4, 0x00a00000},
92 {0x000080d8, 0x00400000},
93 {0x000080dc, 0x00000000},
94 {0x000080e0, 0xffffffff},
95 {0x000080e4, 0x0000ffff},
96 {0x000080e8, 0x3f3f3f3f},
97 {0x000080ec, 0x00000000},
98 {0x000080f0, 0x00000000},
99 {0x000080f4, 0x00000000},
100 {0x000080fc, 0x00020000},
101 {0x00008100, 0x00000000},
102 {0x00008108, 0x00000052},
103 {0x0000810c, 0x00000000},
104 {0x00008110, 0x00000000},
105 {0x00008114, 0x000007ff},
106 {0x00008118, 0x000000aa},
107 {0x0000811c, 0x00003210},
108 {0x00008124, 0x00000000},
109 {0x00008128, 0x00000000},
110 {0x0000812c, 0x00000000},
111 {0x00008130, 0x00000000},
112 {0x00008134, 0x00000000},
113 {0x00008138, 0x00000000},
114 {0x0000813c, 0x0000ffff},
115 {0x00008140, 0x000000fe},
116 {0x00008144, 0xffffffff},
117 {0x00008168, 0x00000000},
118 {0x0000816c, 0x00000000},
119 {0x000081c0, 0x00000000},
120 {0x000081c4, 0x33332210},
121 {0x000081ec, 0x00000000},
122 {0x000081f0, 0x00000000},
123 {0x000081f4, 0x00000000},
124 {0x000081f8, 0x00000000},
125 {0x000081fc, 0x00000000},
126 {0x00008240, 0x00100000},
127 {0x00008244, 0x0010f3d7},
128 {0x00008248, 0x00000852},
129 {0x0000824c, 0x0001e7ae},
130 {0x00008250, 0x00000000},
131 {0x00008254, 0x00000000},
132 {0x00008258, 0x00000000},
133 {0x0000825c, 0x40000000},
134 {0x00008260, 0x00080922},
135 {0x00008264, 0x9d400010},
136 {0x00008268, 0xffffffff},
137 {0x0000826c, 0x0000ffff},
138 {0x00008270, 0x00000000},
139 {0x00008274, 0x40000000},
140 {0x00008278, 0x003e4180},
141 {0x0000827c, 0x00000004},
142 {0x00008284, 0x0000002c},
143 {0x00008288, 0x0000002c},
144 {0x0000828c, 0x000000ff},
145 {0x00008294, 0x00000000},
146 {0x00008298, 0x00000000},
147 {0x0000829c, 0x00000000},
148 {0x00008300, 0x00001d40},
149 {0x00008314, 0x00000000},
150 {0x0000831c, 0x0000010d},
151 {0x00008328, 0x00000000},
152 {0x0000832c, 0x0000001f},
153 {0x00008330, 0x00000302},
154 {0x00008334, 0x00000700},
155 {0x00008338, 0xffff0000},
156 {0x0000833c, 0x02400000},
157 {0x00008340, 0x000107ff},
158 {0x00008344, 0xaa48107b},
159 {0x00008348, 0x008f0000},
160 {0x0000835c, 0x00000000},
161 {0x00008360, 0xffffffff},
162 {0x00008364, 0xffffffff},
163 {0x00008368, 0x00000000},
164 {0x00008370, 0x00000000},
165 {0x00008374, 0x000000ff},
166 {0x00008378, 0x00000000},
167 {0x0000837c, 0x00000000},
168 {0x00008380, 0xffffffff},
169 {0x00008384, 0xffffffff},
170 {0x00008390, 0xffffffff},
171 {0x00008394, 0xffffffff},
172 {0x00008398, 0x00000000},
173 {0x0000839c, 0x00000000},
174 {0x000083a0, 0x00000000},
175 {0x000083a4, 0x0000fa14},
176 {0x000083a8, 0x000f0c00},
177 {0x000083ac, 0x33332210},
178 {0x000083b0, 0x33332210},
179 {0x000083b4, 0x33332210},
180 {0x000083b8, 0x33332210},
181 {0x000083bc, 0x00000000},
182 {0x000083c0, 0x00000000},
183 {0x000083c4, 0x00000000},
184 {0x000083c8, 0x00000000},
185 {0x000083cc, 0x00000200},
186 {0x000083d0, 0x8c7901ff},
187};
188
189static const u32 qca953x_1p0_baseband_core[][2] = {
190 /* Addr allmodes */
191 {0x00009800, 0xafe68e30},
192 {0x00009804, 0xfd14e000},
193 {0x00009808, 0x9c0a9f6b},
194 {0x0000980c, 0x04900000},
195 {0x00009814, 0x0280c00a},
196 {0x00009818, 0x00000000},
197 {0x0000981c, 0x00020028},
198 {0x00009834, 0x6400a190},
199 {0x00009838, 0x0108ecff},
200 {0x0000983c, 0x14000600},
201 {0x00009880, 0x201fff00},
202 {0x00009884, 0x00001042},
203 {0x000098a4, 0x00200400},
204 {0x000098b0, 0x32840bbe},
205 {0x000098bc, 0x00000002},
206 {0x000098d0, 0x004b6a8e},
207 {0x000098d4, 0x00000820},
208 {0x000098dc, 0x00000000},
209 {0x000098f0, 0x00000000},
210 {0x000098f4, 0x00000000},
211 {0x00009c04, 0xff55ff55},
212 {0x00009c08, 0x0320ff55},
213 {0x00009c0c, 0x00000000},
214 {0x00009c10, 0x00000000},
215 {0x00009c14, 0x00046384},
216 {0x00009c18, 0x05b6b440},
217 {0x00009c1c, 0x00b6b440},
218 {0x00009d00, 0xc080a333},
219 {0x00009d04, 0x40206c10},
220 {0x00009d08, 0x009c4060},
221 {0x00009d0c, 0x9883800a},
222 {0x00009d10, 0x01884061},
223 {0x00009d14, 0x00c0040b},
224 {0x00009d18, 0x00000000},
225 {0x00009e08, 0x0038230c},
226 {0x00009e24, 0x990bb515},
227 {0x00009e28, 0x0c6f0000},
228 {0x00009e30, 0x06336f77},
229 {0x00009e34, 0x6af6532f},
230 {0x00009e38, 0x0cc80c00},
231 {0x00009e40, 0x0d261820},
232 {0x00009e4c, 0x00001004},
233 {0x00009e50, 0x00ff03f1},
234 {0x00009fc0, 0x813e4788},
235 {0x00009fc4, 0x0001efb5},
236 {0x00009fcc, 0x40000014},
237 {0x00009fd0, 0x01193b91},
238 {0x0000a20c, 0x00000000},
239 {0x0000a220, 0x00000000},
240 {0x0000a224, 0x00000000},
241 {0x0000a228, 0x10002310},
242 {0x0000a23c, 0x00000000},
243 {0x0000a244, 0x0c000000},
244 {0x0000a248, 0x00000140},
245 {0x0000a2a0, 0x00000007},
246 {0x0000a2c0, 0x00000007},
247 {0x0000a2c8, 0x00000000},
248 {0x0000a2d4, 0x00000000},
249 {0x0000a2ec, 0x00000000},
250 {0x0000a2f0, 0x00000000},
251 {0x0000a2f4, 0x00000000},
252 {0x0000a2f8, 0x00000000},
253 {0x0000a344, 0x00000000},
254 {0x0000a34c, 0x00000000},
255 {0x0000a350, 0x0000a000},
256 {0x0000a364, 0x00000000},
257 {0x0000a370, 0x00000000},
258 {0x0000a390, 0x00000001},
259 {0x0000a394, 0x00000444},
260 {0x0000a398, 0x1f020503},
261 {0x0000a39c, 0x29180c03},
262 {0x0000a3a0, 0x9a8b6844},
263 {0x0000a3a4, 0x000000ff},
264 {0x0000a3a8, 0x6a6a6a6a},
265 {0x0000a3ac, 0x6a6a6a6a},
266 {0x0000a3b0, 0x00c8641a},
267 {0x0000a3b4, 0x0000001a},
268 {0x0000a3b8, 0x0088642a},
269 {0x0000a3bc, 0x000001fa},
270 {0x0000a3c0, 0x20202020},
271 {0x0000a3c4, 0x22222220},
272 {0x0000a3c8, 0x20200020},
273 {0x0000a3cc, 0x20202020},
274 {0x0000a3d0, 0x20202020},
275 {0x0000a3d4, 0x20202020},
276 {0x0000a3d8, 0x20202020},
277 {0x0000a3dc, 0x20202020},
278 {0x0000a3e0, 0x20202020},
279 {0x0000a3e4, 0x20202020},
280 {0x0000a3e8, 0x20202020},
281 {0x0000a3ec, 0x20202020},
282 {0x0000a3f0, 0x00000000},
283 {0x0000a3f4, 0x00000000},
284 {0x0000a3f8, 0x0c9bd380},
285 {0x0000a3fc, 0x000f0f01},
286 {0x0000a400, 0x8fa91f01},
287 {0x0000a404, 0x00000000},
288 {0x0000a408, 0x0e79e5c6},
289 {0x0000a40c, 0x00820820},
290 {0x0000a414, 0x1ce42108},
291 {0x0000a418, 0x2d001dce},
292 {0x0000a41c, 0x1ce73908},
293 {0x0000a420, 0x000001ce},
294 {0x0000a424, 0x1ce738e7},
295 {0x0000a428, 0x000001ce},
296 {0x0000a42c, 0x1ce739ce},
297 {0x0000a430, 0x1ce739ce},
298 {0x0000a434, 0x00000000},
299 {0x0000a438, 0x00001801},
300 {0x0000a43c, 0x00100000},
301 {0x0000a444, 0x00000000},
302 {0x0000a448, 0x05000080},
303 {0x0000a44c, 0x00000001},
304 {0x0000a450, 0x00010000},
305 {0x0000a458, 0x00000000},
306 {0x0000a644, 0xbfad9d74},
307 {0x0000a648, 0x0048060a},
308 {0x0000a64c, 0x00003c37},
309 {0x0000a670, 0x03020100},
310 {0x0000a674, 0x09080504},
311 {0x0000a678, 0x0d0c0b0a},
312 {0x0000a67c, 0x13121110},
313 {0x0000a680, 0x31301514},
314 {0x0000a684, 0x35343332},
315 {0x0000a688, 0x00000036},
316 {0x0000a690, 0x08000838},
317 {0x0000a7cc, 0x00000000},
318 {0x0000a7d0, 0x00000000},
319 {0x0000a7d4, 0x00000004},
320 {0x0000a7dc, 0x00000000},
321 {0x0000a8d0, 0x004b6a8e},
322 {0x0000a8d4, 0x00000820},
323 {0x0000a8dc, 0x00000000},
324 {0x0000a8f0, 0x00000000},
325 {0x0000a8f4, 0x00000000},
326 {0x0000b2d0, 0x00000080},
327 {0x0000b2d4, 0x00000000},
328 {0x0000b2ec, 0x00000000},
329 {0x0000b2f0, 0x00000000},
330 {0x0000b2f4, 0x00000000},
331 {0x0000b2f8, 0x00000000},
332 {0x0000b408, 0x0e79e5c0},
333 {0x0000b40c, 0x00820820},
334 {0x0000b420, 0x00000000},
335};
336
337static const u32 qca953x_1p0_baseband_postamble[][5] = {
338 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
339 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
340 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
341 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
342 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
343 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
344 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
345 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
346 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
347 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
348 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
349 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
350 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
351 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
352 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
353 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
354 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
355 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10822, 0xcfa10822},
356 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
357 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
358 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
359 {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0},
360 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
361 {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
362 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
363 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
364 {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
365 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
366 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
367 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
368 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
369 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
370 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
371 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
372 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
373 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
374 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
375 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
376 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
377 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
378 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
379 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
380 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
381 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
382 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
383 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
384 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
385 {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
386};
387
388static const u32 qca953x_1p0_radio_core[][2] = {
389 /* Addr allmodes */
390 {0x00016000, 0x36db6db6},
391 {0x00016004, 0x6db6db40},
392 {0x00016008, 0x73f00000},
393 {0x0001600c, 0x00000000},
394 {0x00016040, 0x3f80fff8},
395 {0x0001604c, 0x000f0278},
396 {0x00016050, 0x8036db6c},
397 {0x00016054, 0x6db60000},
398 {0x00016080, 0x00080000},
399 {0x00016084, 0x0e48048c},
400 {0x00016088, 0x14214514},
401 {0x0001608c, 0x119f080a},
402 {0x00016090, 0x24926490},
403 {0x00016094, 0x00000000},
404 {0x000160a0, 0xc2108ffe},
405 {0x000160a4, 0x812fc370},
406 {0x000160a8, 0x423c8000},
407 {0x000160b4, 0x92480080},
408 {0x000160c0, 0x006db6d8},
409 {0x000160c4, 0x24b6db6c},
410 {0x000160c8, 0x6db6db6c},
411 {0x000160cc, 0x6db6fb7c},
412 {0x000160d0, 0x6db6da44},
413 {0x00016100, 0x07ff8001},
414 {0x00016108, 0x00080010},
415 {0x00016144, 0x01884080},
416 {0x00016148, 0x000080d8},
417 {0x00016280, 0x01000901},
418 {0x00016284, 0x15d30000},
419 {0x00016288, 0x00318000},
420 {0x0001628c, 0x50000000},
421 {0x00016380, 0x00000000},
422 {0x00016384, 0x00000000},
423 {0x00016388, 0x00800700},
424 {0x0001638c, 0x00800700},
425 {0x00016390, 0x00800700},
426 {0x00016394, 0x00000000},
427 {0x00016398, 0x00000000},
428 {0x0001639c, 0x00000000},
429 {0x000163a0, 0x00000001},
430 {0x000163a4, 0x00000001},
431 {0x000163a8, 0x00000000},
432 {0x000163ac, 0x00000000},
433 {0x000163b0, 0x00000000},
434 {0x000163b4, 0x00000000},
435 {0x000163b8, 0x00000000},
436 {0x000163bc, 0x00000000},
437 {0x000163c0, 0x000000a0},
438 {0x000163c4, 0x000c0000},
439 {0x000163c8, 0x14021402},
440 {0x000163cc, 0x00001402},
441 {0x000163d0, 0x00000000},
442 {0x000163d4, 0x00000000},
443 {0x00016400, 0x36db6db6},
444 {0x00016404, 0x6db6db40},
445 {0x00016408, 0x73f00000},
446 {0x0001640c, 0x00000000},
447 {0x00016440, 0x3f80fff8},
448 {0x0001644c, 0x000f0278},
449 {0x00016450, 0x8036db6c},
450 {0x00016454, 0x6db60000},
451 {0x00016500, 0x07ff8001},
452 {0x00016508, 0x00080010},
453 {0x00016544, 0x01884080},
454 {0x00016548, 0x000080d8},
455 {0x00016780, 0x00000000},
456 {0x00016784, 0x00000000},
457 {0x00016788, 0x00800700},
458 {0x0001678c, 0x00800700},
459 {0x00016790, 0x00800700},
460 {0x00016794, 0x00000000},
461 {0x00016798, 0x00000000},
462 {0x0001679c, 0x00000000},
463 {0x000167a0, 0x00000001},
464 {0x000167a4, 0x00000001},
465 {0x000167a8, 0x00000000},
466 {0x000167ac, 0x00000000},
467 {0x000167b0, 0x00000000},
468 {0x000167b4, 0x00000000},
469 {0x000167b8, 0x00000000},
470 {0x000167bc, 0x00000000},
471 {0x000167c0, 0x000000a0},
472 {0x000167c4, 0x000c0000},
473 {0x000167c8, 0x14021402},
474 {0x000167cc, 0x00001402},
475 {0x000167d0, 0x00000000},
476 {0x000167d4, 0x00000000},
477};
478
479static const u32 qca953x_1p0_radio_postamble[][5] = {
480 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
481 {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xc4128f5c, 0xc4128f5c},
482 {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0fd08f25, 0x0fd08f25},
483 {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24646800, 0x24646800},
484 {0x000160b0, 0x01885f52, 0x01885f52, 0x00fe7f46, 0x00fe7f46},
485 {0x00016104, 0xb7a00001, 0xb7a00001, 0xfff80005, 0xfff80005},
486 {0x0001610c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000},
487 {0x00016140, 0x10804008, 0x10804008, 0x50804000, 0x50804000},
488 {0x00016504, 0xb7a00001, 0xb7a00001, 0xfff80001, 0xfff80001},
489 {0x0001650c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000},
490 {0x00016540, 0x10804008, 0x10804008, 0x50804000, 0x50804000},
491};
492
493static const u32 qca953x_1p0_soc_preamble[][2] = {
494 /* Addr allmodes */
495 {0x00007000, 0x00000000},
496 {0x00007004, 0x00000000},
497 {0x00007008, 0x00000000},
498 {0x0000700c, 0x00000000},
499 {0x0000701c, 0x00000000},
500 {0x00007020, 0x00000000},
501 {0x00007024, 0x00000000},
502 {0x00007028, 0x00000000},
503 {0x0000702c, 0x00000000},
504 {0x00007030, 0x00000000},
505 {0x00007034, 0x00000002},
506 {0x00007038, 0x000004c2},
507 {0x00007048, 0x00000000},
508};
509
510static const u32 qca953x_1p0_common_rx_gain_bounds[][5] = {
511 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
512 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
513 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302018, 0x50302018},
514};
515
516static const u32 qca953x_1p0_common_wo_xlna_rx_gain_bounds[][5] = {
517 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
518 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
519 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
520};
521
522static const u32 qca953x_1p0_modes_xpa_tx_gain_table[][2] = {
523 /* Addr allmodes */
524 {0x0000a2dc, 0xfffd5aaa},
525 {0x0000a2e0, 0xfffe9ccc},
526 {0x0000a2e4, 0xffffe0f0},
527 {0x0000a2e8, 0xfffcff00},
528 {0x0000a410, 0x000050da},
529 {0x0000a500, 0x00000000},
530 {0x0000a504, 0x04000002},
531 {0x0000a508, 0x08000004},
532 {0x0000a50c, 0x0c000006},
533 {0x0000a510, 0x0f00000a},
534 {0x0000a514, 0x1300000c},
535 {0x0000a518, 0x1700000e},
536 {0x0000a51c, 0x1b000064},
537 {0x0000a520, 0x1f000242},
538 {0x0000a524, 0x23000229},
539 {0x0000a528, 0x270002a2},
540 {0x0000a52c, 0x2c001203},
541 {0x0000a530, 0x30001803},
542 {0x0000a534, 0x33000881},
543 {0x0000a538, 0x38001809},
544 {0x0000a53c, 0x3a000814},
545 {0x0000a540, 0x3f001a0c},
546 {0x0000a544, 0x43001a0e},
547 {0x0000a548, 0x46001812},
548 {0x0000a54c, 0x49001884},
549 {0x0000a550, 0x4d001e84},
550 {0x0000a554, 0x50001e69},
551 {0x0000a558, 0x550006f4},
552 {0x0000a55c, 0x59000ad3},
553 {0x0000a560, 0x5e000ad5},
554 {0x0000a564, 0x61001ced},
555 {0x0000a568, 0x660018d4},
556 {0x0000a56c, 0x660018d4},
557 {0x0000a570, 0x660018d4},
558 {0x0000a574, 0x660018d4},
559 {0x0000a578, 0x660018d4},
560 {0x0000a57c, 0x660018d4},
561 {0x0000a600, 0x00000000},
562 {0x0000a604, 0x00000000},
563 {0x0000a608, 0x00000000},
564 {0x0000a60c, 0x03804000},
565 {0x0000a610, 0x0300ca02},
566 {0x0000a614, 0x00000e04},
567 {0x0000a618, 0x03014000},
568 {0x0000a61c, 0x00000000},
569 {0x0000a620, 0x00000000},
570 {0x0000a624, 0x03014000},
571 {0x0000a628, 0x03804c05},
572 {0x0000a62c, 0x0701de06},
573 {0x0000a630, 0x07819c07},
574 {0x0000a634, 0x0701dc07},
575 {0x0000a638, 0x0701dc07},
576 {0x0000a63c, 0x0701dc07},
577 {0x0000b2dc, 0xfffd5aaa},
578 {0x0000b2e0, 0xfffe9ccc},
579 {0x0000b2e4, 0xffffe0f0},
580 {0x0000b2e8, 0xfffcff00},
581 {0x00016044, 0x010002d4},
582 {0x00016048, 0x66482400},
583 {0x00016280, 0x01000015},
584 {0x00016444, 0x010002d4},
585 {0x00016448, 0x66482400},
586};
587
588static const u32 qca953x_1p0_modes_no_xpa_tx_gain_table[][2] = {
589 /* Addr allmodes */
590 {0x0000a2dc, 0xffd5f552},
591 {0x0000a2e0, 0xffe60664},
592 {0x0000a2e4, 0xfff80780},
593 {0x0000a2e8, 0xfffff800},
594 {0x0000a410, 0x000050d6},
595 {0x0000a500, 0x00060020},
596 {0x0000a504, 0x04060060},
597 {0x0000a508, 0x080600a0},
598 {0x0000a50c, 0x0c068020},
599 {0x0000a510, 0x10068060},
600 {0x0000a514, 0x140680a0},
601 {0x0000a518, 0x18090040},
602 {0x0000a51c, 0x1b090080},
603 {0x0000a520, 0x1f0900c0},
604 {0x0000a524, 0x240c0041},
605 {0x0000a528, 0x280d0021},
606 {0x0000a52c, 0x2d0f0061},
607 {0x0000a530, 0x310f00a1},
608 {0x0000a534, 0x350e00a2},
609 {0x0000a538, 0x360e80a2},
610 {0x0000a53c, 0x380f00a2},
611 {0x0000a540, 0x3b0e00a3},
612 {0x0000a544, 0x3d110083},
613 {0x0000a548, 0x3e1100a3},
614 {0x0000a54c, 0x401100e3},
615 {0x0000a550, 0x421380e3},
616 {0x0000a554, 0x431780e3},
617 {0x0000a558, 0x461f80e3},
618 {0x0000a55c, 0x461f80e3},
619 {0x0000a560, 0x461f80e3},
620 {0x0000a564, 0x461f80e3},
621 {0x0000a568, 0x461f80e3},
622 {0x0000a56c, 0x461f80e3},
623 {0x0000a570, 0x461f80e3},
624 {0x0000a574, 0x461f80e3},
625 {0x0000a578, 0x461f80e3},
626 {0x0000a57c, 0x461f80e3},
627 {0x0000a600, 0x00000000},
628 {0x0000a604, 0x00000000},
629 {0x0000a608, 0x00000000},
630 {0x0000a60c, 0x00804201},
631 {0x0000a610, 0x01008201},
632 {0x0000a614, 0x0180c402},
633 {0x0000a618, 0x0180c603},
634 {0x0000a61c, 0x0180c603},
635 {0x0000a620, 0x01c10603},
636 {0x0000a624, 0x01c10704},
637 {0x0000a628, 0x02c18b05},
638 {0x0000a62c, 0x0301cc07},
639 {0x0000a630, 0x0301cc07},
640 {0x0000a634, 0x0301cc07},
641 {0x0000a638, 0x0301cc07},
642 {0x0000a63c, 0x0301cc07},
643 {0x0000b2dc, 0xffd5f552},
644 {0x0000b2e0, 0xffe60664},
645 {0x0000b2e4, 0xfff80780},
646 {0x0000b2e8, 0xfffff800},
647 {0x00016044, 0x049242db},
648 {0x00016048, 0x6c927a70},
649 {0x00016444, 0x049242db},
650 {0x00016448, 0x6c927a70},
651};
652
653static const u32 qca953x_1p1_modes_no_xpa_tx_gain_table[][2] = {
654 /* Addr allmodes */
655 {0x0000a2dc, 0xffd5f552},
656 {0x0000a2e0, 0xffe60664},
657 {0x0000a2e4, 0xfff80780},
658 {0x0000a2e8, 0xfffff800},
659 {0x0000a410, 0x000050de},
660 {0x0000a500, 0x00000061},
661 {0x0000a504, 0x04000063},
662 {0x0000a508, 0x08000065},
663 {0x0000a50c, 0x0c000261},
664 {0x0000a510, 0x10000263},
665 {0x0000a514, 0x14000265},
666 {0x0000a518, 0x18000482},
667 {0x0000a51c, 0x1b000484},
668 {0x0000a520, 0x1f000486},
669 {0x0000a524, 0x240008c2},
670 {0x0000a528, 0x28000cc1},
671 {0x0000a52c, 0x2d000ce3},
672 {0x0000a530, 0x31000ce5},
673 {0x0000a534, 0x350010e5},
674 {0x0000a538, 0x360012e5},
675 {0x0000a53c, 0x380014e5},
676 {0x0000a540, 0x3b0018e5},
677 {0x0000a544, 0x3d001d04},
678 {0x0000a548, 0x3e001d05},
679 {0x0000a54c, 0x40001d07},
680 {0x0000a550, 0x42001f27},
681 {0x0000a554, 0x43001f67},
682 {0x0000a558, 0x46001fe7},
683 {0x0000a55c, 0x47001f2b},
684 {0x0000a560, 0x49001f0d},
685 {0x0000a564, 0x4b001ed2},
686 {0x0000a568, 0x4c001ed4},
687 {0x0000a56c, 0x4e001f15},
688 {0x0000a570, 0x4f001ff6},
689 {0x0000a574, 0x4f001ff6},
690 {0x0000a578, 0x4f001ff6},
691 {0x0000a57c, 0x4f001ff6},
692 {0x0000a600, 0x00000000},
693 {0x0000a604, 0x00000000},
694 {0x0000a608, 0x00000000},
695 {0x0000a60c, 0x00804201},
696 {0x0000a610, 0x01008201},
697 {0x0000a614, 0x0180c402},
698 {0x0000a618, 0x0180c603},
699 {0x0000a61c, 0x0180c603},
700 {0x0000a620, 0x01c10603},
701 {0x0000a624, 0x01c10704},
702 {0x0000a628, 0x02c18b05},
703 {0x0000a62c, 0x02c14c07},
704 {0x0000a630, 0x01008704},
705 {0x0000a634, 0x01c10402},
706 {0x0000a638, 0x0301cc07},
707 {0x0000a63c, 0x0301cc07},
708 {0x0000b2dc, 0xffd5f552},
709 {0x0000b2e0, 0xffe60664},
710 {0x0000b2e4, 0xfff80780},
711 {0x0000b2e8, 0xfffff800},
712 {0x00016044, 0x049242db},
713 {0x00016048, 0x6c927a70},
714 {0x00016444, 0x049242db},
715 {0x00016448, 0x6c927a70},
716};
717
718#endif /* INITVALS_953X_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
index ccc5b6c99add..74d8bc05b317 100644
--- a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
@@ -20,6 +20,14 @@
20 20
21/* AR955X 1.0 */ 21/* AR955X 1.0 */
22 22
23#define ar955x_1p0_soc_postamble ar9300_2p2_soc_postamble
24
25#define ar955x_1p0_common_rx_gain_table ar9300Common_rx_gain_table_2p2
26
27#define ar955x_1p0_common_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
28
29#define ar955x_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
30
23static const u32 ar955x_1p0_radio_postamble[][5] = { 31static const u32 ar955x_1p0_radio_postamble[][5] = {
24 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 32 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
25 {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330}, 33 {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330},
@@ -37,13 +45,6 @@ static const u32 ar955x_1p0_radio_postamble[][5] = {
37 {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008}, 45 {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
38}; 46};
39 47
40static const u32 ar955x_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
41 /* Addr allmodes */
42 {0x0000a398, 0x00000000},
43 {0x0000a39c, 0x6f7f0301},
44 {0x0000a3a0, 0xca9228ee},
45};
46
47static const u32 ar955x_1p0_baseband_postamble[][5] = { 48static const u32 ar955x_1p0_baseband_postamble[][5] = {
48 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 49 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
49 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 50 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
@@ -473,266 +474,6 @@ static const u32 ar955x_1p0_mac_core[][2] = {
473 {0x000083d0, 0x8c7901ff}, 474 {0x000083d0, 0x8c7901ff},
474}; 475};
475 476
476static const u32 ar955x_1p0_common_rx_gain_table[][2] = {
477 /* Addr allmodes */
478 {0x0000a000, 0x00010000},
479 {0x0000a004, 0x00030002},
480 {0x0000a008, 0x00050004},
481 {0x0000a00c, 0x00810080},
482 {0x0000a010, 0x00830082},
483 {0x0000a014, 0x01810180},
484 {0x0000a018, 0x01830182},
485 {0x0000a01c, 0x01850184},
486 {0x0000a020, 0x01890188},
487 {0x0000a024, 0x018b018a},
488 {0x0000a028, 0x018d018c},
489 {0x0000a02c, 0x01910190},
490 {0x0000a030, 0x01930192},
491 {0x0000a034, 0x01950194},
492 {0x0000a038, 0x038a0196},
493 {0x0000a03c, 0x038c038b},
494 {0x0000a040, 0x0390038d},
495 {0x0000a044, 0x03920391},
496 {0x0000a048, 0x03940393},
497 {0x0000a04c, 0x03960395},
498 {0x0000a050, 0x00000000},
499 {0x0000a054, 0x00000000},
500 {0x0000a058, 0x00000000},
501 {0x0000a05c, 0x00000000},
502 {0x0000a060, 0x00000000},
503 {0x0000a064, 0x00000000},
504 {0x0000a068, 0x00000000},
505 {0x0000a06c, 0x00000000},
506 {0x0000a070, 0x00000000},
507 {0x0000a074, 0x00000000},
508 {0x0000a078, 0x00000000},
509 {0x0000a07c, 0x00000000},
510 {0x0000a080, 0x22222229},
511 {0x0000a084, 0x1d1d1d1d},
512 {0x0000a088, 0x1d1d1d1d},
513 {0x0000a08c, 0x1d1d1d1d},
514 {0x0000a090, 0x171d1d1d},
515 {0x0000a094, 0x11111717},
516 {0x0000a098, 0x00030311},
517 {0x0000a09c, 0x00000000},
518 {0x0000a0a0, 0x00000000},
519 {0x0000a0a4, 0x00000000},
520 {0x0000a0a8, 0x00000000},
521 {0x0000a0ac, 0x00000000},
522 {0x0000a0b0, 0x00000000},
523 {0x0000a0b4, 0x00000000},
524 {0x0000a0b8, 0x00000000},
525 {0x0000a0bc, 0x00000000},
526 {0x0000a0c0, 0x001f0000},
527 {0x0000a0c4, 0x01000101},
528 {0x0000a0c8, 0x011e011f},
529 {0x0000a0cc, 0x011c011d},
530 {0x0000a0d0, 0x02030204},
531 {0x0000a0d4, 0x02010202},
532 {0x0000a0d8, 0x021f0200},
533 {0x0000a0dc, 0x0302021e},
534 {0x0000a0e0, 0x03000301},
535 {0x0000a0e4, 0x031e031f},
536 {0x0000a0e8, 0x0402031d},
537 {0x0000a0ec, 0x04000401},
538 {0x0000a0f0, 0x041e041f},
539 {0x0000a0f4, 0x0502041d},
540 {0x0000a0f8, 0x05000501},
541 {0x0000a0fc, 0x051e051f},
542 {0x0000a100, 0x06010602},
543 {0x0000a104, 0x061f0600},
544 {0x0000a108, 0x061d061e},
545 {0x0000a10c, 0x07020703},
546 {0x0000a110, 0x07000701},
547 {0x0000a114, 0x00000000},
548 {0x0000a118, 0x00000000},
549 {0x0000a11c, 0x00000000},
550 {0x0000a120, 0x00000000},
551 {0x0000a124, 0x00000000},
552 {0x0000a128, 0x00000000},
553 {0x0000a12c, 0x00000000},
554 {0x0000a130, 0x00000000},
555 {0x0000a134, 0x00000000},
556 {0x0000a138, 0x00000000},
557 {0x0000a13c, 0x00000000},
558 {0x0000a140, 0x001f0000},
559 {0x0000a144, 0x01000101},
560 {0x0000a148, 0x011e011f},
561 {0x0000a14c, 0x011c011d},
562 {0x0000a150, 0x02030204},
563 {0x0000a154, 0x02010202},
564 {0x0000a158, 0x021f0200},
565 {0x0000a15c, 0x0302021e},
566 {0x0000a160, 0x03000301},
567 {0x0000a164, 0x031e031f},
568 {0x0000a168, 0x0402031d},
569 {0x0000a16c, 0x04000401},
570 {0x0000a170, 0x041e041f},
571 {0x0000a174, 0x0502041d},
572 {0x0000a178, 0x05000501},
573 {0x0000a17c, 0x051e051f},
574 {0x0000a180, 0x06010602},
575 {0x0000a184, 0x061f0600},
576 {0x0000a188, 0x061d061e},
577 {0x0000a18c, 0x07020703},
578 {0x0000a190, 0x07000701},
579 {0x0000a194, 0x00000000},
580 {0x0000a198, 0x00000000},
581 {0x0000a19c, 0x00000000},
582 {0x0000a1a0, 0x00000000},
583 {0x0000a1a4, 0x00000000},
584 {0x0000a1a8, 0x00000000},
585 {0x0000a1ac, 0x00000000},
586 {0x0000a1b0, 0x00000000},
587 {0x0000a1b4, 0x00000000},
588 {0x0000a1b8, 0x00000000},
589 {0x0000a1bc, 0x00000000},
590 {0x0000a1c0, 0x00000000},
591 {0x0000a1c4, 0x00000000},
592 {0x0000a1c8, 0x00000000},
593 {0x0000a1cc, 0x00000000},
594 {0x0000a1d0, 0x00000000},
595 {0x0000a1d4, 0x00000000},
596 {0x0000a1d8, 0x00000000},
597 {0x0000a1dc, 0x00000000},
598 {0x0000a1e0, 0x00000000},
599 {0x0000a1e4, 0x00000000},
600 {0x0000a1e8, 0x00000000},
601 {0x0000a1ec, 0x00000000},
602 {0x0000a1f0, 0x00000396},
603 {0x0000a1f4, 0x00000396},
604 {0x0000a1f8, 0x00000396},
605 {0x0000a1fc, 0x00000196},
606 {0x0000b000, 0x00010000},
607 {0x0000b004, 0x00030002},
608 {0x0000b008, 0x00050004},
609 {0x0000b00c, 0x00810080},
610 {0x0000b010, 0x00830082},
611 {0x0000b014, 0x01810180},
612 {0x0000b018, 0x01830182},
613 {0x0000b01c, 0x01850184},
614 {0x0000b020, 0x02810280},
615 {0x0000b024, 0x02830282},
616 {0x0000b028, 0x02850284},
617 {0x0000b02c, 0x02890288},
618 {0x0000b030, 0x028b028a},
619 {0x0000b034, 0x0388028c},
620 {0x0000b038, 0x038a0389},
621 {0x0000b03c, 0x038c038b},
622 {0x0000b040, 0x0390038d},
623 {0x0000b044, 0x03920391},
624 {0x0000b048, 0x03940393},
625 {0x0000b04c, 0x03960395},
626 {0x0000b050, 0x00000000},
627 {0x0000b054, 0x00000000},
628 {0x0000b058, 0x00000000},
629 {0x0000b05c, 0x00000000},
630 {0x0000b060, 0x00000000},
631 {0x0000b064, 0x00000000},
632 {0x0000b068, 0x00000000},
633 {0x0000b06c, 0x00000000},
634 {0x0000b070, 0x00000000},
635 {0x0000b074, 0x00000000},
636 {0x0000b078, 0x00000000},
637 {0x0000b07c, 0x00000000},
638 {0x0000b080, 0x23232323},
639 {0x0000b084, 0x21232323},
640 {0x0000b088, 0x19191c1e},
641 {0x0000b08c, 0x12141417},
642 {0x0000b090, 0x07070e0e},
643 {0x0000b094, 0x03030305},
644 {0x0000b098, 0x00000003},
645 {0x0000b09c, 0x00000000},
646 {0x0000b0a0, 0x00000000},
647 {0x0000b0a4, 0x00000000},
648 {0x0000b0a8, 0x00000000},
649 {0x0000b0ac, 0x00000000},
650 {0x0000b0b0, 0x00000000},
651 {0x0000b0b4, 0x00000000},
652 {0x0000b0b8, 0x00000000},
653 {0x0000b0bc, 0x00000000},
654 {0x0000b0c0, 0x003f0020},
655 {0x0000b0c4, 0x00400041},
656 {0x0000b0c8, 0x0140005f},
657 {0x0000b0cc, 0x0160015f},
658 {0x0000b0d0, 0x017e017f},
659 {0x0000b0d4, 0x02410242},
660 {0x0000b0d8, 0x025f0240},
661 {0x0000b0dc, 0x027f0260},
662 {0x0000b0e0, 0x0341027e},
663 {0x0000b0e4, 0x035f0340},
664 {0x0000b0e8, 0x037f0360},
665 {0x0000b0ec, 0x04400441},
666 {0x0000b0f0, 0x0460045f},
667 {0x0000b0f4, 0x0541047f},
668 {0x0000b0f8, 0x055f0540},
669 {0x0000b0fc, 0x057f0560},
670 {0x0000b100, 0x06400641},
671 {0x0000b104, 0x0660065f},
672 {0x0000b108, 0x067e067f},
673 {0x0000b10c, 0x07410742},
674 {0x0000b110, 0x075f0740},
675 {0x0000b114, 0x077f0760},
676 {0x0000b118, 0x07800781},
677 {0x0000b11c, 0x07a0079f},
678 {0x0000b120, 0x07c107bf},
679 {0x0000b124, 0x000007c0},
680 {0x0000b128, 0x00000000},
681 {0x0000b12c, 0x00000000},
682 {0x0000b130, 0x00000000},
683 {0x0000b134, 0x00000000},
684 {0x0000b138, 0x00000000},
685 {0x0000b13c, 0x00000000},
686 {0x0000b140, 0x003f0020},
687 {0x0000b144, 0x00400041},
688 {0x0000b148, 0x0140005f},
689 {0x0000b14c, 0x0160015f},
690 {0x0000b150, 0x017e017f},
691 {0x0000b154, 0x02410242},
692 {0x0000b158, 0x025f0240},
693 {0x0000b15c, 0x027f0260},
694 {0x0000b160, 0x0341027e},
695 {0x0000b164, 0x035f0340},
696 {0x0000b168, 0x037f0360},
697 {0x0000b16c, 0x04400441},
698 {0x0000b170, 0x0460045f},
699 {0x0000b174, 0x0541047f},
700 {0x0000b178, 0x055f0540},
701 {0x0000b17c, 0x057f0560},
702 {0x0000b180, 0x06400641},
703 {0x0000b184, 0x0660065f},
704 {0x0000b188, 0x067e067f},
705 {0x0000b18c, 0x07410742},
706 {0x0000b190, 0x075f0740},
707 {0x0000b194, 0x077f0760},
708 {0x0000b198, 0x07800781},
709 {0x0000b19c, 0x07a0079f},
710 {0x0000b1a0, 0x07c107bf},
711 {0x0000b1a4, 0x000007c0},
712 {0x0000b1a8, 0x00000000},
713 {0x0000b1ac, 0x00000000},
714 {0x0000b1b0, 0x00000000},
715 {0x0000b1b4, 0x00000000},
716 {0x0000b1b8, 0x00000000},
717 {0x0000b1bc, 0x00000000},
718 {0x0000b1c0, 0x00000000},
719 {0x0000b1c4, 0x00000000},
720 {0x0000b1c8, 0x00000000},
721 {0x0000b1cc, 0x00000000},
722 {0x0000b1d0, 0x00000000},
723 {0x0000b1d4, 0x00000000},
724 {0x0000b1d8, 0x00000000},
725 {0x0000b1dc, 0x00000000},
726 {0x0000b1e0, 0x00000000},
727 {0x0000b1e4, 0x00000000},
728 {0x0000b1e8, 0x00000000},
729 {0x0000b1ec, 0x00000000},
730 {0x0000b1f0, 0x00000396},
731 {0x0000b1f4, 0x00000396},
732 {0x0000b1f8, 0x00000396},
733 {0x0000b1fc, 0x00000196},
734};
735
736static const u32 ar955x_1p0_baseband_core[][2] = { 477static const u32 ar955x_1p0_baseband_core[][2] = {
737 /* Addr allmodes */ 478 /* Addr allmodes */
738 {0x00009800, 0xafe68e30}, 479 {0x00009800, 0xafe68e30},
@@ -891,266 +632,6 @@ static const u32 ar955x_1p0_baseband_core[][2] = {
891 {0x0000c420, 0x00000000}, 632 {0x0000c420, 0x00000000},
892}; 633};
893 634
894static const u32 ar955x_1p0_common_wo_xlna_rx_gain_table[][2] = {
895 /* Addr allmodes */
896 {0x0000a000, 0x00010000},
897 {0x0000a004, 0x00030002},
898 {0x0000a008, 0x00050004},
899 {0x0000a00c, 0x00810080},
900 {0x0000a010, 0x00830082},
901 {0x0000a014, 0x01810180},
902 {0x0000a018, 0x01830182},
903 {0x0000a01c, 0x01850184},
904 {0x0000a020, 0x01890188},
905 {0x0000a024, 0x018b018a},
906 {0x0000a028, 0x018d018c},
907 {0x0000a02c, 0x03820190},
908 {0x0000a030, 0x03840383},
909 {0x0000a034, 0x03880385},
910 {0x0000a038, 0x038a0389},
911 {0x0000a03c, 0x038c038b},
912 {0x0000a040, 0x0390038d},
913 {0x0000a044, 0x03920391},
914 {0x0000a048, 0x03940393},
915 {0x0000a04c, 0x03960395},
916 {0x0000a050, 0x00000000},
917 {0x0000a054, 0x00000000},
918 {0x0000a058, 0x00000000},
919 {0x0000a05c, 0x00000000},
920 {0x0000a060, 0x00000000},
921 {0x0000a064, 0x00000000},
922 {0x0000a068, 0x00000000},
923 {0x0000a06c, 0x00000000},
924 {0x0000a070, 0x00000000},
925 {0x0000a074, 0x00000000},
926 {0x0000a078, 0x00000000},
927 {0x0000a07c, 0x00000000},
928 {0x0000a080, 0x29292929},
929 {0x0000a084, 0x29292929},
930 {0x0000a088, 0x29292929},
931 {0x0000a08c, 0x29292929},
932 {0x0000a090, 0x22292929},
933 {0x0000a094, 0x1d1d2222},
934 {0x0000a098, 0x0c111117},
935 {0x0000a09c, 0x00030303},
936 {0x0000a0a0, 0x00000000},
937 {0x0000a0a4, 0x00000000},
938 {0x0000a0a8, 0x00000000},
939 {0x0000a0ac, 0x00000000},
940 {0x0000a0b0, 0x00000000},
941 {0x0000a0b4, 0x00000000},
942 {0x0000a0b8, 0x00000000},
943 {0x0000a0bc, 0x00000000},
944 {0x0000a0c0, 0x001f0000},
945 {0x0000a0c4, 0x01000101},
946 {0x0000a0c8, 0x011e011f},
947 {0x0000a0cc, 0x011c011d},
948 {0x0000a0d0, 0x02030204},
949 {0x0000a0d4, 0x02010202},
950 {0x0000a0d8, 0x021f0200},
951 {0x0000a0dc, 0x0302021e},
952 {0x0000a0e0, 0x03000301},
953 {0x0000a0e4, 0x031e031f},
954 {0x0000a0e8, 0x0402031d},
955 {0x0000a0ec, 0x04000401},
956 {0x0000a0f0, 0x041e041f},
957 {0x0000a0f4, 0x0502041d},
958 {0x0000a0f8, 0x05000501},
959 {0x0000a0fc, 0x051e051f},
960 {0x0000a100, 0x06010602},
961 {0x0000a104, 0x061f0600},
962 {0x0000a108, 0x061d061e},
963 {0x0000a10c, 0x07020703},
964 {0x0000a110, 0x07000701},
965 {0x0000a114, 0x00000000},
966 {0x0000a118, 0x00000000},
967 {0x0000a11c, 0x00000000},
968 {0x0000a120, 0x00000000},
969 {0x0000a124, 0x00000000},
970 {0x0000a128, 0x00000000},
971 {0x0000a12c, 0x00000000},
972 {0x0000a130, 0x00000000},
973 {0x0000a134, 0x00000000},
974 {0x0000a138, 0x00000000},
975 {0x0000a13c, 0x00000000},
976 {0x0000a140, 0x001f0000},
977 {0x0000a144, 0x01000101},
978 {0x0000a148, 0x011e011f},
979 {0x0000a14c, 0x011c011d},
980 {0x0000a150, 0x02030204},
981 {0x0000a154, 0x02010202},
982 {0x0000a158, 0x021f0200},
983 {0x0000a15c, 0x0302021e},
984 {0x0000a160, 0x03000301},
985 {0x0000a164, 0x031e031f},
986 {0x0000a168, 0x0402031d},
987 {0x0000a16c, 0x04000401},
988 {0x0000a170, 0x041e041f},
989 {0x0000a174, 0x0502041d},
990 {0x0000a178, 0x05000501},
991 {0x0000a17c, 0x051e051f},
992 {0x0000a180, 0x06010602},
993 {0x0000a184, 0x061f0600},
994 {0x0000a188, 0x061d061e},
995 {0x0000a18c, 0x07020703},
996 {0x0000a190, 0x07000701},
997 {0x0000a194, 0x00000000},
998 {0x0000a198, 0x00000000},
999 {0x0000a19c, 0x00000000},
1000 {0x0000a1a0, 0x00000000},
1001 {0x0000a1a4, 0x00000000},
1002 {0x0000a1a8, 0x00000000},
1003 {0x0000a1ac, 0x00000000},
1004 {0x0000a1b0, 0x00000000},
1005 {0x0000a1b4, 0x00000000},
1006 {0x0000a1b8, 0x00000000},
1007 {0x0000a1bc, 0x00000000},
1008 {0x0000a1c0, 0x00000000},
1009 {0x0000a1c4, 0x00000000},
1010 {0x0000a1c8, 0x00000000},
1011 {0x0000a1cc, 0x00000000},
1012 {0x0000a1d0, 0x00000000},
1013 {0x0000a1d4, 0x00000000},
1014 {0x0000a1d8, 0x00000000},
1015 {0x0000a1dc, 0x00000000},
1016 {0x0000a1e0, 0x00000000},
1017 {0x0000a1e4, 0x00000000},
1018 {0x0000a1e8, 0x00000000},
1019 {0x0000a1ec, 0x00000000},
1020 {0x0000a1f0, 0x00000396},
1021 {0x0000a1f4, 0x00000396},
1022 {0x0000a1f8, 0x00000396},
1023 {0x0000a1fc, 0x00000196},
1024 {0x0000b000, 0x00010000},
1025 {0x0000b004, 0x00030002},
1026 {0x0000b008, 0x00050004},
1027 {0x0000b00c, 0x00810080},
1028 {0x0000b010, 0x00830082},
1029 {0x0000b014, 0x01810180},
1030 {0x0000b018, 0x01830182},
1031 {0x0000b01c, 0x01850184},
1032 {0x0000b020, 0x02810280},
1033 {0x0000b024, 0x02830282},
1034 {0x0000b028, 0x02850284},
1035 {0x0000b02c, 0x02890288},
1036 {0x0000b030, 0x028b028a},
1037 {0x0000b034, 0x0388028c},
1038 {0x0000b038, 0x038a0389},
1039 {0x0000b03c, 0x038c038b},
1040 {0x0000b040, 0x0390038d},
1041 {0x0000b044, 0x03920391},
1042 {0x0000b048, 0x03940393},
1043 {0x0000b04c, 0x03960395},
1044 {0x0000b050, 0x00000000},
1045 {0x0000b054, 0x00000000},
1046 {0x0000b058, 0x00000000},
1047 {0x0000b05c, 0x00000000},
1048 {0x0000b060, 0x00000000},
1049 {0x0000b064, 0x00000000},
1050 {0x0000b068, 0x00000000},
1051 {0x0000b06c, 0x00000000},
1052 {0x0000b070, 0x00000000},
1053 {0x0000b074, 0x00000000},
1054 {0x0000b078, 0x00000000},
1055 {0x0000b07c, 0x00000000},
1056 {0x0000b080, 0x32323232},
1057 {0x0000b084, 0x2f2f3232},
1058 {0x0000b088, 0x23282a2d},
1059 {0x0000b08c, 0x1c1e2123},
1060 {0x0000b090, 0x14171919},
1061 {0x0000b094, 0x0e0e1214},
1062 {0x0000b098, 0x03050707},
1063 {0x0000b09c, 0x00030303},
1064 {0x0000b0a0, 0x00000000},
1065 {0x0000b0a4, 0x00000000},
1066 {0x0000b0a8, 0x00000000},
1067 {0x0000b0ac, 0x00000000},
1068 {0x0000b0b0, 0x00000000},
1069 {0x0000b0b4, 0x00000000},
1070 {0x0000b0b8, 0x00000000},
1071 {0x0000b0bc, 0x00000000},
1072 {0x0000b0c0, 0x003f0020},
1073 {0x0000b0c4, 0x00400041},
1074 {0x0000b0c8, 0x0140005f},
1075 {0x0000b0cc, 0x0160015f},
1076 {0x0000b0d0, 0x017e017f},
1077 {0x0000b0d4, 0x02410242},
1078 {0x0000b0d8, 0x025f0240},
1079 {0x0000b0dc, 0x027f0260},
1080 {0x0000b0e0, 0x0341027e},
1081 {0x0000b0e4, 0x035f0340},
1082 {0x0000b0e8, 0x037f0360},
1083 {0x0000b0ec, 0x04400441},
1084 {0x0000b0f0, 0x0460045f},
1085 {0x0000b0f4, 0x0541047f},
1086 {0x0000b0f8, 0x055f0540},
1087 {0x0000b0fc, 0x057f0560},
1088 {0x0000b100, 0x06400641},
1089 {0x0000b104, 0x0660065f},
1090 {0x0000b108, 0x067e067f},
1091 {0x0000b10c, 0x07410742},
1092 {0x0000b110, 0x075f0740},
1093 {0x0000b114, 0x077f0760},
1094 {0x0000b118, 0x07800781},
1095 {0x0000b11c, 0x07a0079f},
1096 {0x0000b120, 0x07c107bf},
1097 {0x0000b124, 0x000007c0},
1098 {0x0000b128, 0x00000000},
1099 {0x0000b12c, 0x00000000},
1100 {0x0000b130, 0x00000000},
1101 {0x0000b134, 0x00000000},
1102 {0x0000b138, 0x00000000},
1103 {0x0000b13c, 0x00000000},
1104 {0x0000b140, 0x003f0020},
1105 {0x0000b144, 0x00400041},
1106 {0x0000b148, 0x0140005f},
1107 {0x0000b14c, 0x0160015f},
1108 {0x0000b150, 0x017e017f},
1109 {0x0000b154, 0x02410242},
1110 {0x0000b158, 0x025f0240},
1111 {0x0000b15c, 0x027f0260},
1112 {0x0000b160, 0x0341027e},
1113 {0x0000b164, 0x035f0340},
1114 {0x0000b168, 0x037f0360},
1115 {0x0000b16c, 0x04400441},
1116 {0x0000b170, 0x0460045f},
1117 {0x0000b174, 0x0541047f},
1118 {0x0000b178, 0x055f0540},
1119 {0x0000b17c, 0x057f0560},
1120 {0x0000b180, 0x06400641},
1121 {0x0000b184, 0x0660065f},
1122 {0x0000b188, 0x067e067f},
1123 {0x0000b18c, 0x07410742},
1124 {0x0000b190, 0x075f0740},
1125 {0x0000b194, 0x077f0760},
1126 {0x0000b198, 0x07800781},
1127 {0x0000b19c, 0x07a0079f},
1128 {0x0000b1a0, 0x07c107bf},
1129 {0x0000b1a4, 0x000007c0},
1130 {0x0000b1a8, 0x00000000},
1131 {0x0000b1ac, 0x00000000},
1132 {0x0000b1b0, 0x00000000},
1133 {0x0000b1b4, 0x00000000},
1134 {0x0000b1b8, 0x00000000},
1135 {0x0000b1bc, 0x00000000},
1136 {0x0000b1c0, 0x00000000},
1137 {0x0000b1c4, 0x00000000},
1138 {0x0000b1c8, 0x00000000},
1139 {0x0000b1cc, 0x00000000},
1140 {0x0000b1d0, 0x00000000},
1141 {0x0000b1d4, 0x00000000},
1142 {0x0000b1d8, 0x00000000},
1143 {0x0000b1dc, 0x00000000},
1144 {0x0000b1e0, 0x00000000},
1145 {0x0000b1e4, 0x00000000},
1146 {0x0000b1e8, 0x00000000},
1147 {0x0000b1ec, 0x00000000},
1148 {0x0000b1f0, 0x00000396},
1149 {0x0000b1f4, 0x00000396},
1150 {0x0000b1f8, 0x00000396},
1151 {0x0000b1fc, 0x00000196},
1152};
1153
1154static const u32 ar955x_1p0_soc_preamble[][2] = { 635static const u32 ar955x_1p0_soc_preamble[][2] = {
1155 /* Addr allmodes */ 636 /* Addr allmodes */
1156 {0x00007000, 0x00000000}, 637 {0x00007000, 0x00000000},
@@ -1263,11 +744,6 @@ static const u32 ar955x_1p0_modes_no_xpa_tx_gain_table[][9] = {
1263 {0x00016848, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401}, 744 {0x00016848, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
1264}; 745};
1265 746
1266static const u32 ar955x_1p0_soc_postamble[][5] = {
1267 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1268 {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
1269};
1270
1271static const u32 ar955x_1p0_modes_fast_clock[][3] = { 747static const u32 ar955x_1p0_modes_fast_clock[][3] = {
1272 /* Addr 5G_HT20 5G_HT40 */ 748 /* Addr 5G_HT20 5G_HT40 */
1273 {0x00001030, 0x00000268, 0x000004d0}, 749 {0x00001030, 0x00000268, 0x000004d0},
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
index a8c757b6124f..10d4a6cb1c3b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
@@ -20,6 +20,12 @@
20 20
21/* AR9565 1.0 */ 21/* AR9565 1.0 */
22 22
23#define ar9565_1p0_mac_postamble ar9331_1p1_mac_postamble
24
25#define ar9565_1p0_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table
26
27#define ar9565_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
28
23static const u32 ar9565_1p0_mac_core[][2] = { 29static const u32 ar9565_1p0_mac_core[][2] = {
24 /* Addr allmodes */ 30 /* Addr allmodes */
25 {0x00000008, 0x00000000}, 31 {0x00000008, 0x00000000},
@@ -182,18 +188,6 @@ static const u32 ar9565_1p0_mac_core[][2] = {
182 {0x000083d0, 0x800301ff}, 188 {0x000083d0, 0x800301ff},
183}; 189};
184 190
185static const u32 ar9565_1p0_mac_postamble[][5] = {
186 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
187 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
188 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
189 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
190 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
191 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
192 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
193 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
194 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
195};
196
197static const u32 ar9565_1p0_baseband_core[][2] = { 191static const u32 ar9565_1p0_baseband_core[][2] = {
198 /* Addr allmodes */ 192 /* Addr allmodes */
199 {0x00009800, 0xafe68e30}, 193 {0x00009800, 0xafe68e30},
@@ -711,66 +705,6 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
711 {0x0000b1fc, 0x00000196}, 705 {0x0000b1fc, 0x00000196},
712}; 706};
713 707
714static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = {
715 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
716 {0x0000a2dc, 0xfc0a9380, 0xfc0a9380, 0xfdab5b52, 0xfdab5b52},
717 {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84},
718 {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000},
719 {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000},
720 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
721 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
722 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
723 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
724 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
725 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
726 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
727 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
728 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
729 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
730 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
731 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
732 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
733 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
734 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
735 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
736 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
737 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
738 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
739 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
740 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
741 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
742 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
743 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
744 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
745 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
746 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
747 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
748 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
749 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
750 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
751 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
752 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
753 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
754 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
755 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
756 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
757 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
758 {0x0000a614, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
759 {0x0000a618, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
760 {0x0000a61c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
761 {0x0000a620, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
762 {0x0000a624, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
763 {0x0000a628, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
764 {0x0000a62c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
765 {0x0000a630, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
766 {0x0000a634, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
767 {0x0000a638, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
768 {0x0000a63c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
769 {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
770 {0x00016048, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
771 {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
772};
773
774static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = { 708static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = {
775 /* Addr allmodes */ 709 /* Addr allmodes */
776 {0x00018c00, 0x18212ede}, 710 {0x00018c00, 0x18212ede},
@@ -1231,11 +1165,4 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = {
1231 {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1165 {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1232}; 1166};
1233 1167
1234static const u32 ar9565_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
1235 /* Addr allmodes */
1236 {0x0000a398, 0x00000000},
1237 {0x0000a39c, 0x6f7f0301},
1238 {0x0000a3a0, 0xca9228ee},
1239};
1240
1241#endif /* INITVALS_9565_1P0_H */ 1168#endif /* INITVALS_9565_1P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
new file mode 100644
index 000000000000..56810539971e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef INITVALS_9565_1P1_H
19#define INITVALS_9565_1P1_H
20
21/* AR9565 1.1 */
22
23#define ar9565_1p1_mac_core ar9565_1p0_mac_core
24
25#define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble
26
27#define ar9565_1p1_baseband_core ar9565_1p0_baseband_core
28
29#define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble
30
31#define ar9565_1p1_radio_core ar9565_1p0_radio_core
32
33#define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble
34
35#define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble
36
37#define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table
38
39#define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table
40
41#define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1
42
43#define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock
44
45#define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table
46
47#define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table
48
49#define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table
50
51#define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table
52
53#define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484
54
55static const u32 ar9565_1p1_radio_postamble[][5] = {
56 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
57 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
58 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
59 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
60 {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000},
61 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
62};
63
64#endif /* INITVALS_9565_1P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
index bdee2ed67219..e6aec2c0207f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -20,18 +20,34 @@
20 20
21/* AR9580 1.0 */ 21/* AR9580 1.0 */
22 22
23#define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble
24
25#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
26
27#define ar9580_1p0_radio_core ar9300_2p2_radio_core
28
29#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
30
31#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
32
33#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
34
35#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
36
23#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 37#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
24 38
39#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
40
25static const u32 ar9580_1p0_radio_postamble[][5] = { 41static const u32 ar9580_1p0_radio_postamble[][5] = {
26 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 42 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
27 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, 43 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
28 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, 44 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
29 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, 45 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
30 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 46 {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
31 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 47 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
32 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 48 {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
33 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 49 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
34 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 50 {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
35 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 51 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
36}; 52};
37 53
@@ -41,12 +57,10 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
41 {0x00009804, 0xfd14e000}, 57 {0x00009804, 0xfd14e000},
42 {0x00009808, 0x9c0a9f6b}, 58 {0x00009808, 0x9c0a9f6b},
43 {0x0000980c, 0x04900000}, 59 {0x0000980c, 0x04900000},
44 {0x00009814, 0x3280c00a},
45 {0x00009818, 0x00000000},
46 {0x0000981c, 0x00020028}, 60 {0x0000981c, 0x00020028},
47 {0x00009834, 0x6400a290}, 61 {0x00009834, 0x6400a190},
48 {0x00009838, 0x0108ecff}, 62 {0x00009838, 0x0108ecff},
49 {0x0000983c, 0x0d000600}, 63 {0x0000983c, 0x14000600},
50 {0x00009880, 0x201fff00}, 64 {0x00009880, 0x201fff00},
51 {0x00009884, 0x00001042}, 65 {0x00009884, 0x00001042},
52 {0x000098a4, 0x00200400}, 66 {0x000098a4, 0x00200400},
@@ -67,7 +81,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
67 {0x00009d04, 0x40206c10}, 81 {0x00009d04, 0x40206c10},
68 {0x00009d08, 0x009c4060}, 82 {0x00009d08, 0x009c4060},
69 {0x00009d0c, 0x9883800a}, 83 {0x00009d0c, 0x9883800a},
70 {0x00009d10, 0x01834061}, 84 {0x00009d10, 0x01884061},
71 {0x00009d14, 0x00c0040b}, 85 {0x00009d14, 0x00c0040b},
72 {0x00009d18, 0x00000000}, 86 {0x00009d18, 0x00000000},
73 {0x00009e08, 0x0038230c}, 87 {0x00009e08, 0x0038230c},
@@ -198,8 +212,6 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
198 {0x0000c420, 0x00000000}, 212 {0x0000c420, 0x00000000},
199}; 213};
200 214
201#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
202
203static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { 215static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
204 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 216 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
205 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 217 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -306,7 +318,112 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
306 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 318 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
307}; 319};
308 320
309#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table 321static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
322 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
323 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
324 {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
325 {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
326 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
327 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
328 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
329 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
330 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
331 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
332 {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
333 {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
334 {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
335 {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
336 {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
337 {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
338 {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
339 {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
340 {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
341 {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
342 {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
343 {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
344 {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
345 {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
346 {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
347 {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
348 {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
349 {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
350 {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
351 {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
352 {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
353 {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
354 {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
355 {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
356 {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
357 {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
358 {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
359 {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
360 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
361 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
362 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
363 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
364 {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
365 {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
366 {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
367 {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
368 {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
369 {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
370 {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
371 {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
372 {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
373 {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
374 {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
375 {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
376 {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
377 {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
378 {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
379 {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
380 {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
381 {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
382 {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
383 {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
384 {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
385 {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
386 {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
387 {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
388 {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
389 {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
390 {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
391 {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
392 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
393 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
394 {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
395 {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
396 {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
397 {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
398 {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
399 {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
400 {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
401 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
402 {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
403 {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
404 {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
405 {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
406 {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
407 {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
408 {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
409 {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
410 {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
411 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
412 {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
413 {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
414 {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
415 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
416 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
417 {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
418 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
419 {0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408},
420 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
421 {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
422 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
423 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
424 {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
425 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
426};
310 427
311static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { 428static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
312 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 429 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
@@ -414,8 +531,6 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
414 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 531 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
415}; 532};
416 533
417#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
418
419static const u32 ar9580_1p0_mac_core[][2] = { 534static const u32 ar9580_1p0_mac_core[][2] = {
420 /* Addr allmodes */ 535 /* Addr allmodes */
421 {0x00000008, 0x00000000}, 536 {0x00000008, 0x00000000},
@@ -679,14 +794,6 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
679 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 794 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
680}; 795};
681 796
682#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
683
684#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
685
686#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
687
688#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
689
690static const u32 ar9580_1p0_type6_tx_gain_table[][5] = { 797static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
691 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 798 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
692 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, 799 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
@@ -761,165 +868,271 @@ static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
761 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 868 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
762}; 869};
763 870
764static const u32 ar9580_1p0_soc_preamble[][2] = { 871static const u32 ar9580_1p0_rx_gain_table[][2] = {
765 /* Addr allmodes */ 872 /* Addr allmodes */
766 {0x000040a4, 0x00a0c1c9}, 873 {0x0000a000, 0x00010000},
767 {0x00007008, 0x00000000}, 874 {0x0000a004, 0x00030002},
768 {0x00007020, 0x00000000}, 875 {0x0000a008, 0x00050004},
769 {0x00007034, 0x00000002}, 876 {0x0000a00c, 0x00810080},
770 {0x00007038, 0x000004c2}, 877 {0x0000a010, 0x00830082},
771 {0x00007048, 0x00000008}, 878 {0x0000a014, 0x01810180},
772}; 879 {0x0000a018, 0x01830182},
773 880 {0x0000a01c, 0x01850184},
774#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0 881 {0x0000a020, 0x01890188},
775 882 {0x0000a024, 0x018b018a},
776static const u32 ar9580_1p0_radio_core[][2] = { 883 {0x0000a028, 0x018d018c},
777 /* Addr allmodes */ 884 {0x0000a02c, 0x01910190},
778 {0x00016000, 0x36db6db6}, 885 {0x0000a030, 0x01930192},
779 {0x00016004, 0x6db6db40}, 886 {0x0000a034, 0x01950194},
780 {0x00016008, 0x73f00000}, 887 {0x0000a038, 0x038a0196},
781 {0x0001600c, 0x00000000}, 888 {0x0000a03c, 0x038c038b},
782 {0x00016040, 0x7f80fff8}, 889 {0x0000a040, 0x0390038d},
783 {0x0001604c, 0x76d005b5}, 890 {0x0000a044, 0x03920391},
784 {0x00016050, 0x556cf031}, 891 {0x0000a048, 0x03940393},
785 {0x00016054, 0x13449440}, 892 {0x0000a04c, 0x03960395},
786 {0x00016058, 0x0c51c92c}, 893 {0x0000a050, 0x00000000},
787 {0x0001605c, 0x3db7fffc}, 894 {0x0000a054, 0x00000000},
788 {0x00016060, 0xfffffffc}, 895 {0x0000a058, 0x00000000},
789 {0x00016064, 0x000f0278}, 896 {0x0000a05c, 0x00000000},
790 {0x0001606c, 0x6db60000}, 897 {0x0000a060, 0x00000000},
791 {0x00016080, 0x00000000}, 898 {0x0000a064, 0x00000000},
792 {0x00016084, 0x0e48048c}, 899 {0x0000a068, 0x00000000},
793 {0x00016088, 0x54214514}, 900 {0x0000a06c, 0x00000000},
794 {0x0001608c, 0x119f481e}, 901 {0x0000a070, 0x00000000},
795 {0x00016090, 0x24926490}, 902 {0x0000a074, 0x00000000},
796 {0x00016098, 0xd2888888}, 903 {0x0000a078, 0x00000000},
797 {0x000160a0, 0x0a108ffe}, 904 {0x0000a07c, 0x00000000},
798 {0x000160a4, 0x812fc370}, 905 {0x0000a080, 0x22222229},
799 {0x000160a8, 0x423c8000}, 906 {0x0000a084, 0x1d1d1d1d},
800 {0x000160b4, 0x92480080}, 907 {0x0000a088, 0x1d1d1d1d},
801 {0x000160c0, 0x00adb6d0}, 908 {0x0000a08c, 0x1d1d1d1d},
802 {0x000160c4, 0x6db6db60}, 909 {0x0000a090, 0x171d1d1d},
803 {0x000160c8, 0x6db6db6c}, 910 {0x0000a094, 0x11111717},
804 {0x000160cc, 0x01e6c000}, 911 {0x0000a098, 0x00030311},
805 {0x00016100, 0x3fffbe01}, 912 {0x0000a09c, 0x00000000},
806 {0x00016104, 0xfff80000}, 913 {0x0000a0a0, 0x00000000},
807 {0x00016108, 0x00080010}, 914 {0x0000a0a4, 0x00000000},
808 {0x00016144, 0x02084080}, 915 {0x0000a0a8, 0x00000000},
809 {0x00016148, 0x00000000}, 916 {0x0000a0ac, 0x00000000},
810 {0x00016280, 0x058a0001}, 917 {0x0000a0b0, 0x00000000},
811 {0x00016284, 0x3d840208}, 918 {0x0000a0b4, 0x00000000},
812 {0x00016288, 0x05a20408}, 919 {0x0000a0b8, 0x00000000},
813 {0x0001628c, 0x00038c07}, 920 {0x0000a0bc, 0x00000000},
814 {0x00016290, 0x00000004}, 921 {0x0000a0c0, 0x001f0000},
815 {0x00016294, 0x458aa14f}, 922 {0x0000a0c4, 0x01000101},
816 {0x00016380, 0x00000000}, 923 {0x0000a0c8, 0x011e011f},
817 {0x00016384, 0x00000000}, 924 {0x0000a0cc, 0x011c011d},
818 {0x00016388, 0x00800700}, 925 {0x0000a0d0, 0x02030204},
819 {0x0001638c, 0x00800700}, 926 {0x0000a0d4, 0x02010202},
820 {0x00016390, 0x00800700}, 927 {0x0000a0d8, 0x021f0200},
821 {0x00016394, 0x00000000}, 928 {0x0000a0dc, 0x0302021e},
822 {0x00016398, 0x00000000}, 929 {0x0000a0e0, 0x03000301},
823 {0x0001639c, 0x00000000}, 930 {0x0000a0e4, 0x031e031f},
824 {0x000163a0, 0x00000001}, 931 {0x0000a0e8, 0x0402031d},
825 {0x000163a4, 0x00000001}, 932 {0x0000a0ec, 0x04000401},
826 {0x000163a8, 0x00000000}, 933 {0x0000a0f0, 0x041e041f},
827 {0x000163ac, 0x00000000}, 934 {0x0000a0f4, 0x0502041d},
828 {0x000163b0, 0x00000000}, 935 {0x0000a0f8, 0x05000501},
829 {0x000163b4, 0x00000000}, 936 {0x0000a0fc, 0x051e051f},
830 {0x000163b8, 0x00000000}, 937 {0x0000a100, 0x06010602},
831 {0x000163bc, 0x00000000}, 938 {0x0000a104, 0x061f0600},
832 {0x000163c0, 0x000000a0}, 939 {0x0000a108, 0x061d061e},
833 {0x000163c4, 0x000c0000}, 940 {0x0000a10c, 0x07020703},
834 {0x000163c8, 0x14021402}, 941 {0x0000a110, 0x07000701},
835 {0x000163cc, 0x00001402}, 942 {0x0000a114, 0x00000000},
836 {0x000163d0, 0x00000000}, 943 {0x0000a118, 0x00000000},
837 {0x000163d4, 0x00000000}, 944 {0x0000a11c, 0x00000000},
838 {0x00016400, 0x36db6db6}, 945 {0x0000a120, 0x00000000},
839 {0x00016404, 0x6db6db40}, 946 {0x0000a124, 0x00000000},
840 {0x00016408, 0x73f00000}, 947 {0x0000a128, 0x00000000},
841 {0x0001640c, 0x00000000}, 948 {0x0000a12c, 0x00000000},
842 {0x00016440, 0x7f80fff8}, 949 {0x0000a130, 0x00000000},
843 {0x0001644c, 0x76d005b5}, 950 {0x0000a134, 0x00000000},
844 {0x00016450, 0x556cf031}, 951 {0x0000a138, 0x00000000},
845 {0x00016454, 0x13449440}, 952 {0x0000a13c, 0x00000000},
846 {0x00016458, 0x0c51c92c}, 953 {0x0000a140, 0x001f0000},
847 {0x0001645c, 0x3db7fffc}, 954 {0x0000a144, 0x01000101},
848 {0x00016460, 0xfffffffc}, 955 {0x0000a148, 0x011e011f},
849 {0x00016464, 0x000f0278}, 956 {0x0000a14c, 0x011c011d},
850 {0x0001646c, 0x6db60000}, 957 {0x0000a150, 0x02030204},
851 {0x00016500, 0x3fffbe01}, 958 {0x0000a154, 0x02010202},
852 {0x00016504, 0xfff80000}, 959 {0x0000a158, 0x021f0200},
853 {0x00016508, 0x00080010}, 960 {0x0000a15c, 0x0302021e},
854 {0x00016544, 0x02084080}, 961 {0x0000a160, 0x03000301},
855 {0x00016548, 0x00000000}, 962 {0x0000a164, 0x031e031f},
856 {0x00016780, 0x00000000}, 963 {0x0000a168, 0x0402031d},
857 {0x00016784, 0x00000000}, 964 {0x0000a16c, 0x04000401},
858 {0x00016788, 0x00800700}, 965 {0x0000a170, 0x041e041f},
859 {0x0001678c, 0x00800700}, 966 {0x0000a174, 0x0502041d},
860 {0x00016790, 0x00800700}, 967 {0x0000a178, 0x05000501},
861 {0x00016794, 0x00000000}, 968 {0x0000a17c, 0x051e051f},
862 {0x00016798, 0x00000000}, 969 {0x0000a180, 0x06010602},
863 {0x0001679c, 0x00000000}, 970 {0x0000a184, 0x061f0600},
864 {0x000167a0, 0x00000001}, 971 {0x0000a188, 0x061d061e},
865 {0x000167a4, 0x00000001}, 972 {0x0000a18c, 0x07020703},
866 {0x000167a8, 0x00000000}, 973 {0x0000a190, 0x07000701},
867 {0x000167ac, 0x00000000}, 974 {0x0000a194, 0x00000000},
868 {0x000167b0, 0x00000000}, 975 {0x0000a198, 0x00000000},
869 {0x000167b4, 0x00000000}, 976 {0x0000a19c, 0x00000000},
870 {0x000167b8, 0x00000000}, 977 {0x0000a1a0, 0x00000000},
871 {0x000167bc, 0x00000000}, 978 {0x0000a1a4, 0x00000000},
872 {0x000167c0, 0x000000a0}, 979 {0x0000a1a8, 0x00000000},
873 {0x000167c4, 0x000c0000}, 980 {0x0000a1ac, 0x00000000},
874 {0x000167c8, 0x14021402}, 981 {0x0000a1b0, 0x00000000},
875 {0x000167cc, 0x00001402}, 982 {0x0000a1b4, 0x00000000},
876 {0x000167d0, 0x00000000}, 983 {0x0000a1b8, 0x00000000},
877 {0x000167d4, 0x00000000}, 984 {0x0000a1bc, 0x00000000},
878 {0x00016800, 0x36db6db6}, 985 {0x0000a1c0, 0x00000000},
879 {0x00016804, 0x6db6db40}, 986 {0x0000a1c4, 0x00000000},
880 {0x00016808, 0x73f00000}, 987 {0x0000a1c8, 0x00000000},
881 {0x0001680c, 0x00000000}, 988 {0x0000a1cc, 0x00000000},
882 {0x00016840, 0x7f80fff8}, 989 {0x0000a1d0, 0x00000000},
883 {0x0001684c, 0x76d005b5}, 990 {0x0000a1d4, 0x00000000},
884 {0x00016850, 0x556cf031}, 991 {0x0000a1d8, 0x00000000},
885 {0x00016854, 0x13449440}, 992 {0x0000a1dc, 0x00000000},
886 {0x00016858, 0x0c51c92c}, 993 {0x0000a1e0, 0x00000000},
887 {0x0001685c, 0x3db7fffc}, 994 {0x0000a1e4, 0x00000000},
888 {0x00016860, 0xfffffffc}, 995 {0x0000a1e8, 0x00000000},
889 {0x00016864, 0x000f0278}, 996 {0x0000a1ec, 0x00000000},
890 {0x0001686c, 0x6db60000}, 997 {0x0000a1f0, 0x00000396},
891 {0x00016900, 0x3fffbe01}, 998 {0x0000a1f4, 0x00000396},
892 {0x00016904, 0xfff80000}, 999 {0x0000a1f8, 0x00000396},
893 {0x00016908, 0x00080010}, 1000 {0x0000a1fc, 0x00000196},
894 {0x00016944, 0x02084080}, 1001 {0x0000b000, 0x00010000},
895 {0x00016948, 0x00000000}, 1002 {0x0000b004, 0x00030002},
896 {0x00016b80, 0x00000000}, 1003 {0x0000b008, 0x00050004},
897 {0x00016b84, 0x00000000}, 1004 {0x0000b00c, 0x00810080},
898 {0x00016b88, 0x00800700}, 1005 {0x0000b010, 0x00830082},
899 {0x00016b8c, 0x00800700}, 1006 {0x0000b014, 0x01810180},
900 {0x00016b90, 0x00800700}, 1007 {0x0000b018, 0x01830182},
901 {0x00016b94, 0x00000000}, 1008 {0x0000b01c, 0x01850184},
902 {0x00016b98, 0x00000000}, 1009 {0x0000b020, 0x02810280},
903 {0x00016b9c, 0x00000000}, 1010 {0x0000b024, 0x02830282},
904 {0x00016ba0, 0x00000001}, 1011 {0x0000b028, 0x02850284},
905 {0x00016ba4, 0x00000001}, 1012 {0x0000b02c, 0x02890288},
906 {0x00016ba8, 0x00000000}, 1013 {0x0000b030, 0x028b028a},
907 {0x00016bac, 0x00000000}, 1014 {0x0000b034, 0x0388028c},
908 {0x00016bb0, 0x00000000}, 1015 {0x0000b038, 0x038a0389},
909 {0x00016bb4, 0x00000000}, 1016 {0x0000b03c, 0x038c038b},
910 {0x00016bb8, 0x00000000}, 1017 {0x0000b040, 0x0390038d},
911 {0x00016bbc, 0x00000000}, 1018 {0x0000b044, 0x03920391},
912 {0x00016bc0, 0x000000a0}, 1019 {0x0000b048, 0x03940393},
913 {0x00016bc4, 0x000c0000}, 1020 {0x0000b04c, 0x03960395},
914 {0x00016bc8, 0x14021402}, 1021 {0x0000b050, 0x00000000},
915 {0x00016bcc, 0x00001402}, 1022 {0x0000b054, 0x00000000},
916 {0x00016bd0, 0x00000000}, 1023 {0x0000b058, 0x00000000},
917 {0x00016bd4, 0x00000000}, 1024 {0x0000b05c, 0x00000000},
1025 {0x0000b060, 0x00000000},
1026 {0x0000b064, 0x00000000},
1027 {0x0000b068, 0x00000000},
1028 {0x0000b06c, 0x00000000},
1029 {0x0000b070, 0x00000000},
1030 {0x0000b074, 0x00000000},
1031 {0x0000b078, 0x00000000},
1032 {0x0000b07c, 0x00000000},
1033 {0x0000b080, 0x23232323},
1034 {0x0000b084, 0x21232323},
1035 {0x0000b088, 0x19191c1e},
1036 {0x0000b08c, 0x12141417},
1037 {0x0000b090, 0x07070e0e},
1038 {0x0000b094, 0x03030305},
1039 {0x0000b098, 0x00000003},
1040 {0x0000b09c, 0x00000000},
1041 {0x0000b0a0, 0x00000000},
1042 {0x0000b0a4, 0x00000000},
1043 {0x0000b0a8, 0x00000000},
1044 {0x0000b0ac, 0x00000000},
1045 {0x0000b0b0, 0x00000000},
1046 {0x0000b0b4, 0x00000000},
1047 {0x0000b0b8, 0x00000000},
1048 {0x0000b0bc, 0x00000000},
1049 {0x0000b0c0, 0x003f0020},
1050 {0x0000b0c4, 0x00400041},
1051 {0x0000b0c8, 0x0140005f},
1052 {0x0000b0cc, 0x0160015f},
1053 {0x0000b0d0, 0x017e017f},
1054 {0x0000b0d4, 0x02410242},
1055 {0x0000b0d8, 0x025f0240},
1056 {0x0000b0dc, 0x027f0260},
1057 {0x0000b0e0, 0x0341027e},
1058 {0x0000b0e4, 0x035f0340},
1059 {0x0000b0e8, 0x037f0360},
1060 {0x0000b0ec, 0x04400441},
1061 {0x0000b0f0, 0x0460045f},
1062 {0x0000b0f4, 0x0541047f},
1063 {0x0000b0f8, 0x055f0540},
1064 {0x0000b0fc, 0x057f0560},
1065 {0x0000b100, 0x06400641},
1066 {0x0000b104, 0x0660065f},
1067 {0x0000b108, 0x067e067f},
1068 {0x0000b10c, 0x07410742},
1069 {0x0000b110, 0x075f0740},
1070 {0x0000b114, 0x077f0760},
1071 {0x0000b118, 0x07800781},
1072 {0x0000b11c, 0x07a0079f},
1073 {0x0000b120, 0x07c107bf},
1074 {0x0000b124, 0x000007c0},
1075 {0x0000b128, 0x00000000},
1076 {0x0000b12c, 0x00000000},
1077 {0x0000b130, 0x00000000},
1078 {0x0000b134, 0x00000000},
1079 {0x0000b138, 0x00000000},
1080 {0x0000b13c, 0x00000000},
1081 {0x0000b140, 0x003f0020},
1082 {0x0000b144, 0x00400041},
1083 {0x0000b148, 0x0140005f},
1084 {0x0000b14c, 0x0160015f},
1085 {0x0000b150, 0x017e017f},
1086 {0x0000b154, 0x02410242},
1087 {0x0000b158, 0x025f0240},
1088 {0x0000b15c, 0x027f0260},
1089 {0x0000b160, 0x0341027e},
1090 {0x0000b164, 0x035f0340},
1091 {0x0000b168, 0x037f0360},
1092 {0x0000b16c, 0x04400441},
1093 {0x0000b170, 0x0460045f},
1094 {0x0000b174, 0x0541047f},
1095 {0x0000b178, 0x055f0540},
1096 {0x0000b17c, 0x057f0560},
1097 {0x0000b180, 0x06400641},
1098 {0x0000b184, 0x0660065f},
1099 {0x0000b188, 0x067e067f},
1100 {0x0000b18c, 0x07410742},
1101 {0x0000b190, 0x075f0740},
1102 {0x0000b194, 0x077f0760},
1103 {0x0000b198, 0x07800781},
1104 {0x0000b19c, 0x07a0079f},
1105 {0x0000b1a0, 0x07c107bf},
1106 {0x0000b1a4, 0x000007c0},
1107 {0x0000b1a8, 0x00000000},
1108 {0x0000b1ac, 0x00000000},
1109 {0x0000b1b0, 0x00000000},
1110 {0x0000b1b4, 0x00000000},
1111 {0x0000b1b8, 0x00000000},
1112 {0x0000b1bc, 0x00000000},
1113 {0x0000b1c0, 0x00000000},
1114 {0x0000b1c4, 0x00000000},
1115 {0x0000b1c8, 0x00000000},
1116 {0x0000b1cc, 0x00000000},
1117 {0x0000b1d0, 0x00000000},
1118 {0x0000b1d4, 0x00000000},
1119 {0x0000b1d8, 0x00000000},
1120 {0x0000b1dc, 0x00000000},
1121 {0x0000b1e0, 0x00000000},
1122 {0x0000b1e4, 0x00000000},
1123 {0x0000b1e8, 0x00000000},
1124 {0x0000b1ec, 0x00000000},
1125 {0x0000b1f0, 0x00000396},
1126 {0x0000b1f4, 0x00000396},
1127 {0x0000b1f8, 0x00000396},
1128 {0x0000b1fc, 0x00000196},
918}; 1129};
919 1130
920static const u32 ar9580_1p0_baseband_postamble[][5] = { 1131static const u32 ar9580_1p0_baseband_postamble[][5] = {
921 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 1132 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
922 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 1133 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
1134 {0x00009814, 0x3280c00a, 0x3280c00a, 0x3280c00a, 0x3280c00a},
1135 {0x00009818, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
923 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, 1136 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
924 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 1137 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
925 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 1138 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
@@ -956,7 +1169,7 @@ static const u32 ar9580_1p0_baseband_postamble[][5] = {
956 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 1169 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
957 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 1170 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
958 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 1171 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
959 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 1172 {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
960 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 1173 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
961 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1174 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
962 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, 1175 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
@@ -994,4 +1207,13 @@ static const u32 ar9580_1p0_pcie_phy_pll_on_clkreq[][2] = {
994 {0x00004044, 0x00000000}, 1207 {0x00004044, 0x00000000},
995}; 1208};
996 1209
1210static const u32 ar9580_1p0_baseband_postamble_dfs_channel[][3] = {
1211 /* Addr 5G 2G */
1212 {0x00009814, 0x3400c00f, 0x3400c00f},
1213 {0x00009824, 0x5ac668d0, 0x5ac668d0},
1214 {0x00009828, 0x06903080, 0x06903080},
1215 {0x00009e0c, 0x6d4000e2, 0x6d4000e2},
1216 {0x00009e14, 0x37b9625e, 0x37b9625e},
1217};
1218
997#endif /* INITVALS_9580_1P0_H */ 1219#endif /* INITVALS_9580_1P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 60a5da53668f..b5ac32cfbeb8 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -27,40 +27,15 @@
27#include "common.h" 27#include "common.h"
28#include "mci.h" 28#include "mci.h"
29#include "dfs.h" 29#include "dfs.h"
30 30#include "spectral.h"
31/*
32 * Header for the ath9k.ko driver core *only* -- hw code nor any other driver
33 * should rely on this file or its contents.
34 */
35 31
36struct ath_node; 32struct ath_node;
33struct ath_rate_table;
37 34
38/* Macro to expand scalars to 64-bit objects */ 35extern struct ieee80211_ops ath9k_ops;
39 36extern int ath9k_modparam_nohwcrypt;
40#define ito64(x) (sizeof(x) == 1) ? \ 37extern int led_blink;
41 (((unsigned long long int)(x)) & (0xff)) : \ 38extern bool is_ath9k_unloaded;
42 (sizeof(x) == 2) ? \
43 (((unsigned long long int)(x)) & 0xffff) : \
44 ((sizeof(x) == 4) ? \
45 (((unsigned long long int)(x)) & 0xffffffff) : \
46 (unsigned long long int)(x))
47
48/* increment with wrap-around */
49#define INCR(_l, _sz) do { \
50 (_l)++; \
51 (_l) &= ((_sz) - 1); \
52 } while (0)
53
54/* decrement with wrap-around */
55#define DECR(_l, _sz) do { \
56 (_l)--; \
57 (_l) &= ((_sz) - 1); \
58 } while (0)
59
60#define TSF_TO_TU(_h,_l) \
61 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
62
63#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
64 39
65struct ath_config { 40struct ath_config {
66 u16 txpowlimit; 41 u16 txpowlimit;
@@ -70,6 +45,17 @@ struct ath_config {
70/* Descriptor Management */ 45/* Descriptor Management */
71/*************************/ 46/*************************/
72 47
48#define ATH_TXSTATUS_RING_SIZE 512
49
50/* Macro to expand scalars to 64-bit objects */
51#define ito64(x) (sizeof(x) == 1) ? \
52 (((unsigned long long int)(x)) & (0xff)) : \
53 (sizeof(x) == 2) ? \
54 (((unsigned long long int)(x)) & 0xffff) : \
55 ((sizeof(x) == 4) ? \
56 (((unsigned long long int)(x)) & 0xffffffff) : \
57 (unsigned long long int)(x))
58
73#define ATH_TXBUF_RESET(_bf) do { \ 59#define ATH_TXBUF_RESET(_bf) do { \
74 (_bf)->bf_lastbf = NULL; \ 60 (_bf)->bf_lastbf = NULL; \
75 (_bf)->bf_next = NULL; \ 61 (_bf)->bf_next = NULL; \
@@ -77,23 +63,6 @@ struct ath_config {
77 sizeof(struct ath_buf_state)); \ 63 sizeof(struct ath_buf_state)); \
78 } while (0) 64 } while (0)
79 65
80/**
81 * enum buffer_type - Buffer type flags
82 *
83 * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
84 * @BUF_AGGR: Indicates whether the buffer can be aggregated
85 * (used in aggregation scheduling)
86 */
87enum buffer_type {
88 BUF_AMPDU = BIT(0),
89 BUF_AGGR = BIT(1),
90};
91
92#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
93#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
94
95#define ATH_TXSTATUS_RING_SIZE 512
96
97#define DS2PHYS(_dd, _ds) \ 66#define DS2PHYS(_dd, _ds) \
98 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 67 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
99#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) 68#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
@@ -113,11 +82,20 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
113/* RX / TX */ 82/* RX / TX */
114/***********/ 83/***********/
115 84
85#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
86
87/* increment with wrap-around */
88#define INCR(_l, _sz) do { \
89 (_l)++; \
90 (_l) &= ((_sz) - 1); \
91 } while (0)
92
116#define ATH_RXBUF 512 93#define ATH_RXBUF 512
117#define ATH_TXBUF 512 94#define ATH_TXBUF 512
118#define ATH_TXBUF_RESERVE 5 95#define ATH_TXBUF_RESERVE 5
119#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) 96#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
120#define ATH_TXMAXTRY 13 97#define ATH_TXMAXTRY 13
98#define ATH_MAX_SW_RETRIES 30
121 99
122#define TID_TO_WME_AC(_tid) \ 100#define TID_TO_WME_AC(_tid) \
123 ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \ 101 ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \
@@ -133,6 +111,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
133#define ATH_AGGR_MIN_QDEPTH 2 111#define ATH_AGGR_MIN_QDEPTH 2
134/* minimum h/w qdepth for non-aggregated traffic */ 112/* minimum h/w qdepth for non-aggregated traffic */
135#define ATH_NON_AGGR_MIN_QDEPTH 8 113#define ATH_NON_AGGR_MIN_QDEPTH 8
114#define ATH_TX_COMPLETE_POLL_INT 1000
115#define ATH_TXFIFO_DEPTH 8
116#define ATH_TX_ERROR 0x01
136 117
137#define IEEE80211_SEQ_SEQ_SHIFT 4 118#define IEEE80211_SEQ_SEQ_SHIFT 4
138#define IEEE80211_SEQ_MAX 4096 119#define IEEE80211_SEQ_MAX 4096
@@ -165,11 +146,10 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
165 146
166#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 147#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
167 148
168#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) 149#define IS_HT_RATE(rate) (rate & 0x80)
150#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
151#define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf))
169 152
170#define ATH_TX_COMPLETE_POLL_INT 1000
171
172#define ATH_TXFIFO_DEPTH 8
173struct ath_txq { 153struct ath_txq {
174 int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ 154 int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
175 u32 axq_qnum; /* ath9k hardware queue number */ 155 u32 axq_qnum; /* ath9k hardware queue number */
@@ -214,6 +194,21 @@ struct ath_rxbuf {
214 dma_addr_t bf_buf_addr; 194 dma_addr_t bf_buf_addr;
215}; 195};
216 196
197/**
198 * enum buffer_type - Buffer type flags
199 *
200 * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
201 * @BUF_AGGR: Indicates whether the buffer can be aggregated
202 * (used in aggregation scheduling)
203 */
204enum buffer_type {
205 BUF_AMPDU = BIT(0),
206 BUF_AGGR = BIT(1),
207};
208
209#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
210#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
211
217struct ath_buf_state { 212struct ath_buf_state {
218 u8 bf_type; 213 u8 bf_type;
219 u8 bfs_paprd; 214 u8 bfs_paprd;
@@ -269,6 +264,10 @@ struct ath_node {
269 264
270 bool sleeping; 265 bool sleeping;
271 bool no_ps_filter; 266 bool no_ps_filter;
267
268#ifdef CONFIG_ATH9K_STATION_STATISTICS
269 struct ath_rx_rate_stats rx_rate_stats;
270#endif
272}; 271};
273 272
274struct ath_tx_control { 273struct ath_tx_control {
@@ -278,7 +277,6 @@ struct ath_tx_control {
278 struct ieee80211_sta *sta; 277 struct ieee80211_sta *sta;
279}; 278};
280 279
281#define ATH_TX_ERROR 0x01
282 280
283/** 281/**
284 * @txq_map: Index is mac80211 queue number. This is 282 * @txq_map: Index is mac80211 queue number. This is
@@ -372,6 +370,22 @@ struct ath_vif {
372 struct ath_buf *av_bcbuf; 370 struct ath_buf *av_bcbuf;
373}; 371};
374 372
373struct ath9k_vif_iter_data {
374 u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
375 u8 mask[ETH_ALEN]; /* bssid mask */
376 bool has_hw_macaddr;
377
378 int naps; /* number of AP vifs */
379 int nmeshes; /* number of mesh vifs */
380 int nstations; /* number of station vifs */
381 int nwds; /* number of WDS vifs */
382 int nadhocs; /* number of adhoc vifs */
383};
384
385void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
386 struct ieee80211_vif *vif,
387 struct ath9k_vif_iter_data *iter_data);
388
375/*******************/ 389/*******************/
376/* Beacon Handling */ 390/* Beacon Handling */
377/*******************/ 391/*******************/
@@ -387,6 +401,9 @@ struct ath_vif {
387#define ATH_DEFAULT_BMISS_LIMIT 10 401#define ATH_DEFAULT_BMISS_LIMIT 10
388#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) 402#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
389 403
404#define TSF_TO_TU(_h,_l) \
405 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
406
390struct ath_beacon_config { 407struct ath_beacon_config {
391 int beacon_interval; 408 int beacon_interval;
392 u16 listen_interval; 409 u16 listen_interval;
@@ -420,12 +437,10 @@ struct ath_beacon {
420}; 437};
421 438
422void ath9k_beacon_tasklet(unsigned long data); 439void ath9k_beacon_tasklet(unsigned long data);
423bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
424void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, 440void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
425 u32 changed); 441 u32 changed);
426void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); 442void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
427void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); 443void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
428void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif);
429void ath9k_set_beacon(struct ath_softc *sc); 444void ath9k_set_beacon(struct ath_softc *sc);
430bool ath9k_csa_is_finished(struct ath_softc *sc); 445bool ath9k_csa_is_finished(struct ath_softc *sc);
431 446
@@ -440,17 +455,14 @@ bool ath9k_csa_is_finished(struct ath_softc *sc);
440#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ 455#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */
441#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 456#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
442#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 457#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
443#define ATH_ANI_MAX_SKIP_COUNT 10 458#define ATH_ANI_MAX_SKIP_COUNT 10
444 459#define ATH_PAPRD_TIMEOUT 100 /* msecs */
445#define ATH_PAPRD_TIMEOUT 100 /* msecs */ 460#define ATH_PLL_WORK_INTERVAL 100
446#define ATH_PLL_WORK_INTERVAL 100
447 461
448void ath_tx_complete_poll_work(struct work_struct *work); 462void ath_tx_complete_poll_work(struct work_struct *work);
449void ath_reset_work(struct work_struct *work); 463void ath_reset_work(struct work_struct *work);
450void ath_hw_check(struct work_struct *work); 464bool ath_hw_check(struct ath_softc *sc);
451void ath_hw_pll_work(struct work_struct *work); 465void ath_hw_pll_work(struct work_struct *work);
452void ath_rx_poll(unsigned long data);
453void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon);
454void ath_paprd_calibrate(struct work_struct *work); 466void ath_paprd_calibrate(struct work_struct *work);
455void ath_ani_calibrate(unsigned long data); 467void ath_ani_calibrate(unsigned long data);
456void ath_start_ani(struct ath_softc *sc); 468void ath_start_ani(struct ath_softc *sc);
@@ -459,6 +471,7 @@ void ath_check_ani(struct ath_softc *sc);
459int ath_update_survey_stats(struct ath_softc *sc); 471int ath_update_survey_stats(struct ath_softc *sc);
460void ath_update_survey_nf(struct ath_softc *sc, int channel); 472void ath_update_survey_nf(struct ath_softc *sc, int channel);
461void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); 473void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
474void ath_ps_full_sleep(unsigned long data);
462 475
463/**********/ 476/**********/
464/* BTCOEX */ 477/* BTCOEX */
@@ -476,20 +489,19 @@ enum bt_op_flags {
476}; 489};
477 490
478struct ath_btcoex { 491struct ath_btcoex {
479 bool hw_timer_enabled;
480 spinlock_t btcoex_lock; 492 spinlock_t btcoex_lock;
481 struct timer_list period_timer; /* Timer for BT period */ 493 struct timer_list period_timer; /* Timer for BT period */
494 struct timer_list no_stomp_timer;
482 u32 bt_priority_cnt; 495 u32 bt_priority_cnt;
483 unsigned long bt_priority_time; 496 unsigned long bt_priority_time;
484 unsigned long op_flags; 497 unsigned long op_flags;
485 int bt_stomp_type; /* Types of BT stomping */ 498 int bt_stomp_type; /* Types of BT stomping */
486 u32 btcoex_no_stomp; /* in usec */ 499 u32 btcoex_no_stomp; /* in msec */
487 u32 btcoex_period; /* in msec */ 500 u32 btcoex_period; /* in msec */
488 u32 btscan_no_stomp; /* in usec */ 501 u32 btscan_no_stomp; /* in msec */
489 u32 duty_cycle; 502 u32 duty_cycle;
490 u32 bt_wait_time; 503 u32 bt_wait_time;
491 int rssi_count; 504 int rssi_count;
492 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
493 struct ath_mci_profile mci; 505 struct ath_mci_profile mci;
494 u8 stomp_audio; 506 u8 stomp_audio;
495}; 507};
@@ -537,12 +549,6 @@ static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
537} 549}
538#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 550#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
539 551
540struct ath9k_wow_pattern {
541 u8 pattern_bytes[MAX_PATTERN_SIZE];
542 u8 mask_bytes[MAX_PATTERN_SIZE];
543 u32 pattern_len;
544};
545
546/********************/ 552/********************/
547/* LED Control */ 553/* LED Control */
548/********************/ 554/********************/
@@ -570,6 +576,40 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
570} 576}
571#endif 577#endif
572 578
579/************************/
580/* Wake on Wireless LAN */
581/************************/
582
583struct ath9k_wow_pattern {
584 u8 pattern_bytes[MAX_PATTERN_SIZE];
585 u8 mask_bytes[MAX_PATTERN_SIZE];
586 u32 pattern_len;
587};
588
589#ifdef CONFIG_ATH9K_WOW
590void ath9k_init_wow(struct ieee80211_hw *hw);
591int ath9k_suspend(struct ieee80211_hw *hw,
592 struct cfg80211_wowlan *wowlan);
593int ath9k_resume(struct ieee80211_hw *hw);
594void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
595#else
596static inline void ath9k_init_wow(struct ieee80211_hw *hw)
597{
598}
599static inline int ath9k_suspend(struct ieee80211_hw *hw,
600 struct cfg80211_wowlan *wowlan)
601{
602 return 0;
603}
604static inline int ath9k_resume(struct ieee80211_hw *hw)
605{
606 return 0;
607}
608static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
609{
610}
611#endif /* CONFIG_ATH9K_WOW */
612
573/*******************************/ 613/*******************************/
574/* Antenna diversity/combining */ 614/* Antenna diversity/combining */
575/*******************************/ 615/*******************************/
@@ -642,19 +682,16 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
642#define ATH9K_PCI_AR9565_1ANT 0x0080 682#define ATH9K_PCI_AR9565_1ANT 0x0080
643#define ATH9K_PCI_AR9565_2ANT 0x0100 683#define ATH9K_PCI_AR9565_2ANT 0x0100
644#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 684#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200
685#define ATH9K_PCI_KILLER 0x0400
645 686
646/* 687/*
647 * Default cache line size, in bytes. 688 * Default cache line size, in bytes.
648 * Used when PCI device not fully initialized by bootrom/BIOS 689 * Used when PCI device not fully initialized by bootrom/BIOS
649*/ 690*/
650#define DEFAULT_CACHELINE 32 691#define DEFAULT_CACHELINE 32
651#define ATH_REGCLASSIDS_MAX 10
652#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ 692#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
653#define ATH_MAX_SW_RETRIES 30
654#define ATH_CHAN_MAX 255
655
656#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ 693#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
657#define ATH_RATE_DUMMY_MARKER 0 694#define MAX_GTT_CNT 5
658 695
659enum sc_op_flags { 696enum sc_op_flags {
660 SC_OP_INVALID, 697 SC_OP_INVALID,
@@ -673,37 +710,6 @@ enum sc_op_flags {
673#define PS_BEACON_SYNC BIT(4) 710#define PS_BEACON_SYNC BIT(4)
674#define PS_WAIT_FOR_ANI BIT(5) 711#define PS_WAIT_FOR_ANI BIT(5)
675 712
676struct ath_rate_table;
677
678struct ath9k_vif_iter_data {
679 u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
680 u8 mask[ETH_ALEN]; /* bssid mask */
681 bool has_hw_macaddr;
682
683 int naps; /* number of AP vifs */
684 int nmeshes; /* number of mesh vifs */
685 int nstations; /* number of station vifs */
686 int nwds; /* number of WDS vifs */
687 int nadhocs; /* number of adhoc vifs */
688};
689
690/* enum spectral_mode:
691 *
692 * @SPECTRAL_DISABLED: spectral mode is disabled
693 * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
694 * something else.
695 * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
696 * is performed manually.
697 * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
698 * during a channel scan.
699 */
700enum spectral_mode {
701 SPECTRAL_DISABLED = 0,
702 SPECTRAL_BACKGROUND,
703 SPECTRAL_MANUAL,
704 SPECTRAL_CHANSCAN,
705};
706
707struct ath_softc { 713struct ath_softc {
708 struct ieee80211_hw *hw; 714 struct ieee80211_hw *hw;
709 struct device *dev; 715 struct device *dev;
@@ -721,14 +727,14 @@ struct ath_softc {
721 spinlock_t sc_pcu_lock; 727 spinlock_t sc_pcu_lock;
722 struct mutex mutex; 728 struct mutex mutex;
723 struct work_struct paprd_work; 729 struct work_struct paprd_work;
724 struct work_struct hw_check_work;
725 struct work_struct hw_reset_work; 730 struct work_struct hw_reset_work;
726 struct completion paprd_complete; 731 struct completion paprd_complete;
732 wait_queue_head_t tx_wait;
727 733
728 unsigned int hw_busy_count;
729 unsigned long sc_flags; 734 unsigned long sc_flags;
730 unsigned long driver_data; 735 unsigned long driver_data;
731 736
737 u8 gtt_cnt;
732 u32 intrstatus; 738 u32 intrstatus;
733 u16 ps_flags; /* PS_* */ 739 u16 ps_flags; /* PS_* */
734 u16 curtxpow; 740 u16 curtxpow;
@@ -759,7 +765,7 @@ struct ath_softc {
759 struct ath_beacon_config cur_beacon_conf; 765 struct ath_beacon_config cur_beacon_conf;
760 struct delayed_work tx_complete_work; 766 struct delayed_work tx_complete_work;
761 struct delayed_work hw_pll_work; 767 struct delayed_work hw_pll_work;
762 struct timer_list rx_poll_timer; 768 struct timer_list sleep_timer;
763 769
764#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 770#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
765 struct ath_btcoex btcoex; 771 struct ath_btcoex btcoex;
@@ -784,199 +790,54 @@ struct ath_softc {
784 bool tx99_state; 790 bool tx99_state;
785 s16 tx99_power; 791 s16 tx99_power;
786 792
787#ifdef CONFIG_PM_SLEEP 793#ifdef CONFIG_ATH9K_WOW
788 atomic_t wow_got_bmiss_intr; 794 atomic_t wow_got_bmiss_intr;
789 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ 795 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
790 u32 wow_intr_before_sleep; 796 u32 wow_intr_before_sleep;
791#endif 797#endif
792}; 798};
793 799
794#define SPECTRAL_SCAN_BITMASK 0x10 800/********/
795/* Radar info packet format, used for DFS and spectral formats. */ 801/* TX99 */
796struct ath_radar_info { 802/********/
797 u8 pulse_length_pri;
798 u8 pulse_length_ext;
799 u8 pulse_bw_info;
800} __packed;
801
802/* The HT20 spectral data has 4 bytes of additional information at it's end.
803 *
804 * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
805 * [7:0]: all bins max_magnitude[9:2]
806 * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
807 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
808 */
809struct ath_ht20_mag_info {
810 u8 all_bins[3];
811 u8 max_exp;
812} __packed;
813
814#define SPECTRAL_HT20_NUM_BINS 56
815
816/* WARNING: don't actually use this struct! MAC may vary the amount of
817 * data by -1/+2. This struct is for reference only.
818 */
819struct ath_ht20_fft_packet {
820 u8 data[SPECTRAL_HT20_NUM_BINS];
821 struct ath_ht20_mag_info mag_info;
822 struct ath_radar_info radar_info;
823} __packed;
824
825#define SPECTRAL_HT20_TOTAL_DATA_LEN (sizeof(struct ath_ht20_fft_packet))
826
827/* Dynamic 20/40 mode:
828 *
829 * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
830 * [7:0]: lower bins max_magnitude[9:2]
831 * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
832 * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
833 * [7:0]: upper bins max_magnitude[9:2]
834 * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
835 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
836 */
837struct ath_ht20_40_mag_info {
838 u8 lower_bins[3];
839 u8 upper_bins[3];
840 u8 max_exp;
841} __packed;
842
843#define SPECTRAL_HT20_40_NUM_BINS 128
844
845/* WARNING: don't actually use this struct! MAC may vary the amount of
846 * data. This struct is for reference only.
847 */
848struct ath_ht20_40_fft_packet {
849 u8 data[SPECTRAL_HT20_40_NUM_BINS];
850 struct ath_ht20_40_mag_info mag_info;
851 struct ath_radar_info radar_info;
852} __packed;
853
854
855#define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
856
857/* grabs the max magnitude from the all/upper/lower bins */
858static inline u16 spectral_max_magnitude(u8 *bins)
859{
860 return (bins[0] & 0xc0) >> 6 |
861 (bins[1] & 0xff) << 2 |
862 (bins[2] & 0x03) << 10;
863}
864 803
865/* return the max magnitude from the all/upper/lower bins */ 804#ifdef CONFIG_ATH9K_TX99
866static inline u8 spectral_max_index(u8 *bins) 805void ath9k_tx99_init_debug(struct ath_softc *sc);
806int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
807 struct ath_tx_control *txctl);
808#else
809static inline void ath9k_tx99_init_debug(struct ath_softc *sc)
867{ 810{
868 s8 m = (bins[2] & 0xfc) >> 2;
869
870 /* TODO: this still doesn't always report the right values ... */
871 if (m > 32)
872 m |= 0xe0;
873 else
874 m &= ~0xe0;
875
876 return m + 29;
877} 811}
878 812static inline int ath9k_tx99_send(struct ath_softc *sc,
879/* return the bitmap weight from the all/upper/lower bins */ 813 struct sk_buff *skb,
880static inline u8 spectral_bitmap_weight(u8 *bins) 814 struct ath_tx_control *txctl)
881{ 815{
882 return bins[0] & 0x3f; 816 return 0;
883} 817}
884 818#endif /* CONFIG_ATH9K_TX99 */
885/* FFT sample format given to userspace via debugfs.
886 *
887 * Please keep the type/length at the front position and change
888 * other fields after adding another sample type
889 *
890 * TODO: this might need rework when switching to nl80211-based
891 * interface.
892 */
893enum ath_fft_sample_type {
894 ATH_FFT_SAMPLE_HT20 = 1,
895 ATH_FFT_SAMPLE_HT20_40,
896};
897
898struct fft_sample_tlv {
899 u8 type; /* see ath_fft_sample */
900 __be16 length;
901 /* type dependent data follows */
902} __packed;
903
904struct fft_sample_ht20 {
905 struct fft_sample_tlv tlv;
906
907 u8 max_exp;
908
909 __be16 freq;
910 s8 rssi;
911 s8 noise;
912
913 __be16 max_magnitude;
914 u8 max_index;
915 u8 bitmap_weight;
916
917 __be64 tsf;
918
919 u8 data[SPECTRAL_HT20_NUM_BINS];
920} __packed;
921
922struct fft_sample_ht20_40 {
923 struct fft_sample_tlv tlv;
924
925 u8 channel_type;
926 __be16 freq;
927
928 s8 lower_rssi;
929 s8 upper_rssi;
930
931 __be64 tsf;
932
933 s8 lower_noise;
934 s8 upper_noise;
935
936 __be16 lower_max_magnitude;
937 __be16 upper_max_magnitude;
938
939 u8 lower_max_index;
940 u8 upper_max_index;
941
942 u8 lower_bitmap_weight;
943 u8 upper_bitmap_weight;
944
945 u8 max_exp;
946
947 u8 data[SPECTRAL_HT20_40_NUM_BINS];
948} __packed;
949
950int ath9k_tx99_init(struct ath_softc *sc);
951void ath9k_tx99_deinit(struct ath_softc *sc);
952int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
953 struct ath_tx_control *txctl);
954
955void ath9k_tasklet(unsigned long data);
956int ath_cabq_update(struct ath_softc *);
957 819
958static inline void ath_read_cachesize(struct ath_common *common, int *csz) 820static inline void ath_read_cachesize(struct ath_common *common, int *csz)
959{ 821{
960 common->bus_ops->read_cachesize(common, csz); 822 common->bus_ops->read_cachesize(common, csz);
961} 823}
962 824
963extern struct ieee80211_ops ath9k_ops; 825void ath9k_tasklet(unsigned long data);
964extern int ath9k_modparam_nohwcrypt; 826int ath_cabq_update(struct ath_softc *);
965extern int led_blink;
966extern bool is_ath9k_unloaded;
967
968u8 ath9k_parse_mpdudensity(u8 mpdudensity); 827u8 ath9k_parse_mpdudensity(u8 mpdudensity);
969irqreturn_t ath_isr(int irq, void *dev); 828irqreturn_t ath_isr(int irq, void *dev);
829int ath_reset(struct ath_softc *sc);
830void ath_cancel_work(struct ath_softc *sc);
831void ath_restart_work(struct ath_softc *sc);
970int ath9k_init_device(u16 devid, struct ath_softc *sc, 832int ath9k_init_device(u16 devid, struct ath_softc *sc,
971 const struct ath_bus_ops *bus_ops); 833 const struct ath_bus_ops *bus_ops);
972void ath9k_deinit_device(struct ath_softc *sc); 834void ath9k_deinit_device(struct ath_softc *sc);
973void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
974void ath9k_reload_chainmask_settings(struct ath_softc *sc); 835void ath9k_reload_chainmask_settings(struct ath_softc *sc);
975 836u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
976void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); 837void ath_start_rfkill_poll(struct ath_softc *sc);
977int ath9k_spectral_scan_config(struct ieee80211_hw *hw, 838void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
978 enum spectral_mode spectral_mode); 839void ath9k_ps_wakeup(struct ath_softc *sc);
979 840void ath9k_ps_restore(struct ath_softc *sc);
980 841
981#ifdef CONFIG_ATH9K_PCI 842#ifdef CONFIG_ATH9K_PCI
982int ath_pci_init(void); 843int ath_pci_init(void);
@@ -994,15 +855,4 @@ static inline int ath_ahb_init(void) { return 0; };
994static inline void ath_ahb_exit(void) {}; 855static inline void ath_ahb_exit(void) {};
995#endif 856#endif
996 857
997void ath9k_ps_wakeup(struct ath_softc *sc);
998void ath9k_ps_restore(struct ath_softc *sc);
999
1000u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
1001
1002void ath_start_rfkill_poll(struct ath_softc *sc);
1003void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
1004void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
1005 struct ieee80211_vif *vif,
1006 struct ath9k_vif_iter_data *iter_data);
1007
1008#endif /* ATH9K_H */ 858#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 17be35392bb4..2e8bba0eb361 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -274,18 +274,19 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
274 return slot; 274 return slot;
275} 275}
276 276
277void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) 277static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
278{ 278{
279 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 279 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
280 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 280 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
281 struct ath_vif *avp = (void *)vif->drv_priv; 281 struct ath_vif *avp = (void *)vif->drv_priv;
282 u64 tsfadjust; 282 u32 tsfadjust;
283 283
284 if (avp->av_bslot == 0) 284 if (avp->av_bslot == 0)
285 return; 285 return;
286 286
287 tsfadjust = cur_conf->beacon_interval * avp->av_bslot / ATH_BCBUF; 287 tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
288 avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); 288 tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF;
289 avp->tsf_adjust = cpu_to_le64(tsfadjust);
289 290
290 ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", 291 ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n",
291 (unsigned long long)tsfadjust, avp->av_bslot); 292 (unsigned long long)tsfadjust, avp->av_bslot);
@@ -336,8 +337,14 @@ void ath9k_beacon_tasklet(unsigned long data)
336 337
337 ath9k_hw_check_nav(ah); 338 ath9k_hw_check_nav(ah);
338 339
339 if (!ath9k_hw_check_alive(ah)) 340 /*
340 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 341 * If the previous beacon has not been transmitted
342 * and a MAC/BB hang has been identified, return
343 * here because a chip reset would have been
344 * initiated.
345 */
346 if (!ath_hw_check(sc))
347 return;
341 348
342 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { 349 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
343 ath_dbg(common, BSTUCK, 350 ath_dbg(common, BSTUCK,
@@ -431,6 +438,33 @@ static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
431 ath9k_hw_enable_interrupts(ah); 438 ath9k_hw_enable_interrupts(ah);
432} 439}
433 440
441/* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */
442static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu)
443{
444 u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo;
445
446 tsf_mod = tsf & (BIT(10) - 1);
447 tsf_hi = tsf >> 32;
448 tsf_lo = ((u32) tsf) >> 10;
449
450 mod_hi = tsf_hi % div_tu;
451 mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu;
452
453 return (mod_lo << 10) | tsf_mod;
454}
455
456static u32 ath9k_get_next_tbtt(struct ath_softc *sc, u64 tsf,
457 unsigned int interval)
458{
459 struct ath_hw *ah = sc->sc_ah;
460 unsigned int offset;
461
462 tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time);
463 offset = ath9k_mod_tsf64_tu(tsf, interval);
464
465 return (u32) tsf + TU_TO_USEC(interval) - offset;
466}
467
434/* 468/*
435 * For multi-bss ap support beacons are either staggered evenly over N slots or 469 * For multi-bss ap support beacons are either staggered evenly over N slots or
436 * burst together. For the former arrange for the SWBA to be delivered for each 470 * burst together. For the former arrange for the SWBA to be delivered for each
@@ -446,7 +480,8 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
446 /* NB: the beacon interval is kept internally in TU's */ 480 /* NB: the beacon interval is kept internally in TU's */
447 intval = TU_TO_USEC(conf->beacon_interval); 481 intval = TU_TO_USEC(conf->beacon_interval);
448 intval /= ATH_BCBUF; 482 intval /= ATH_BCBUF;
449 nexttbtt = intval; 483 nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
484 conf->beacon_interval);
450 485
451 if (conf->enable_beacon) 486 if (conf->enable_beacon)
452 ah->imask |= ATH9K_INT_SWBA; 487 ah->imask |= ATH9K_INT_SWBA;
@@ -458,7 +493,7 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
458 (conf->enable_beacon) ? "Enable" : "Disable", 493 (conf->enable_beacon) ? "Enable" : "Disable",
459 nexttbtt, intval, conf->beacon_interval); 494 nexttbtt, intval, conf->beacon_interval);
460 495
461 ath9k_beacon_init(sc, nexttbtt, intval, true); 496 ath9k_beacon_init(sc, nexttbtt, intval, false);
462} 497}
463 498
464/* 499/*
@@ -475,11 +510,9 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
475 struct ath_hw *ah = sc->sc_ah; 510 struct ath_hw *ah = sc->sc_ah;
476 struct ath_common *common = ath9k_hw_common(ah); 511 struct ath_common *common = ath9k_hw_common(ah);
477 struct ath9k_beacon_state bs; 512 struct ath9k_beacon_state bs;
478 int dtimperiod, dtimcount, sleepduration; 513 int dtim_intval, sleepduration;
479 int cfpperiod, cfpcount; 514 u32 nexttbtt = 0, intval;
480 u32 nexttbtt = 0, intval, tsftu;
481 u64 tsf; 515 u64 tsf;
482 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
483 516
484 /* No need to configure beacon if we are not associated */ 517 /* No need to configure beacon if we are not associated */
485 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 518 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
@@ -492,53 +525,25 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
492 intval = conf->beacon_interval; 525 intval = conf->beacon_interval;
493 526
494 /* 527 /*
495 * Setup dtim and cfp parameters according to 528 * Setup dtim parameters according to
496 * last beacon we received (which may be none). 529 * last beacon we received (which may be none).
497 */ 530 */
498 dtimperiod = conf->dtim_period; 531 dtim_intval = intval * conf->dtim_period;
499 dtimcount = conf->dtim_count;
500 if (dtimcount >= dtimperiod) /* NB: sanity check */
501 dtimcount = 0;
502 cfpperiod = 1; /* NB: no PCF support yet */
503 cfpcount = 0;
504
505 sleepduration = conf->listen_interval * intval; 532 sleepduration = conf->listen_interval * intval;
506 533
507 /* 534 /*
508 * Pull nexttbtt forward to reflect the current 535 * Pull nexttbtt forward to reflect the current
509 * TSF and calculate dtim+cfp state for the result. 536 * TSF and calculate dtim state for the result.
510 */ 537 */
511 tsf = ath9k_hw_gettsf64(ah); 538 tsf = ath9k_hw_gettsf64(ah);
512 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 539 nexttbtt = ath9k_get_next_tbtt(sc, tsf, intval);
513 540
514 num_beacons = tsftu / intval + 1; 541 bs.bs_intval = TU_TO_USEC(intval);
515 offset = tsftu % intval; 542 bs.bs_dtimperiod = conf->dtim_period * bs.bs_intval;
516 nexttbtt = tsftu - offset;
517 if (offset)
518 nexttbtt += intval;
519
520 /* DTIM Beacon every dtimperiod Beacon */
521 dtim_dec_count = num_beacons % dtimperiod;
522 /* CFP every cfpperiod DTIM Beacon */
523 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
524 if (dtim_dec_count)
525 cfp_dec_count++;
526
527 dtimcount -= dtim_dec_count;
528 if (dtimcount < 0)
529 dtimcount += dtimperiod;
530
531 cfpcount -= cfp_dec_count;
532 if (cfpcount < 0)
533 cfpcount += cfpperiod;
534
535 bs.bs_intval = intval;
536 bs.bs_nexttbtt = nexttbtt; 543 bs.bs_nexttbtt = nexttbtt;
537 bs.bs_dtimperiod = dtimperiod*intval; 544 bs.bs_nextdtim = nexttbtt;
538 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval; 545 if (conf->dtim_period > 1)
539 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; 546 bs.bs_nextdtim = ath9k_get_next_tbtt(sc, tsf, dtim_intval);
540 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
541 bs.bs_cfpmaxduration = 0;
542 547
543 /* 548 /*
544 * Calculate the number of consecutive beacons to miss* before taking 549 * Calculate the number of consecutive beacons to miss* before taking
@@ -566,18 +571,16 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
566 * XXX fixed at 100ms 571 * XXX fixed at 100ms
567 */ 572 */
568 573
569 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration); 574 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
575 sleepduration));
570 if (bs.bs_sleepduration > bs.bs_dtimperiod) 576 if (bs.bs_sleepduration > bs.bs_dtimperiod)
571 bs.bs_sleepduration = bs.bs_dtimperiod; 577 bs.bs_sleepduration = bs.bs_dtimperiod;
572 578
573 /* TSF out of range threshold fixed at 1 second */ 579 /* TSF out of range threshold fixed at 1 second */
574 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; 580 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
575 581
576 ath_dbg(common, BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); 582 ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n",
577 ath_dbg(common, BEACON, 583 bs.bs_bmissthreshold, bs.bs_sleepduration);
578 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
579 bs.bs_bmissthreshold, bs.bs_sleepduration,
580 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
581 584
582 /* Set the computed STA beacon timers */ 585 /* Set the computed STA beacon timers */
583 586
@@ -600,25 +603,11 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
600 603
601 intval = TU_TO_USEC(conf->beacon_interval); 604 intval = TU_TO_USEC(conf->beacon_interval);
602 605
603 if (conf->ibss_creator) { 606 if (conf->ibss_creator)
604 nexttbtt = intval; 607 nexttbtt = intval;
605 } else { 608 else
606 u32 tbtt, offset, tsftu; 609 nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
607 u64 tsf; 610 conf->beacon_interval);
608
609 /*
610 * Pull nexttbtt forward to reflect the current
611 * sync'd TSF.
612 */
613 tsf = ath9k_hw_gettsf64(ah);
614 tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
615 offset = tsftu % conf->beacon_interval;
616 tbtt = tsftu - offset;
617 if (offset)
618 tbtt += conf->beacon_interval;
619
620 nexttbtt = TU_TO_USEC(tbtt);
621 }
622 611
623 if (conf->enable_beacon) 612 if (conf->enable_beacon)
624 ah->imask |= ATH9K_INT_SWBA; 613 ah->imask |= ATH9K_INT_SWBA;
@@ -640,7 +629,8 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
640 set_bit(SC_OP_BEACONS, &sc->sc_flags); 629 set_bit(SC_OP_BEACONS, &sc->sc_flags);
641} 630}
642 631
643bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) 632static bool ath9k_allow_beacon_config(struct ath_softc *sc,
633 struct ieee80211_vif *vif)
644{ 634{
645 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 635 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
646 struct ath_vif *avp = (void *)vif->drv_priv; 636 struct ath_vif *avp = (void *)vif->drv_priv;
@@ -711,12 +701,17 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
711 unsigned long flags; 701 unsigned long flags;
712 bool skip_beacon = false; 702 bool skip_beacon = false;
713 703
704 if (vif->type == NL80211_IFTYPE_AP)
705 ath9k_set_tsfadjust(sc, vif);
706
707 if (!ath9k_allow_beacon_config(sc, vif))
708 return;
709
714 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { 710 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
715 ath9k_cache_beacon_config(sc, bss_conf); 711 ath9k_cache_beacon_config(sc, bss_conf);
716 ath9k_set_beacon(sc); 712 ath9k_set_beacon(sc);
717 set_bit(SC_OP_BEACONS, &sc->sc_flags); 713 set_bit(SC_OP_BEACONS, &sc->sc_flags);
718 return; 714 return;
719
720 } 715 }
721 716
722 /* 717 /*
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 9963b0bf9f72..3dfc2c7f1f07 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -66,7 +66,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
66 .bt_first_slot_time = 5, 66 .bt_first_slot_time = 5,
67 .bt_hold_rx_clear = true, 67 .bt_hold_rx_clear = true,
68 }; 68 };
69 u32 i, idx;
70 bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; 69 bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
71 70
72 if (AR_SREV_9300_20_OR_LATER(ah)) 71 if (AR_SREV_9300_20_OR_LATER(ah))
@@ -88,11 +87,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
88 SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) | 87 SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
89 SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) | 88 SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
90 AR_BT_DISABLE_BT_ANT; 89 AR_BT_DISABLE_BT_ANT;
91
92 for (i = 0; i < 32; i++) {
93 idx = (debruijn32 << i) >> 27;
94 ah->hw_gen_timers.gen_timer_index[idx] = i;
95 }
96} 90}
97EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw); 91EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
98 92
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index a7e5a05b2eff..768c733cad31 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -98,10 +98,8 @@ struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw,
98{ 98{
99 struct ieee80211_channel *curchan = chandef->chan; 99 struct ieee80211_channel *curchan = chandef->chan;
100 struct ath9k_channel *channel; 100 struct ath9k_channel *channel;
101 u8 chan_idx;
102 101
103 chan_idx = curchan->hw_value; 102 channel = &ah->channels[curchan->hw_value];
104 channel = &ah->channels[chan_idx];
105 ath9k_cmn_update_ichannel(channel, chandef); 103 ath9k_cmn_update_ichannel(channel, chandef);
106 104
107 return channel; 105 return channel;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 83a2c59f680b..ab7264c1d8f7 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -17,7 +17,6 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
19#include <linux/export.h> 19#include <linux/export.h>
20#include <linux/relay.h>
21#include <asm/unaligned.h> 20#include <asm/unaligned.h>
22 21
23#include "ath9k.h" 22#include "ath9k.h"
@@ -27,6 +26,47 @@
27#define REG_READ_D(_ah, _reg) \ 26#define REG_READ_D(_ah, _reg) \
28 ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) 27 ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
29 28
29void ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)
30{
31 if (sync_cause)
32 sc->debug.stats.istats.sync_cause_all++;
33 if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
34 sc->debug.stats.istats.sync_rtc_irq++;
35 if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
36 sc->debug.stats.istats.sync_mac_irq++;
37 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
38 sc->debug.stats.istats.eeprom_illegal_access++;
39 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
40 sc->debug.stats.istats.apb_timeout++;
41 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
42 sc->debug.stats.istats.pci_mode_conflict++;
43 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
44 sc->debug.stats.istats.host1_fatal++;
45 if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
46 sc->debug.stats.istats.host1_perr++;
47 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
48 sc->debug.stats.istats.trcv_fifo_perr++;
49 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
50 sc->debug.stats.istats.radm_cpl_ep++;
51 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
52 sc->debug.stats.istats.radm_cpl_dllp_abort++;
53 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
54 sc->debug.stats.istats.radm_cpl_tlp_abort++;
55 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
56 sc->debug.stats.istats.radm_cpl_ecrc_err++;
57 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
58 sc->debug.stats.istats.radm_cpl_timeout++;
59 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
60 sc->debug.stats.istats.local_timeout++;
61 if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
62 sc->debug.stats.istats.pm_access++;
63 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
64 sc->debug.stats.istats.mac_awake++;
65 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
66 sc->debug.stats.istats.mac_asleep++;
67 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
68 sc->debug.stats.istats.mac_sleep_access++;
69}
30 70
31static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, 71static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf,
32 size_t count, loff_t *ppos) 72 size_t count, loff_t *ppos)
@@ -903,14 +943,10 @@ static const struct file_operations fops_reset = {
903static ssize_t read_file_recv(struct file *file, char __user *user_buf, 943static ssize_t read_file_recv(struct file *file, char __user *user_buf,
904 size_t count, loff_t *ppos) 944 size_t count, loff_t *ppos)
905{ 945{
906#define PHY_ERR(s, p) \
907 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
908 sc->debug.stats.rxstats.phy_err_stats[p]);
909
910#define RXS_ERR(s, e) \ 946#define RXS_ERR(s, e) \
911 do { \ 947 do { \
912 len += scnprintf(buf + len, size - len, \ 948 len += scnprintf(buf + len, size - len, \
913 "%22s : %10u\n", s, \ 949 "%18s : %10u\n", s, \
914 sc->debug.stats.rxstats.e);\ 950 sc->debug.stats.rxstats.e);\
915 } while (0) 951 } while (0)
916 952
@@ -923,6 +959,12 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
923 if (buf == NULL) 959 if (buf == NULL)
924 return -ENOMEM; 960 return -ENOMEM;
925 961
962 RXS_ERR("PKTS-ALL", rx_pkts_all);
963 RXS_ERR("BYTES-ALL", rx_bytes_all);
964 RXS_ERR("BEACONS", rx_beacons);
965 RXS_ERR("FRAGS", rx_frags);
966 RXS_ERR("SPECTRAL", rx_spectral);
967
926 RXS_ERR("CRC ERR", crc_err); 968 RXS_ERR("CRC ERR", crc_err);
927 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err); 969 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
928 RXS_ERR("PHY ERR", phy_err); 970 RXS_ERR("PHY ERR", phy_err);
@@ -930,43 +972,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
930 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err); 972 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
931 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err); 973 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
932 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err); 974 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
933 RXS_ERR("RX-LENGTH-ERR", rx_len_err); 975 RXS_ERR("LENGTH-ERR", rx_len_err);
934 RXS_ERR("RX-OOM-ERR", rx_oom_err); 976 RXS_ERR("OOM-ERR", rx_oom_err);
935 RXS_ERR("RX-RATE-ERR", rx_rate_err); 977 RXS_ERR("RATE-ERR", rx_rate_err);
936 RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); 978 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
937
938 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
939 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
940 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
941 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
942 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
943 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
944 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
945 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
946 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
947 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
948 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
949 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
950 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
951 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
952 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
953 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
954 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
955 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
956 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
957 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
958 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
959 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
960 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
961 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
962 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
963 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
964
965 RXS_ERR("RX-Pkts-All", rx_pkts_all);
966 RXS_ERR("RX-Bytes-All", rx_bytes_all);
967 RXS_ERR("RX-Beacons", rx_beacons);
968 RXS_ERR("RX-Frags", rx_frags);
969 RXS_ERR("RX-Spectral", rx_spectral);
970 979
971 if (len > size) 980 if (len > size)
972 len = size; 981 len = size;
@@ -977,7 +986,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
977 return retval; 986 return retval;
978 987
979#undef RXS_ERR 988#undef RXS_ERR
980#undef PHY_ERR
981} 989}
982 990
983void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 991void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
@@ -1016,293 +1024,67 @@ static const struct file_operations fops_recv = {
1016 .llseek = default_llseek, 1024 .llseek = default_llseek,
1017}; 1025};
1018 1026
1019static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, 1027static ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
1020 size_t count, loff_t *ppos) 1028 size_t count, loff_t *ppos)
1021{
1022 struct ath_softc *sc = file->private_data;
1023 char *mode = "";
1024 unsigned int len;
1025
1026 switch (sc->spectral_mode) {
1027 case SPECTRAL_DISABLED:
1028 mode = "disable";
1029 break;
1030 case SPECTRAL_BACKGROUND:
1031 mode = "background";
1032 break;
1033 case SPECTRAL_CHANSCAN:
1034 mode = "chanscan";
1035 break;
1036 case SPECTRAL_MANUAL:
1037 mode = "manual";
1038 break;
1039 }
1040 len = strlen(mode);
1041 return simple_read_from_buffer(user_buf, count, ppos, mode, len);
1042}
1043
1044static ssize_t write_file_spec_scan_ctl(struct file *file,
1045 const char __user *user_buf,
1046 size_t count, loff_t *ppos)
1047{
1048 struct ath_softc *sc = file->private_data;
1049 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1050 char buf[32];
1051 ssize_t len;
1052
1053 if (config_enabled(CONFIG_ATH9K_TX99))
1054 return -EOPNOTSUPP;
1055
1056 len = min(count, sizeof(buf) - 1);
1057 if (copy_from_user(buf, user_buf, len))
1058 return -EFAULT;
1059
1060 buf[len] = '\0';
1061
1062 if (strncmp("trigger", buf, 7) == 0) {
1063 ath9k_spectral_scan_trigger(sc->hw);
1064 } else if (strncmp("background", buf, 9) == 0) {
1065 ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND);
1066 ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n");
1067 } else if (strncmp("chanscan", buf, 8) == 0) {
1068 ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN);
1069 ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n");
1070 } else if (strncmp("manual", buf, 6) == 0) {
1071 ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL);
1072 ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n");
1073 } else if (strncmp("disable", buf, 7) == 0) {
1074 ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED);
1075 ath_dbg(common, CONFIG, "spectral scan: disabled\n");
1076 } else {
1077 return -EINVAL;
1078 }
1079
1080 return count;
1081}
1082
1083static const struct file_operations fops_spec_scan_ctl = {
1084 .read = read_file_spec_scan_ctl,
1085 .write = write_file_spec_scan_ctl,
1086 .open = simple_open,
1087 .owner = THIS_MODULE,
1088 .llseek = default_llseek,
1089};
1090
1091static ssize_t read_file_spectral_short_repeat(struct file *file,
1092 char __user *user_buf,
1093 size_t count, loff_t *ppos)
1094{
1095 struct ath_softc *sc = file->private_data;
1096 char buf[32];
1097 unsigned int len;
1098
1099 len = sprintf(buf, "%d\n", sc->spec_config.short_repeat);
1100 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1101}
1102
1103static ssize_t write_file_spectral_short_repeat(struct file *file,
1104 const char __user *user_buf,
1105 size_t count, loff_t *ppos)
1106{
1107 struct ath_softc *sc = file->private_data;
1108 unsigned long val;
1109 char buf[32];
1110 ssize_t len;
1111
1112 len = min(count, sizeof(buf) - 1);
1113 if (copy_from_user(buf, user_buf, len))
1114 return -EFAULT;
1115
1116 buf[len] = '\0';
1117 if (kstrtoul(buf, 0, &val))
1118 return -EINVAL;
1119
1120 if (val < 0 || val > 1)
1121 return -EINVAL;
1122
1123 sc->spec_config.short_repeat = val;
1124 return count;
1125}
1126
1127static const struct file_operations fops_spectral_short_repeat = {
1128 .read = read_file_spectral_short_repeat,
1129 .write = write_file_spectral_short_repeat,
1130 .open = simple_open,
1131 .owner = THIS_MODULE,
1132 .llseek = default_llseek,
1133};
1134
1135static ssize_t read_file_spectral_count(struct file *file,
1136 char __user *user_buf,
1137 size_t count, loff_t *ppos)
1138{
1139 struct ath_softc *sc = file->private_data;
1140 char buf[32];
1141 unsigned int len;
1142
1143 len = sprintf(buf, "%d\n", sc->spec_config.count);
1144 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1145}
1146
1147static ssize_t write_file_spectral_count(struct file *file,
1148 const char __user *user_buf,
1149 size_t count, loff_t *ppos)
1150{ 1029{
1151 struct ath_softc *sc = file->private_data; 1030#define PHY_ERR(s, p) \
1152 unsigned long val; 1031 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
1153 char buf[32]; 1032 sc->debug.stats.rxstats.phy_err_stats[p]);
1154 ssize_t len;
1155
1156 len = min(count, sizeof(buf) - 1);
1157 if (copy_from_user(buf, user_buf, len))
1158 return -EFAULT;
1159
1160 buf[len] = '\0';
1161 if (kstrtoul(buf, 0, &val))
1162 return -EINVAL;
1163
1164 if (val < 0 || val > 255)
1165 return -EINVAL;
1166
1167 sc->spec_config.count = val;
1168 return count;
1169}
1170
1171static const struct file_operations fops_spectral_count = {
1172 .read = read_file_spectral_count,
1173 .write = write_file_spectral_count,
1174 .open = simple_open,
1175 .owner = THIS_MODULE,
1176 .llseek = default_llseek,
1177};
1178
1179static ssize_t read_file_spectral_period(struct file *file,
1180 char __user *user_buf,
1181 size_t count, loff_t *ppos)
1182{
1183 struct ath_softc *sc = file->private_data;
1184 char buf[32];
1185 unsigned int len;
1186
1187 len = sprintf(buf, "%d\n", sc->spec_config.period);
1188 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1189}
1190
1191static ssize_t write_file_spectral_period(struct file *file,
1192 const char __user *user_buf,
1193 size_t count, loff_t *ppos)
1194{
1195 struct ath_softc *sc = file->private_data;
1196 unsigned long val;
1197 char buf[32];
1198 ssize_t len;
1199
1200 len = min(count, sizeof(buf) - 1);
1201 if (copy_from_user(buf, user_buf, len))
1202 return -EFAULT;
1203
1204 buf[len] = '\0';
1205 if (kstrtoul(buf, 0, &val))
1206 return -EINVAL;
1207
1208 if (val < 0 || val > 255)
1209 return -EINVAL;
1210
1211 sc->spec_config.period = val;
1212 return count;
1213}
1214
1215static const struct file_operations fops_spectral_period = {
1216 .read = read_file_spectral_period,
1217 .write = write_file_spectral_period,
1218 .open = simple_open,
1219 .owner = THIS_MODULE,
1220 .llseek = default_llseek,
1221};
1222 1033
1223static ssize_t read_file_spectral_fft_period(struct file *file,
1224 char __user *user_buf,
1225 size_t count, loff_t *ppos)
1226{
1227 struct ath_softc *sc = file->private_data; 1034 struct ath_softc *sc = file->private_data;
1228 char buf[32]; 1035 char *buf;
1229 unsigned int len; 1036 unsigned int len = 0, size = 1600;
1037 ssize_t retval = 0;
1230 1038
1231 len = sprintf(buf, "%d\n", sc->spec_config.fft_period); 1039 buf = kzalloc(size, GFP_KERNEL);
1232 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1040 if (buf == NULL)
1233} 1041 return -ENOMEM;
1234 1042
1235static ssize_t write_file_spectral_fft_period(struct file *file, 1043 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
1236 const char __user *user_buf, 1044 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
1237 size_t count, loff_t *ppos) 1045 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
1238{ 1046 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
1239 struct ath_softc *sc = file->private_data; 1047 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
1240 unsigned long val; 1048 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
1241 char buf[32]; 1049 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
1242 ssize_t len; 1050 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
1051 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
1052 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
1053 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
1054 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
1055 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
1056 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
1057 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
1058 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
1059 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
1060 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
1061 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
1062 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
1063 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
1064 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
1065 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
1066 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
1067 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
1068 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
1243 1069
1244 len = min(count, sizeof(buf) - 1); 1070 if (len > size)
1245 if (copy_from_user(buf, user_buf, len)) 1071 len = size;
1246 return -EFAULT;
1247 1072
1248 buf[len] = '\0'; 1073 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1249 if (kstrtoul(buf, 0, &val)) 1074 kfree(buf);
1250 return -EINVAL;
1251 1075
1252 if (val < 0 || val > 15) 1076 return retval;
1253 return -EINVAL;
1254 1077
1255 sc->spec_config.fft_period = val; 1078#undef PHY_ERR
1256 return count;
1257} 1079}
1258 1080
1259static const struct file_operations fops_spectral_fft_period = { 1081static const struct file_operations fops_phy_err = {
1260 .read = read_file_spectral_fft_period, 1082 .read = read_file_phy_err,
1261 .write = write_file_spectral_fft_period,
1262 .open = simple_open, 1083 .open = simple_open,
1263 .owner = THIS_MODULE, 1084 .owner = THIS_MODULE,
1264 .llseek = default_llseek, 1085 .llseek = default_llseek,
1265}; 1086};
1266 1087
1267static struct dentry *create_buf_file_handler(const char *filename,
1268 struct dentry *parent,
1269 umode_t mode,
1270 struct rchan_buf *buf,
1271 int *is_global)
1272{
1273 struct dentry *buf_file;
1274
1275 buf_file = debugfs_create_file(filename, mode, parent, buf,
1276 &relay_file_operations);
1277 *is_global = 1;
1278 return buf_file;
1279}
1280
1281static int remove_buf_file_handler(struct dentry *dentry)
1282{
1283 debugfs_remove(dentry);
1284
1285 return 0;
1286}
1287
1288void ath_debug_send_fft_sample(struct ath_softc *sc,
1289 struct fft_sample_tlv *fft_sample_tlv)
1290{
1291 int length;
1292 if (!sc->rfs_chan_spec_scan)
1293 return;
1294
1295 length = __be16_to_cpu(fft_sample_tlv->length) +
1296 sizeof(*fft_sample_tlv);
1297 relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, length);
1298}
1299
1300static struct rchan_callbacks rfs_spec_scan_cb = {
1301 .create_buf_file = create_buf_file_handler,
1302 .remove_buf_file = remove_buf_file_handler,
1303};
1304
1305
1306static ssize_t read_file_regidx(struct file *file, char __user *user_buf, 1088static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
1307 size_t count, loff_t *ppos) 1089 size_t count, loff_t *ppos)
1308{ 1090{
@@ -1569,86 +1351,6 @@ static const struct file_operations fops_btcoex = {
1569}; 1351};
1570#endif 1352#endif
1571 1353
1572static ssize_t read_file_node_stat(struct file *file, char __user *user_buf,
1573 size_t count, loff_t *ppos)
1574{
1575 struct ath_node *an = file->private_data;
1576 struct ath_softc *sc = an->sc;
1577 struct ath_atx_tid *tid;
1578 struct ath_atx_ac *ac;
1579 struct ath_txq *txq;
1580 u32 len = 0, size = 4096;
1581 char *buf;
1582 size_t retval;
1583 int tidno, acno;
1584
1585 buf = kzalloc(size, GFP_KERNEL);
1586 if (buf == NULL)
1587 return -ENOMEM;
1588
1589 if (!an->sta->ht_cap.ht_supported) {
1590 len = scnprintf(buf, size, "%s\n",
1591 "HT not supported");
1592 goto exit;
1593 }
1594
1595 len = scnprintf(buf, size, "Max-AMPDU: %d\n",
1596 an->maxampdu);
1597 len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n",
1598 an->mpdudensity);
1599
1600 len += scnprintf(buf + len, size - len,
1601 "%2s%7s\n", "AC", "SCHED");
1602
1603 for (acno = 0, ac = &an->ac[acno];
1604 acno < IEEE80211_NUM_ACS; acno++, ac++) {
1605 txq = ac->txq;
1606 ath_txq_lock(sc, txq);
1607 len += scnprintf(buf + len, size - len,
1608 "%2d%7d\n",
1609 acno, ac->sched);
1610 ath_txq_unlock(sc, txq);
1611 }
1612
1613 len += scnprintf(buf + len, size - len,
1614 "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
1615 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
1616 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
1617
1618 for (tidno = 0, tid = &an->tid[tidno];
1619 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
1620 txq = tid->ac->txq;
1621 ath_txq_lock(sc, txq);
1622 len += scnprintf(buf + len, size - len,
1623 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
1624 tid->tidno, tid->seq_start, tid->seq_next,
1625 tid->baw_size, tid->baw_head, tid->baw_tail,
1626 tid->bar_index, tid->sched, tid->paused);
1627 ath_txq_unlock(sc, txq);
1628 }
1629exit:
1630 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1631 kfree(buf);
1632
1633 return retval;
1634}
1635
1636static const struct file_operations fops_node_stat = {
1637 .read = read_file_node_stat,
1638 .open = simple_open,
1639 .owner = THIS_MODULE,
1640 .llseek = default_llseek,
1641};
1642
1643void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
1644 struct ieee80211_vif *vif,
1645 struct ieee80211_sta *sta,
1646 struct dentry *dir)
1647{
1648 struct ath_node *an = (struct ath_node *)sta->drv_priv;
1649 debugfs_create_file("node_stat", S_IRUGO, dir, an, &fops_node_stat);
1650}
1651
1652/* Ethtool support for get-stats */ 1354/* Ethtool support for get-stats */
1653 1355
1654#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 1356#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
@@ -1772,117 +1474,9 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
1772 1474
1773void ath9k_deinit_debug(struct ath_softc *sc) 1475void ath9k_deinit_debug(struct ath_softc *sc)
1774{ 1476{
1775 if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) { 1477 ath9k_spectral_deinit_debug(sc);
1776 relay_close(sc->rfs_chan_spec_scan);
1777 sc->rfs_chan_spec_scan = NULL;
1778 }
1779}
1780
1781static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
1782 size_t count, loff_t *ppos)
1783{
1784 struct ath_softc *sc = file->private_data;
1785 char buf[3];
1786 unsigned int len;
1787
1788 len = sprintf(buf, "%d\n", sc->tx99_state);
1789 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1790}
1791
1792static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
1793 size_t count, loff_t *ppos)
1794{
1795 struct ath_softc *sc = file->private_data;
1796 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1797 char buf[32];
1798 bool start;
1799 ssize_t len;
1800 int r;
1801
1802 if (sc->nvifs > 1)
1803 return -EOPNOTSUPP;
1804
1805 len = min(count, sizeof(buf) - 1);
1806 if (copy_from_user(buf, user_buf, len))
1807 return -EFAULT;
1808
1809 if (strtobool(buf, &start))
1810 return -EINVAL;
1811
1812 if (start == sc->tx99_state) {
1813 if (!start)
1814 return count;
1815 ath_dbg(common, XMIT, "Resetting TX99\n");
1816 ath9k_tx99_deinit(sc);
1817 }
1818
1819 if (!start) {
1820 ath9k_tx99_deinit(sc);
1821 return count;
1822 }
1823
1824 r = ath9k_tx99_init(sc);
1825 if (r)
1826 return r;
1827
1828 return count;
1829}
1830
1831static const struct file_operations fops_tx99 = {
1832 .read = read_file_tx99,
1833 .write = write_file_tx99,
1834 .open = simple_open,
1835 .owner = THIS_MODULE,
1836 .llseek = default_llseek,
1837};
1838
1839static ssize_t read_file_tx99_power(struct file *file,
1840 char __user *user_buf,
1841 size_t count, loff_t *ppos)
1842{
1843 struct ath_softc *sc = file->private_data;
1844 char buf[32];
1845 unsigned int len;
1846
1847 len = sprintf(buf, "%d (%d dBm)\n",
1848 sc->tx99_power,
1849 sc->tx99_power / 2);
1850
1851 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1852} 1478}
1853 1479
1854static ssize_t write_file_tx99_power(struct file *file,
1855 const char __user *user_buf,
1856 size_t count, loff_t *ppos)
1857{
1858 struct ath_softc *sc = file->private_data;
1859 int r;
1860 u8 tx_power;
1861
1862 r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
1863 if (r)
1864 return r;
1865
1866 if (tx_power > MAX_RATE_POWER)
1867 return -EINVAL;
1868
1869 sc->tx99_power = tx_power;
1870
1871 ath9k_ps_wakeup(sc);
1872 ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
1873 ath9k_ps_restore(sc);
1874
1875 return count;
1876}
1877
1878static const struct file_operations fops_tx99_power = {
1879 .read = read_file_tx99_power,
1880 .write = write_file_tx99_power,
1881 .open = simple_open,
1882 .owner = THIS_MODULE,
1883 .llseek = default_llseek,
1884};
1885
1886int ath9k_init_debug(struct ath_hw *ah) 1480int ath9k_init_debug(struct ath_hw *ah)
1887{ 1481{
1888 struct ath_common *common = ath9k_hw_common(ah); 1482 struct ath_common *common = ath9k_hw_common(ah);
@@ -1899,6 +1493,8 @@ int ath9k_init_debug(struct ath_hw *ah)
1899#endif 1493#endif
1900 1494
1901 ath9k_dfs_init_debug(sc); 1495 ath9k_dfs_init_debug(sc);
1496 ath9k_tx99_init_debug(sc);
1497 ath9k_spectral_init_debug(sc);
1902 1498
1903 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1499 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
1904 &fops_dma); 1500 &fops_dma);
@@ -1922,6 +1518,8 @@ int ath9k_init_debug(struct ath_hw *ah)
1922 &fops_reset); 1518 &fops_reset);
1923 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, 1519 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
1924 &fops_recv); 1520 &fops_recv);
1521 debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc,
1522 &fops_phy_err);
1925 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1523 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
1926 &ah->rxchainmask); 1524 &ah->rxchainmask);
1927 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1525 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
@@ -1945,23 +1543,6 @@ int ath9k_init_debug(struct ath_hw *ah)
1945 &fops_base_eeprom); 1543 &fops_base_eeprom);
1946 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1544 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1947 &fops_modal_eeprom); 1545 &fops_modal_eeprom);
1948 sc->rfs_chan_spec_scan = relay_open("spectral_scan",
1949 sc->debug.debugfs_phy,
1950 1024, 256, &rfs_spec_scan_cb,
1951 NULL);
1952 debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
1953 sc->debug.debugfs_phy, sc,
1954 &fops_spec_scan_ctl);
1955 debugfs_create_file("spectral_short_repeat", S_IRUSR | S_IWUSR,
1956 sc->debug.debugfs_phy, sc,
1957 &fops_spectral_short_repeat);
1958 debugfs_create_file("spectral_count", S_IRUSR | S_IWUSR,
1959 sc->debug.debugfs_phy, sc, &fops_spectral_count);
1960 debugfs_create_file("spectral_period", S_IRUSR | S_IWUSR,
1961 sc->debug.debugfs_phy, sc, &fops_spectral_period);
1962 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR,
1963 sc->debug.debugfs_phy, sc,
1964 &fops_spectral_fft_period);
1965 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1546 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1966 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1547 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1967 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1548 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
@@ -1974,15 +1555,6 @@ int ath9k_init_debug(struct ath_hw *ah)
1974 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1555 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
1975 &fops_btcoex); 1556 &fops_btcoex);
1976#endif 1557#endif
1977 if (config_enabled(CONFIG_ATH9K_TX99) &&
1978 AR_SREV_9300_20_OR_LATER(ah)) {
1979 debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
1980 sc->debug.debugfs_phy, sc,
1981 &fops_tx99);
1982 debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
1983 sc->debug.debugfs_phy, sc,
1984 &fops_tx99_power);
1985 }
1986 1558
1987 return 0; 1559 return 0;
1988} 1560}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index d6e3fa4299a4..cc7a025d833e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -27,11 +27,13 @@ struct fft_sample_tlv;
27 27
28#ifdef CONFIG_ATH9K_DEBUGFS 28#ifdef CONFIG_ATH9K_DEBUGFS
29#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++ 29#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
30#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++)
30#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++ 31#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
31#define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++ 32#define ANT_STAT_INC(i, c) sc->debug.stats.ant_stats[i].c++
32#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++; 33#define ANT_LNA_INC(i, c) sc->debug.stats.ant_stats[i].lna_recv_cnt[c]++;
33#else 34#else
34#define TX_STAT_INC(q, c) do { } while (0) 35#define TX_STAT_INC(q, c) do { } while (0)
36#define RX_STAT_INC(c)
35#define RESET_STAT_INC(sc, type) do { } while (0) 37#define RESET_STAT_INC(sc, type) do { } while (0)
36#define ANT_STAT_INC(i, c) do { } while (0) 38#define ANT_STAT_INC(i, c) do { } while (0)
37#define ANT_LNA_INC(i, c) do { } while (0) 39#define ANT_LNA_INC(i, c) do { } while (0)
@@ -42,6 +44,7 @@ enum ath_reset_type {
42 RESET_TYPE_BB_WATCHDOG, 44 RESET_TYPE_BB_WATCHDOG,
43 RESET_TYPE_FATAL_INT, 45 RESET_TYPE_FATAL_INT,
44 RESET_TYPE_TX_ERROR, 46 RESET_TYPE_TX_ERROR,
47 RESET_TYPE_TX_GTT,
45 RESET_TYPE_TX_HANG, 48 RESET_TYPE_TX_HANG,
46 RESET_TYPE_PLL_HANG, 49 RESET_TYPE_PLL_HANG,
47 RESET_TYPE_MAC_HANG, 50 RESET_TYPE_MAC_HANG,
@@ -201,7 +204,23 @@ struct ath_tx_stats {
201 TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ 204 TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \
202 } while(0) 205 } while(0)
203 206
204#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) 207struct ath_rx_rate_stats {
208 struct {
209 u32 ht20_cnt;
210 u32 ht40_cnt;
211 u32 sgi_cnt;
212 u32 lgi_cnt;
213 } ht_stats[24];
214
215 struct {
216 u32 ofdm_cnt;
217 } ofdm_stats[8];
218
219 struct {
220 u32 cck_lp_cnt;
221 u32 cck_sp_cnt;
222 } cck_stats[4];
223};
205 224
206/** 225/**
207 * struct ath_rx_stats - RX Statistics 226 * struct ath_rx_stats - RX Statistics
@@ -292,14 +311,12 @@ void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
292 struct ieee80211_vif *vif, 311 struct ieee80211_vif *vif,
293 struct ieee80211_sta *sta, 312 struct ieee80211_sta *sta,
294 struct dentry *dir); 313 struct dentry *dir);
295void ath_debug_send_fft_sample(struct ath_softc *sc,
296 struct fft_sample_tlv *fft_sample);
297void ath9k_debug_stat_ant(struct ath_softc *sc, 314void ath9k_debug_stat_ant(struct ath_softc *sc,
298 struct ath_hw_antcomb_conf *div_ant_conf, 315 struct ath_hw_antcomb_conf *div_ant_conf,
299 int main_rssi_avg, int alt_rssi_avg); 316 int main_rssi_avg, int alt_rssi_avg);
300#else 317void ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause);
301 318
302#define RX_STAT_INC(c) /* NOP */ 319#else
303 320
304static inline int ath9k_init_debug(struct ath_hw *ah) 321static inline int ath9k_init_debug(struct ath_hw *ah)
305{ 322{
@@ -331,6 +348,23 @@ static inline void ath9k_debug_stat_ant(struct ath_softc *sc,
331 348
332} 349}
333 350
351static inline void
352ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)
353{
354}
355
334#endif /* CONFIG_ATH9K_DEBUGFS */ 356#endif /* CONFIG_ATH9K_DEBUGFS */
335 357
358#ifdef CONFIG_ATH9K_STATION_STATISTICS
359void ath_debug_rate_stats(struct ath_softc *sc,
360 struct ath_rx_status *rs,
361 struct sk_buff *skb);
362#else
363static inline void ath_debug_rate_stats(struct ath_softc *sc,
364 struct ath_rx_status *rs,
365 struct sk_buff *skb)
366{
367}
368#endif /* CONFIG_ATH9K_STATION_STATISTICS */
369
336#endif /* DEBUG_H */ 370#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c
new file mode 100644
index 000000000000..d76e6e0120d2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -0,0 +1,269 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19/*************/
20/* node_aggr */
21/*************/
22
23static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf,
24 size_t count, loff_t *ppos)
25{
26 struct ath_node *an = file->private_data;
27 struct ath_softc *sc = an->sc;
28 struct ath_atx_tid *tid;
29 struct ath_atx_ac *ac;
30 struct ath_txq *txq;
31 u32 len = 0, size = 4096;
32 char *buf;
33 size_t retval;
34 int tidno, acno;
35
36 buf = kzalloc(size, GFP_KERNEL);
37 if (buf == NULL)
38 return -ENOMEM;
39
40 if (!an->sta->ht_cap.ht_supported) {
41 len = scnprintf(buf, size, "%s\n",
42 "HT not supported");
43 goto exit;
44 }
45
46 len = scnprintf(buf, size, "Max-AMPDU: %d\n",
47 an->maxampdu);
48 len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n",
49 an->mpdudensity);
50
51 len += scnprintf(buf + len, size - len,
52 "%2s%7s\n", "AC", "SCHED");
53
54 for (acno = 0, ac = &an->ac[acno];
55 acno < IEEE80211_NUM_ACS; acno++, ac++) {
56 txq = ac->txq;
57 ath_txq_lock(sc, txq);
58 len += scnprintf(buf + len, size - len,
59 "%2d%7d\n",
60 acno, ac->sched);
61 ath_txq_unlock(sc, txq);
62 }
63
64 len += scnprintf(buf + len, size - len,
65 "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
66 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
67 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
68
69 for (tidno = 0, tid = &an->tid[tidno];
70 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
71 txq = tid->ac->txq;
72 ath_txq_lock(sc, txq);
73 if (tid->active) {
74 len += scnprintf(buf + len, size - len,
75 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
76 tid->tidno,
77 tid->seq_start,
78 tid->seq_next,
79 tid->baw_size,
80 tid->baw_head,
81 tid->baw_tail,
82 tid->bar_index,
83 tid->sched,
84 tid->paused);
85 }
86 ath_txq_unlock(sc, txq);
87 }
88exit:
89 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
90 kfree(buf);
91
92 return retval;
93}
94
95static const struct file_operations fops_node_aggr = {
96 .read = read_file_node_aggr,
97 .open = simple_open,
98 .owner = THIS_MODULE,
99 .llseek = default_llseek,
100};
101
102/*************/
103/* node_recv */
104/*************/
105
106void ath_debug_rate_stats(struct ath_softc *sc,
107 struct ath_rx_status *rs,
108 struct sk_buff *skb)
109{
110 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
111 struct ath_hw *ah = sc->sc_ah;
112 struct ieee80211_rx_status *rxs;
113 struct ath_rx_rate_stats *rstats;
114 struct ieee80211_sta *sta;
115 struct ath_node *an;
116
117 if (!ieee80211_is_data(hdr->frame_control))
118 return;
119
120 rcu_read_lock();
121
122 sta = ieee80211_find_sta_by_ifaddr(sc->hw, hdr->addr2, NULL);
123 if (!sta)
124 goto exit;
125
126 an = (struct ath_node *) sta->drv_priv;
127 rstats = &an->rx_rate_stats;
128 rxs = IEEE80211_SKB_RXCB(skb);
129
130 if (IS_HT_RATE(rs->rs_rate)) {
131 if (rxs->rate_idx >= ARRAY_SIZE(rstats->ht_stats))
132 goto exit;
133
134 if (rxs->flag & RX_FLAG_40MHZ)
135 rstats->ht_stats[rxs->rate_idx].ht40_cnt++;
136 else
137 rstats->ht_stats[rxs->rate_idx].ht20_cnt++;
138
139 if (rxs->flag & RX_FLAG_SHORT_GI)
140 rstats->ht_stats[rxs->rate_idx].sgi_cnt++;
141 else
142 rstats->ht_stats[rxs->rate_idx].lgi_cnt++;
143
144 goto exit;
145 }
146
147 if (IS_CCK_RATE(rs->rs_rate)) {
148 if (rxs->flag & RX_FLAG_SHORTPRE)
149 rstats->cck_stats[rxs->rate_idx].cck_sp_cnt++;
150 else
151 rstats->cck_stats[rxs->rate_idx].cck_lp_cnt++;
152
153 goto exit;
154 }
155
156 if (IS_OFDM_RATE(rs->rs_rate)) {
157 if (ah->curchan->chan->band == IEEE80211_BAND_2GHZ)
158 rstats->ofdm_stats[rxs->rate_idx - 4].ofdm_cnt++;
159 else
160 rstats->ofdm_stats[rxs->rate_idx].ofdm_cnt++;
161 }
162exit:
163 rcu_read_unlock();
164}
165
166#define PRINT_CCK_RATE(str, i, sp) \
167 do { \
168 len += scnprintf(buf + len, size - len, \
169 "%11s : %10u\n", \
170 str, \
171 (sp) ? rstats->cck_stats[i].cck_sp_cnt : \
172 rstats->cck_stats[i].cck_lp_cnt); \
173 } while (0)
174
175#define PRINT_OFDM_RATE(str, i) \
176 do { \
177 len += scnprintf(buf + len, size - len, \
178 "%11s : %10u\n", \
179 str, \
180 rstats->ofdm_stats[i].ofdm_cnt); \
181 } while (0)
182
183static ssize_t read_file_node_recv(struct file *file, char __user *user_buf,
184 size_t count, loff_t *ppos)
185{
186 struct ath_node *an = file->private_data;
187 struct ath_softc *sc = an->sc;
188 struct ath_hw *ah = sc->sc_ah;
189 struct ath_rx_rate_stats *rstats;
190 struct ieee80211_sta *sta = an->sta;
191 enum ieee80211_band band;
192 u32 len = 0, size = 4096;
193 char *buf;
194 size_t retval;
195 int i;
196
197 buf = kzalloc(size, GFP_KERNEL);
198 if (buf == NULL)
199 return -ENOMEM;
200
201 band = ah->curchan->chan->band;
202 rstats = &an->rx_rate_stats;
203
204 if (!sta->ht_cap.ht_supported)
205 goto legacy;
206
207 len += scnprintf(buf + len, size - len,
208 "%24s%10s%10s%10s\n",
209 "HT20", "HT40", "SGI", "LGI");
210
211 for (i = 0; i < 24; i++) {
212 len += scnprintf(buf + len, size - len,
213 "%8s%3u : %10u%10u%10u%10u\n",
214 "MCS", i,
215 rstats->ht_stats[i].ht20_cnt,
216 rstats->ht_stats[i].ht40_cnt,
217 rstats->ht_stats[i].sgi_cnt,
218 rstats->ht_stats[i].lgi_cnt);
219 }
220
221 len += scnprintf(buf + len, size - len, "\n");
222
223legacy:
224 if (band == IEEE80211_BAND_2GHZ) {
225 PRINT_CCK_RATE("CCK-1M/LP", 0, false);
226 PRINT_CCK_RATE("CCK-2M/LP", 1, false);
227 PRINT_CCK_RATE("CCK-5.5M/LP", 2, false);
228 PRINT_CCK_RATE("CCK-11M/LP", 3, false);
229
230 PRINT_CCK_RATE("CCK-2M/SP", 1, true);
231 PRINT_CCK_RATE("CCK-5.5M/SP", 2, true);
232 PRINT_CCK_RATE("CCK-11M/SP", 3, true);
233 }
234
235 PRINT_OFDM_RATE("OFDM-6M", 0);
236 PRINT_OFDM_RATE("OFDM-9M", 1);
237 PRINT_OFDM_RATE("OFDM-12M", 2);
238 PRINT_OFDM_RATE("OFDM-18M", 3);
239 PRINT_OFDM_RATE("OFDM-24M", 4);
240 PRINT_OFDM_RATE("OFDM-36M", 5);
241 PRINT_OFDM_RATE("OFDM-48M", 6);
242 PRINT_OFDM_RATE("OFDM-54M", 7);
243
244 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
245 kfree(buf);
246
247 return retval;
248}
249
250#undef PRINT_OFDM_RATE
251#undef PRINT_CCK_RATE
252
253static const struct file_operations fops_node_recv = {
254 .read = read_file_node_recv,
255 .open = simple_open,
256 .owner = THIS_MODULE,
257 .llseek = default_llseek,
258};
259
260void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
261 struct ieee80211_vif *vif,
262 struct ieee80211_sta *sta,
263 struct dentry *dir)
264{
265 struct ath_node *an = (struct ath_node *)sta->drv_priv;
266
267 debugfs_create_file("node_aggr", S_IRUGO, dir, an, &fops_node_aggr);
268 debugfs_create_file("node_recv", S_IRUGO, dir, an, &fops_node_recv);
269}
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
index 7187d3671512..857bb28b3894 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -158,8 +158,8 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
158 return; 158 return;
159 } 159 }
160 160
161 ard.rssi = rs->rs_rssi_ctl0; 161 ard.rssi = rs->rs_rssi_ctl[0];
162 ard.ext_rssi = rs->rs_rssi_ext0; 162 ard.ext_rssi = rs->rs_rssi_ext[0];
163 163
164 /* 164 /*
165 * hardware stores this as 8 bit signed value. 165 * hardware stores this as 8 bit signed value.
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index b4091716e9b3..07b806c56c56 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1085,31 +1085,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1085 1085
1086static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1086static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1087{ 1087{
1088#define EEP_MAP4K_SPURCHAN \ 1088 return ah->eeprom.map4k.modalHeader.spurChans[i].spurChan;
1089 (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
1090 struct ath_common *common = ath9k_hw_common(ah);
1091
1092 u16 spur_val = AR_NO_SPUR;
1093
1094 ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
1095 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1096
1097 switch (ah->config.spurmode) {
1098 case SPUR_DISABLE:
1099 break;
1100 case SPUR_ENABLE_IOCTL:
1101 spur_val = ah->config.spurchans[i][is2GHz];
1102 ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
1103 spur_val);
1104 break;
1105 case SPUR_ENABLE_EEPROM:
1106 spur_val = EEP_MAP4K_SPURCHAN;
1107 break;
1108 }
1109
1110 return spur_val;
1111
1112#undef EEP_MAP4K_SPURCHAN
1113} 1089}
1114 1090
1115const struct eeprom_ops eep_4k_ops = { 1091const struct eeprom_ops eep_4k_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index e1d0c217c104..5ba1385c9838 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -1004,31 +1004,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
1004static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, 1004static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
1005 u16 i, bool is2GHz) 1005 u16 i, bool is2GHz)
1006{ 1006{
1007#define EEP_MAP9287_SPURCHAN \ 1007 return ah->eeprom.map9287.modalHeader.spurChans[i].spurChan;
1008 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1009
1010 struct ath_common *common = ath9k_hw_common(ah);
1011 u16 spur_val = AR_NO_SPUR;
1012
1013 ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
1014 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1015
1016 switch (ah->config.spurmode) {
1017 case SPUR_DISABLE:
1018 break;
1019 case SPUR_ENABLE_IOCTL:
1020 spur_val = ah->config.spurchans[i][is2GHz];
1021 ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
1022 spur_val);
1023 break;
1024 case SPUR_ENABLE_EEPROM:
1025 spur_val = EEP_MAP9287_SPURCHAN;
1026 break;
1027 }
1028
1029 return spur_val;
1030
1031#undef EEP_MAP9287_SPURCHAN
1032} 1008}
1033 1009
1034const struct eeprom_ops eep_ar9287_ops = { 1010const struct eeprom_ops eep_ar9287_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 39107e31e79a..3218ca994746 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -1348,31 +1348,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1348 1348
1349static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1349static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1350{ 1350{
1351#define EEP_DEF_SPURCHAN \ 1351 return ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan;
1352 (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
1353 struct ath_common *common = ath9k_hw_common(ah);
1354
1355 u16 spur_val = AR_NO_SPUR;
1356
1357 ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n",
1358 i, is2GHz, ah->config.spurchans[i][is2GHz]);
1359
1360 switch (ah->config.spurmode) {
1361 case SPUR_DISABLE:
1362 break;
1363 case SPUR_ENABLE_IOCTL:
1364 spur_val = ah->config.spurchans[i][is2GHz];
1365 ath_dbg(common, ANI, "Getting spur val from new loc. %d\n",
1366 spur_val);
1367 break;
1368 case SPUR_ENABLE_EEPROM:
1369 spur_val = EEP_DEF_SPURCHAN;
1370 break;
1371 }
1372
1373 return spur_val;
1374
1375#undef EEP_DEF_SPURCHAN
1376} 1352}
1377 1353
1378const struct eeprom_ops eep_def_ops = { 1354const struct eeprom_ops eep_def_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index c34f21241da9..b1956bf6e01e 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -157,36 +157,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
157 } 157 }
158} 158}
159 159
160static void ath9k_gen_timer_start(struct ath_hw *ah,
161 struct ath_gen_timer *timer,
162 u32 trig_timeout,
163 u32 timer_period)
164{
165 ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
166
167 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
168 ath9k_hw_disable_interrupts(ah);
169 ah->imask |= ATH9K_INT_GENTIMER;
170 ath9k_hw_set_interrupts(ah);
171 ath9k_hw_enable_interrupts(ah);
172 }
173}
174
175static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
176{
177 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
178
179 ath9k_hw_gen_timer_stop(ah, timer);
180
181 /* if no timer is enabled, turn off interrupt mask */
182 if (timer_table->timer_mask.val == 0) {
183 ath9k_hw_disable_interrupts(ah);
184 ah->imask &= ~ATH9K_INT_GENTIMER;
185 ath9k_hw_set_interrupts(ah);
186 ath9k_hw_enable_interrupts(ah);
187 }
188}
189
190static void ath_mci_ftp_adjust(struct ath_softc *sc) 160static void ath_mci_ftp_adjust(struct ath_softc *sc)
191{ 161{
192 struct ath_btcoex *btcoex = &sc->btcoex; 162 struct ath_btcoex *btcoex = &sc->btcoex;
@@ -257,19 +227,9 @@ static void ath_btcoex_period_timer(unsigned long data)
257 227
258 spin_unlock_bh(&btcoex->btcoex_lock); 228 spin_unlock_bh(&btcoex->btcoex_lock);
259 229
260 /* 230 if (btcoex->btcoex_period != btcoex->btcoex_no_stomp)
261 * btcoex_period is in msec while (btocex/btscan_)no_stomp are in usec, 231 mod_timer(&btcoex->no_stomp_timer,
262 * ensure that we properly convert btcoex_period to usec 232 jiffies + msecs_to_jiffies(timer_period));
263 * for any comparision with (btcoex/btscan_)no_stomp.
264 */
265 if (btcoex->btcoex_period * 1000 != btcoex->btcoex_no_stomp) {
266 if (btcoex->hw_timer_enabled)
267 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
268
269 ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
270 timer_period * 10);
271 btcoex->hw_timer_enabled = true;
272 }
273 233
274 ath9k_ps_restore(sc); 234 ath9k_ps_restore(sc);
275 235
@@ -282,7 +242,7 @@ skip_hw_wakeup:
282 * Generic tsf based hw timer which configures weight 242 * Generic tsf based hw timer which configures weight
283 * registers to time slice between wlan and bt traffic 243 * registers to time slice between wlan and bt traffic
284 */ 244 */
285static void ath_btcoex_no_stomp_timer(void *arg) 245static void ath_btcoex_no_stomp_timer(unsigned long arg)
286{ 246{
287 struct ath_softc *sc = (struct ath_softc *)arg; 247 struct ath_softc *sc = (struct ath_softc *)arg;
288 struct ath_hw *ah = sc->sc_ah; 248 struct ath_hw *ah = sc->sc_ah;
@@ -311,24 +271,18 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
311 struct ath_btcoex *btcoex = &sc->btcoex; 271 struct ath_btcoex *btcoex = &sc->btcoex;
312 272
313 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; 273 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
314 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * 274 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
315 btcoex->btcoex_period / 100; 275 btcoex->btcoex_period / 100;
316 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * 276 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
317 btcoex->btcoex_period / 100; 277 btcoex->btcoex_period / 100;
318 278
319 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 279 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
320 (unsigned long) sc); 280 (unsigned long) sc);
281 setup_timer(&btcoex->no_stomp_timer, ath_btcoex_no_stomp_timer,
282 (unsigned long) sc);
321 283
322 spin_lock_init(&btcoex->btcoex_lock); 284 spin_lock_init(&btcoex->btcoex_lock);
323 285
324 btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
325 ath_btcoex_no_stomp_timer,
326 ath_btcoex_no_stomp_timer,
327 (void *) sc, AR_FIRST_NDP_TIMER);
328
329 if (!btcoex->no_stomp_timer)
330 return -ENOMEM;
331
332 return 0; 286 return 0;
333} 287}
334 288
@@ -343,10 +297,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
343 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); 297 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
344 298
345 /* make sure duty cycle timer is also stopped when resuming */ 299 /* make sure duty cycle timer is also stopped when resuming */
346 if (btcoex->hw_timer_enabled) { 300 del_timer_sync(&btcoex->no_stomp_timer);
347 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
348 btcoex->hw_timer_enabled = false;
349 }
350 301
351 btcoex->bt_priority_cnt = 0; 302 btcoex->bt_priority_cnt = 0;
352 btcoex->bt_priority_time = jiffies; 303 btcoex->bt_priority_time = jiffies;
@@ -363,24 +314,16 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
363void ath9k_btcoex_timer_pause(struct ath_softc *sc) 314void ath9k_btcoex_timer_pause(struct ath_softc *sc)
364{ 315{
365 struct ath_btcoex *btcoex = &sc->btcoex; 316 struct ath_btcoex *btcoex = &sc->btcoex;
366 struct ath_hw *ah = sc->sc_ah;
367 317
368 del_timer_sync(&btcoex->period_timer); 318 del_timer_sync(&btcoex->period_timer);
369 319 del_timer_sync(&btcoex->no_stomp_timer);
370 if (btcoex->hw_timer_enabled) {
371 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
372 btcoex->hw_timer_enabled = false;
373 }
374} 320}
375 321
376void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) 322void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
377{ 323{
378 struct ath_btcoex *btcoex = &sc->btcoex; 324 struct ath_btcoex *btcoex = &sc->btcoex;
379 325
380 if (btcoex->hw_timer_enabled) { 326 del_timer_sync(&btcoex->no_stomp_timer);
381 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
382 btcoex->hw_timer_enabled = false;
383 }
384} 327}
385 328
386u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) 329u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
@@ -400,12 +343,6 @@ u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
400 343
401void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status) 344void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status)
402{ 345{
403 struct ath_hw *ah = sc->sc_ah;
404
405 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
406 if (status & ATH9K_INT_GENTIMER)
407 ath_gen_timer_isr(sc->sc_ah);
408
409 if (status & ATH9K_INT_MCI) 346 if (status & ATH9K_INT_MCI)
410 ath_mci_intr(sc); 347 ath_mci_intr(sc);
411} 348}
@@ -447,10 +384,6 @@ void ath9k_deinit_btcoex(struct ath_softc *sc)
447{ 384{
448 struct ath_hw *ah = sc->sc_ah; 385 struct ath_hw *ah = sc->sc_ah;
449 386
450 if ((sc->btcoex.no_stomp_timer) &&
451 ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
452 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
453
454 if (ath9k_hw_mci_is_enabled(ah)) 387 if (ath9k_hw_mci_is_enabled(ah))
455 ath_mci_cleanup(sc); 388 ath_mci_cleanup(sc);
456} 389}
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 055d7c25e090..58da3468d1f0 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -600,10 +600,15 @@ void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
600struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv); 600struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv);
601 601
602#ifdef CONFIG_MAC80211_LEDS 602#ifdef CONFIG_MAC80211_LEDS
603void ath9k_configure_leds(struct ath9k_htc_priv *priv);
603void ath9k_init_leds(struct ath9k_htc_priv *priv); 604void ath9k_init_leds(struct ath9k_htc_priv *priv);
604void ath9k_deinit_leds(struct ath9k_htc_priv *priv); 605void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
605void ath9k_led_work(struct work_struct *work); 606void ath9k_led_work(struct work_struct *work);
606#else 607#else
608static inline void ath9k_configure_leds(struct ath9k_htc_priv *priv)
609{
610}
611
607static inline void ath9k_init_leds(struct ath9k_htc_priv *priv) 612static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
608{ 613{
609} 614}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index e0c03bd64182..8b5757734596 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -70,11 +70,11 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
70 struct ath9k_beacon_state bs; 70 struct ath9k_beacon_state bs;
71 enum ath9k_int imask = 0; 71 enum ath9k_int imask = 0;
72 int dtimperiod, dtimcount, sleepduration; 72 int dtimperiod, dtimcount, sleepduration;
73 int cfpperiod, cfpcount, bmiss_timeout; 73 int bmiss_timeout;
74 u32 nexttbtt = 0, intval, tsftu; 74 u32 nexttbtt = 0, intval, tsftu;
75 __be32 htc_imask = 0; 75 __be32 htc_imask = 0;
76 u64 tsf; 76 u64 tsf;
77 int num_beacons, offset, dtim_dec_count, cfp_dec_count; 77 int num_beacons, offset, dtim_dec_count;
78 int ret __attribute__ ((unused)); 78 int ret __attribute__ ((unused));
79 u8 cmd_rsp; 79 u8 cmd_rsp;
80 80
@@ -84,7 +84,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
84 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); 84 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
85 85
86 /* 86 /*
87 * Setup dtim and cfp parameters according to 87 * Setup dtim parameters according to
88 * last beacon we received (which may be none). 88 * last beacon we received (which may be none).
89 */ 89 */
90 dtimperiod = bss_conf->dtim_period; 90 dtimperiod = bss_conf->dtim_period;
@@ -93,8 +93,6 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
93 dtimcount = 1; 93 dtimcount = 1;
94 if (dtimcount >= dtimperiod) /* NB: sanity check */ 94 if (dtimcount >= dtimperiod) /* NB: sanity check */
95 dtimcount = 0; 95 dtimcount = 0;
96 cfpperiod = 1; /* NB: no PCF support yet */
97 cfpcount = 0;
98 96
99 sleepduration = intval; 97 sleepduration = intval;
100 if (sleepduration <= 0) 98 if (sleepduration <= 0)
@@ -102,7 +100,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
102 100
103 /* 101 /*
104 * Pull nexttbtt forward to reflect the current 102 * Pull nexttbtt forward to reflect the current
105 * TSF and calculate dtim+cfp state for the result. 103 * TSF and calculate dtim state for the result.
106 */ 104 */
107 tsf = ath9k_hw_gettsf64(priv->ah); 105 tsf = ath9k_hw_gettsf64(priv->ah);
108 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 106 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
@@ -115,26 +113,14 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
115 113
116 /* DTIM Beacon every dtimperiod Beacon */ 114 /* DTIM Beacon every dtimperiod Beacon */
117 dtim_dec_count = num_beacons % dtimperiod; 115 dtim_dec_count = num_beacons % dtimperiod;
118 /* CFP every cfpperiod DTIM Beacon */
119 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
120 if (dtim_dec_count)
121 cfp_dec_count++;
122
123 dtimcount -= dtim_dec_count; 116 dtimcount -= dtim_dec_count;
124 if (dtimcount < 0) 117 if (dtimcount < 0)
125 dtimcount += dtimperiod; 118 dtimcount += dtimperiod;
126 119
127 cfpcount -= cfp_dec_count; 120 bs.bs_intval = TU_TO_USEC(intval);
128 if (cfpcount < 0) 121 bs.bs_nexttbtt = TU_TO_USEC(nexttbtt);
129 cfpcount += cfpperiod; 122 bs.bs_dtimperiod = dtimperiod * bs.bs_intval;
130 123 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount * bs.bs_intval;
131 bs.bs_intval = intval;
132 bs.bs_nexttbtt = nexttbtt;
133 bs.bs_dtimperiod = dtimperiod*intval;
134 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
135 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
136 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
137 bs.bs_cfpmaxduration = 0;
138 124
139 /* 125 /*
140 * Calculate the number of consecutive beacons to miss* before taking 126 * Calculate the number of consecutive beacons to miss* before taking
@@ -161,7 +147,8 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
161 * XXX fixed at 100ms 147 * XXX fixed at 100ms
162 */ 148 */
163 149
164 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration); 150 bs.bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
151 sleepduration));
165 if (bs.bs_sleepduration > bs.bs_dtimperiod) 152 if (bs.bs_sleepduration > bs.bs_dtimperiod)
166 bs.bs_sleepduration = bs.bs_dtimperiod; 153 bs.bs_sleepduration = bs.bs_dtimperiod;
167 154
@@ -170,10 +157,8 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
170 157
171 ath_dbg(common, CONFIG, "intval: %u tsf: %llu tsftu: %u\n", 158 ath_dbg(common, CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
172 intval, tsf, tsftu); 159 intval, tsf, tsftu);
173 ath_dbg(common, CONFIG, 160 ath_dbg(common, CONFIG, "bmiss: %u sleep: %u\n",
174 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", 161 bs.bs_bmissthreshold, bs.bs_sleepduration);
175 bs.bs_bmissthreshold, bs.bs_sleepduration,
176 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
177 162
178 /* Set the computed STA beacon timers */ 163 /* Set the computed STA beacon timers */
179 164
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 105582d6b714..50f74a2a4cf8 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -255,6 +255,17 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
255 cancel_work_sync(&priv->led_work); 255 cancel_work_sync(&priv->led_work);
256} 256}
257 257
258
259void ath9k_configure_leds(struct ath9k_htc_priv *priv)
260{
261 /* Configure gpio 1 for output */
262 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
263 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
264 /* LED off, active low */
265 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
266
267}
268
258void ath9k_init_leds(struct ath9k_htc_priv *priv) 269void ath9k_init_leds(struct ath9k_htc_priv *priv)
259{ 270{
260 int ret; 271 int ret;
@@ -268,11 +279,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
268 else 279 else
269 priv->ah->led_pin = ATH_LED_PIN_DEF; 280 priv->ah->led_pin = ATH_LED_PIN_DEF;
270 281
271 /* Configure gpio 1 for output */ 282 ath9k_configure_leds(priv);
272 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
273 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
274 /* LED off, active low */
275 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
276 283
277 snprintf(priv->led_name, sizeof(priv->led_name), 284 snprintf(priv->led_name, sizeof(priv->led_name),
278 "ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); 285 "ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index c3676bf1d6c4..f4e1de20d99c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -748,7 +748,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
748 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 748 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
749 749
750 hw->queues = 4; 750 hw->queues = 4;
751 hw->channel_change_time = 5000;
752 hw->max_listen_interval = 1; 751 hw->max_listen_interval = 1;
753 752
754 hw->vif_data_size = sizeof(struct ath9k_htc_vif); 753 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
@@ -1000,6 +999,8 @@ int ath9k_htc_resume(struct htc_target *htc_handle)
1000 999
1001 ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid, 1000 ret = ath9k_init_htc_services(priv, priv->ah->hw_version.devid,
1002 priv->ah->hw_version.usbdev); 1001 priv->ah->hw_version.usbdev);
1002 ath9k_configure_leds(priv);
1003
1003 return ret; 1004 return ret;
1004} 1005}
1005#endif 1006#endif
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index c028df76b564..12e0f32a4905 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1075,9 +1075,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
1075 1075
1076 last_rssi = priv->rx.last_rssi; 1076 last_rssi = priv->rx.last_rssi;
1077 1077
1078 if (ieee80211_is_beacon(hdr->frame_control) && 1078 if (ath_is_mybeacon(common, hdr)) {
1079 !is_zero_ether_addr(common->curbssid) &&
1080 ether_addr_equal(hdr->addr3, common->curbssid)) {
1081 s8 rssi = rxbuf->rxstatus.rs_rssi; 1079 s8 rssi = rxbuf->rxstatus.rs_rssi;
1082 1080
1083 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) 1081 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 4f9378ddf07f..a47ea8423f1e 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -49,9 +49,10 @@ static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
49 return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal); 49 return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
50} 50}
51 51
52static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) 52static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked,
53 u32 *sync_cause_p)
53{ 54{
54 return ath9k_hw_ops(ah)->get_isr(ah, masked); 55 return ath9k_hw_ops(ah)->get_isr(ah, masked, sync_cause_p);
55} 56}
56 57
57static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds, 58static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds,
@@ -106,6 +107,21 @@ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
106 107
107/* Private hardware call ops */ 108/* Private hardware call ops */
108 109
110static inline void ath9k_hw_init_hang_checks(struct ath_hw *ah)
111{
112 ath9k_hw_private_ops(ah)->init_hang_checks(ah);
113}
114
115static inline bool ath9k_hw_detect_mac_hang(struct ath_hw *ah)
116{
117 return ath9k_hw_private_ops(ah)->detect_mac_hang(ah);
118}
119
120static inline bool ath9k_hw_detect_bb_hang(struct ath_hw *ah)
121{
122 return ath9k_hw_private_ops(ah)->detect_bb_hang(ah);
123}
124
109/* PHY ops */ 125/* PHY ops */
110 126
111static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah, 127static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
@@ -231,4 +247,31 @@ static inline void ath9k_hw_set_radar_params(struct ath_hw *ah)
231 ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf); 247 ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf);
232} 248}
233 249
250static inline void ath9k_hw_init_cal_settings(struct ath_hw *ah)
251{
252 ath9k_hw_private_ops(ah)->init_cal_settings(ah);
253}
254
255static inline u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
256 struct ath9k_channel *chan)
257{
258 return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
259}
260
261static inline void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
262{
263 if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
264 return;
265
266 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
267}
268
269static inline void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
270{
271 if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
272 return;
273
274 ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
275}
276
234#endif /* ATH9K_HW_OPS_H */ 277#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8918035da3a3..fbf43c05713f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -17,6 +17,8 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/time.h>
21#include <linux/bitops.h>
20#include <asm/unaligned.h> 22#include <asm/unaligned.h>
21 23
22#include "hw.h" 24#include "hw.h"
@@ -35,99 +37,6 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
35MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); 37MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
36MODULE_LICENSE("Dual BSD/GPL"); 38MODULE_LICENSE("Dual BSD/GPL");
37 39
38static int __init ath9k_init(void)
39{
40 return 0;
41}
42module_init(ath9k_init);
43
44static void __exit ath9k_exit(void)
45{
46 return;
47}
48module_exit(ath9k_exit);
49
50/* Private hardware callbacks */
51
52static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
53{
54 ath9k_hw_private_ops(ah)->init_cal_settings(ah);
55}
56
57static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
58 struct ath9k_channel *chan)
59{
60 return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
61}
62
63static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
64{
65 if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
66 return;
67
68 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
69}
70
71static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
72{
73 /* You will not have this callback if using the old ANI */
74 if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
75 return;
76
77 ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
78}
79
80/********************/
81/* Helper Functions */
82/********************/
83
84#ifdef CONFIG_ATH9K_DEBUGFS
85
86void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
87{
88 struct ath_softc *sc = common->priv;
89 if (sync_cause)
90 sc->debug.stats.istats.sync_cause_all++;
91 if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
92 sc->debug.stats.istats.sync_rtc_irq++;
93 if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
94 sc->debug.stats.istats.sync_mac_irq++;
95 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
96 sc->debug.stats.istats.eeprom_illegal_access++;
97 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
98 sc->debug.stats.istats.apb_timeout++;
99 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
100 sc->debug.stats.istats.pci_mode_conflict++;
101 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
102 sc->debug.stats.istats.host1_fatal++;
103 if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
104 sc->debug.stats.istats.host1_perr++;
105 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
106 sc->debug.stats.istats.trcv_fifo_perr++;
107 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
108 sc->debug.stats.istats.radm_cpl_ep++;
109 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
110 sc->debug.stats.istats.radm_cpl_dllp_abort++;
111 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
112 sc->debug.stats.istats.radm_cpl_tlp_abort++;
113 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
114 sc->debug.stats.istats.radm_cpl_ecrc_err++;
115 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
116 sc->debug.stats.istats.radm_cpl_timeout++;
117 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
118 sc->debug.stats.istats.local_timeout++;
119 if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
120 sc->debug.stats.istats.pm_access++;
121 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
122 sc->debug.stats.istats.mac_awake++;
123 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
124 sc->debug.stats.istats.mac_asleep++;
125 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
126 sc->debug.stats.istats.mac_sleep_access++;
127}
128#endif
129
130
131static void ath9k_hw_set_clockrate(struct ath_hw *ah) 40static void ath9k_hw_set_clockrate(struct ath_hw *ah)
132{ 41{
133 struct ath_common *common = ath9k_hw_common(ah); 42 struct ath_common *common = ath9k_hw_common(ah);
@@ -336,6 +245,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
336 case AR9300_DEVID_QCA955X: 245 case AR9300_DEVID_QCA955X:
337 ah->hw_version.macVersion = AR_SREV_VERSION_9550; 246 ah->hw_version.macVersion = AR_SREV_VERSION_9550;
338 return; 247 return;
248 case AR9300_DEVID_AR953X:
249 ah->hw_version.macVersion = AR_SREV_VERSION_9531;
250 return;
339 } 251 }
340 252
341 val = REG_READ(ah, AR_SREV) & AR_SREV_ID; 253 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
@@ -437,23 +349,22 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah)
437 349
438static void ath9k_hw_init_config(struct ath_hw *ah) 350static void ath9k_hw_init_config(struct ath_hw *ah)
439{ 351{
440 int i; 352 struct ath_common *common = ath9k_hw_common(ah);
441 353
442 ah->config.dma_beacon_response_time = 1; 354 ah->config.dma_beacon_response_time = 1;
443 ah->config.sw_beacon_response_time = 6; 355 ah->config.sw_beacon_response_time = 6;
444 ah->config.additional_swba_backoff = 0;
445 ah->config.ack_6mb = 0x0;
446 ah->config.cwm_ignore_extcca = 0; 356 ah->config.cwm_ignore_extcca = 0;
447 ah->config.pcie_clock_req = 0;
448 ah->config.analog_shiftreg = 1; 357 ah->config.analog_shiftreg = 1;
449 358
450 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
451 ah->config.spurchans[i][0] = AR_NO_SPUR;
452 ah->config.spurchans[i][1] = AR_NO_SPUR;
453 }
454
455 ah->config.rx_intr_mitigation = true; 359 ah->config.rx_intr_mitigation = true;
456 ah->config.pcieSerDesWrite = true; 360
361 if (AR_SREV_9300_20_OR_LATER(ah)) {
362 ah->config.rimt_last = 500;
363 ah->config.rimt_first = 2000;
364 } else {
365 ah->config.rimt_last = 250;
366 ah->config.rimt_first = 700;
367 }
457 368
458 /* 369 /*
459 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 370 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -473,6 +384,24 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
473 */ 384 */
474 if (num_possible_cpus() > 1) 385 if (num_possible_cpus() > 1)
475 ah->config.serialize_regmode = SER_REG_MODE_AUTO; 386 ah->config.serialize_regmode = SER_REG_MODE_AUTO;
387
388 if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
389 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
390 ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
391 !ah->is_pciexpress)) {
392 ah->config.serialize_regmode = SER_REG_MODE_ON;
393 } else {
394 ah->config.serialize_regmode = SER_REG_MODE_OFF;
395 }
396 }
397
398 ath_dbg(common, RESET, "serialize_regmode is %d\n",
399 ah->config.serialize_regmode);
400
401 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
402 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
403 else
404 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
476} 405}
477 406
478static void ath9k_hw_init_defaults(struct ath_hw *ah) 407static void ath9k_hw_init_defaults(struct ath_hw *ah)
@@ -485,16 +414,24 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
485 ah->hw_version.magic = AR5416_MAGIC; 414 ah->hw_version.magic = AR5416_MAGIC;
486 ah->hw_version.subvendorid = 0; 415 ah->hw_version.subvendorid = 0;
487 416
488 ah->atim_window = 0; 417 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE |
489 ah->sta_id1_defaults = 418 AR_STA_ID1_MCAST_KSRCH;
490 AR_STA_ID1_CRPT_MIC_ENABLE |
491 AR_STA_ID1_MCAST_KSRCH;
492 if (AR_SREV_9100(ah)) 419 if (AR_SREV_9100(ah))
493 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; 420 ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
421
494 ah->slottime = ATH9K_SLOT_TIME_9; 422 ah->slottime = ATH9K_SLOT_TIME_9;
495 ah->globaltxtimeout = (u32) -1; 423 ah->globaltxtimeout = (u32) -1;
496 ah->power_mode = ATH9K_PM_UNDEFINED; 424 ah->power_mode = ATH9K_PM_UNDEFINED;
497 ah->htc_reset_init = true; 425 ah->htc_reset_init = true;
426
427 ah->ani_function = ATH9K_ANI_ALL;
428 if (!AR_SREV_9300_20_OR_LATER(ah))
429 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
430
431 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
432 ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
433 else
434 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
498} 435}
499 436
500static int ath9k_hw_init_macaddr(struct ath_hw *ah) 437static int ath9k_hw_init_macaddr(struct ath_hw *ah)
@@ -548,11 +485,11 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
548 * EEPROM needs to be initialized before we do this. 485 * EEPROM needs to be initialized before we do this.
549 * This is required for regulatory compliance. 486 * This is required for regulatory compliance.
550 */ 487 */
551 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 488 if (AR_SREV_9300_20_OR_LATER(ah)) {
552 u16 regdmn = ah->eep_ops->get_eeprom(ah, EEP_REG_0); 489 u16 regdmn = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
553 if ((regdmn & 0xF0) == CTL_FCC) { 490 if ((regdmn & 0xF0) == CTL_FCC) {
554 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_2GHZ; 491 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_2GHZ;
555 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_5GHZ; 492 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_FCC_5GHZ;
556 } 493 }
557 } 494 }
558 495
@@ -576,6 +513,31 @@ static int __ath9k_hw_init(struct ath_hw *ah)
576 513
577 ath9k_hw_read_revisions(ah); 514 ath9k_hw_read_revisions(ah);
578 515
516 switch (ah->hw_version.macVersion) {
517 case AR_SREV_VERSION_5416_PCI:
518 case AR_SREV_VERSION_5416_PCIE:
519 case AR_SREV_VERSION_9160:
520 case AR_SREV_VERSION_9100:
521 case AR_SREV_VERSION_9280:
522 case AR_SREV_VERSION_9285:
523 case AR_SREV_VERSION_9287:
524 case AR_SREV_VERSION_9271:
525 case AR_SREV_VERSION_9300:
526 case AR_SREV_VERSION_9330:
527 case AR_SREV_VERSION_9485:
528 case AR_SREV_VERSION_9340:
529 case AR_SREV_VERSION_9462:
530 case AR_SREV_VERSION_9550:
531 case AR_SREV_VERSION_9565:
532 case AR_SREV_VERSION_9531:
533 break;
534 default:
535 ath_err(common,
536 "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
537 ah->hw_version.macVersion, ah->hw_version.macRev);
538 return -EOPNOTSUPP;
539 }
540
579 /* 541 /*
580 * Read back AR_WA into a permanent copy and set bits 14 and 17. 542 * Read back AR_WA into a permanent copy and set bits 14 and 17.
581 * We need to do this to avoid RMW of this register. We cannot 543 * We need to do this to avoid RMW of this register. We cannot
@@ -609,50 +571,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
609 return -EIO; 571 return -EIO;
610 } 572 }
611 573
612 if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
613 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
614 ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
615 !ah->is_pciexpress)) {
616 ah->config.serialize_regmode =
617 SER_REG_MODE_ON;
618 } else {
619 ah->config.serialize_regmode =
620 SER_REG_MODE_OFF;
621 }
622 }
623
624 ath_dbg(common, RESET, "serialize_regmode is %d\n",
625 ah->config.serialize_regmode);
626
627 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
628 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
629 else
630 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
631
632 switch (ah->hw_version.macVersion) {
633 case AR_SREV_VERSION_5416_PCI:
634 case AR_SREV_VERSION_5416_PCIE:
635 case AR_SREV_VERSION_9160:
636 case AR_SREV_VERSION_9100:
637 case AR_SREV_VERSION_9280:
638 case AR_SREV_VERSION_9285:
639 case AR_SREV_VERSION_9287:
640 case AR_SREV_VERSION_9271:
641 case AR_SREV_VERSION_9300:
642 case AR_SREV_VERSION_9330:
643 case AR_SREV_VERSION_9485:
644 case AR_SREV_VERSION_9340:
645 case AR_SREV_VERSION_9462:
646 case AR_SREV_VERSION_9550:
647 case AR_SREV_VERSION_9565:
648 break;
649 default:
650 ath_err(common,
651 "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
652 ah->hw_version.macVersion, ah->hw_version.macRev);
653 return -EOPNOTSUPP;
654 }
655
656 if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || 574 if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) ||
657 AR_SREV_9330(ah) || AR_SREV_9550(ah)) 575 AR_SREV_9330(ah) || AR_SREV_9550(ah))
658 ah->is_pciexpress = false; 576 ah->is_pciexpress = false;
@@ -660,10 +578,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
660 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 578 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
661 ath9k_hw_init_cal_settings(ah); 579 ath9k_hw_init_cal_settings(ah);
662 580
663 ah->ani_function = ATH9K_ANI_ALL;
664 if (!AR_SREV_9300_20_OR_LATER(ah))
665 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
666
667 if (!ah->is_pciexpress) 581 if (!ah->is_pciexpress)
668 ath9k_hw_disablepcie(ah); 582 ath9k_hw_disablepcie(ah);
669 583
@@ -682,15 +596,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
682 return r; 596 return r;
683 } 597 }
684 598
685 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) 599 ath9k_hw_init_hang_checks(ah);
686 ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
687 else
688 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
689
690 if (AR_SREV_9330(ah))
691 ah->bb_watchdog_timeout_ms = 85;
692 else
693 ah->bb_watchdog_timeout_ms = 25;
694 600
695 common->state = ATH_HW_INITIALIZED; 601 common->state = ATH_HW_INITIALIZED;
696 602
@@ -723,6 +629,7 @@ int ath9k_hw_init(struct ath_hw *ah)
723 case AR9300_DEVID_AR9462: 629 case AR9300_DEVID_AR9462:
724 case AR9485_DEVID_AR1111: 630 case AR9485_DEVID_AR1111:
725 case AR9300_DEVID_AR9565: 631 case AR9300_DEVID_AR9565:
632 case AR9300_DEVID_AR953X:
726 break; 633 break;
727 default: 634 default:
728 if (common->bus_ops->ath_bus_type == ATH_USB) 635 if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -858,7 +765,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
858 /* program BB PLL phase_shift */ 765 /* program BB PLL phase_shift */
859 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 766 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
860 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); 767 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1);
861 } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) { 768 } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
862 u32 regval, pll2_divint, pll2_divfrac, refdiv; 769 u32 regval, pll2_divint, pll2_divfrac, refdiv;
863 770
864 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); 771 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
@@ -868,9 +775,15 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
868 udelay(100); 775 udelay(100);
869 776
870 if (ah->is_clk_25mhz) { 777 if (ah->is_clk_25mhz) {
871 pll2_divint = 0x54; 778 if (AR_SREV_9531(ah)) {
872 pll2_divfrac = 0x1eb85; 779 pll2_divint = 0x1c;
873 refdiv = 3; 780 pll2_divfrac = 0xa3d2;
781 refdiv = 1;
782 } else {
783 pll2_divint = 0x54;
784 pll2_divfrac = 0x1eb85;
785 refdiv = 3;
786 }
874 } else { 787 } else {
875 if (AR_SREV_9340(ah)) { 788 if (AR_SREV_9340(ah)) {
876 pll2_divint = 88; 789 pll2_divint = 88;
@@ -884,7 +797,10 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
884 } 797 }
885 798
886 regval = REG_READ(ah, AR_PHY_PLL_MODE); 799 regval = REG_READ(ah, AR_PHY_PLL_MODE);
887 regval |= (0x1 << 16); 800 if (AR_SREV_9531(ah))
801 regval |= (0x1 << 22);
802 else
803 regval |= (0x1 << 16);
888 REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 804 REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
889 udelay(100); 805 udelay(100);
890 806
@@ -894,14 +810,33 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
894 810
895 regval = REG_READ(ah, AR_PHY_PLL_MODE); 811 regval = REG_READ(ah, AR_PHY_PLL_MODE);
896 if (AR_SREV_9340(ah)) 812 if (AR_SREV_9340(ah))
897 regval = (regval & 0x80071fff) | (0x1 << 30) | 813 regval = (regval & 0x80071fff) |
898 (0x1 << 13) | (0x4 << 26) | (0x18 << 19); 814 (0x1 << 30) |
815 (0x1 << 13) |
816 (0x4 << 26) |
817 (0x18 << 19);
818 else if (AR_SREV_9531(ah))
819 regval = (regval & 0x01c00fff) |
820 (0x1 << 31) |
821 (0x2 << 29) |
822 (0xa << 25) |
823 (0x1 << 19) |
824 (0x6 << 12);
899 else 825 else
900 regval = (regval & 0x80071fff) | (0x3 << 30) | 826 regval = (regval & 0x80071fff) |
901 (0x1 << 13) | (0x4 << 26) | (0x60 << 19); 827 (0x3 << 30) |
828 (0x1 << 13) |
829 (0x4 << 26) |
830 (0x60 << 19);
902 REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 831 REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
903 REG_WRITE(ah, AR_PHY_PLL_MODE, 832
904 REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); 833 if (AR_SREV_9531(ah))
834 REG_WRITE(ah, AR_PHY_PLL_MODE,
835 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff);
836 else
837 REG_WRITE(ah, AR_PHY_PLL_MODE,
838 REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
839
905 udelay(1000); 840 udelay(1000);
906 } 841 }
907 842
@@ -1281,6 +1216,42 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
1281 *coef_exponent = coef_exp - 16; 1216 *coef_exponent = coef_exp - 16;
1282} 1217}
1283 1218
1219/* AR9330 WAR:
1220 * call external reset function to reset WMAC if:
1221 * - doing a cold reset
1222 * - we have pending frames in the TX queues.
1223 */
1224static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
1225{
1226 int i, npend = 0;
1227
1228 for (i = 0; i < AR_NUM_QCU; i++) {
1229 npend = ath9k_hw_numtxpending(ah, i);
1230 if (npend)
1231 break;
1232 }
1233
1234 if (ah->external_reset &&
1235 (npend || type == ATH9K_RESET_COLD)) {
1236 int reset_err = 0;
1237
1238 ath_dbg(ath9k_hw_common(ah), RESET,
1239 "reset MAC via external reset\n");
1240
1241 reset_err = ah->external_reset();
1242 if (reset_err) {
1243 ath_err(ath9k_hw_common(ah),
1244 "External reset failed, err=%d\n",
1245 reset_err);
1246 return false;
1247 }
1248
1249 REG_WRITE(ah, AR_RTC_RESET, 1);
1250 }
1251
1252 return true;
1253}
1254
1284static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) 1255static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1285{ 1256{
1286 u32 rst_flags; 1257 u32 rst_flags;
@@ -1331,38 +1302,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1331 } 1302 }
1332 1303
1333 if (AR_SREV_9330(ah)) { 1304 if (AR_SREV_9330(ah)) {
1334 int npend = 0; 1305 if (!ath9k_hw_ar9330_reset_war(ah, type))
1335 int i; 1306 return false;
1336
1337 /* AR9330 WAR:
1338 * call external reset function to reset WMAC if:
1339 * - doing a cold reset
1340 * - we have pending frames in the TX queues
1341 */
1342
1343 for (i = 0; i < AR_NUM_QCU; i++) {
1344 npend = ath9k_hw_numtxpending(ah, i);
1345 if (npend)
1346 break;
1347 }
1348
1349 if (ah->external_reset &&
1350 (npend || type == ATH9K_RESET_COLD)) {
1351 int reset_err = 0;
1352
1353 ath_dbg(ath9k_hw_common(ah), RESET,
1354 "reset MAC via external reset\n");
1355
1356 reset_err = ah->external_reset();
1357 if (reset_err) {
1358 ath_err(ath9k_hw_common(ah),
1359 "External reset failed, err=%d\n",
1360 reset_err);
1361 return false;
1362 }
1363
1364 REG_WRITE(ah, AR_RTC_RESET, 1);
1365 }
1366 } 1307 }
1367 1308
1368 if (ath9k_hw_mci_is_enabled(ah)) 1309 if (ath9k_hw_mci_is_enabled(ah))
@@ -1372,7 +1313,12 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1372 1313
1373 REGWRITE_BUFFER_FLUSH(ah); 1314 REGWRITE_BUFFER_FLUSH(ah);
1374 1315
1375 udelay(50); 1316 if (AR_SREV_9300_20_OR_LATER(ah))
1317 udelay(50);
1318 else if (AR_SREV_9100(ah))
1319 udelay(10000);
1320 else
1321 udelay(100);
1376 1322
1377 REG_WRITE(ah, AR_RTC_RC, 0); 1323 REG_WRITE(ah, AR_RTC_RC, 0);
1378 if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { 1324 if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
@@ -1408,8 +1354,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1408 1354
1409 REGWRITE_BUFFER_FLUSH(ah); 1355 REGWRITE_BUFFER_FLUSH(ah);
1410 1356
1411 if (!AR_SREV_9300_20_OR_LATER(ah)) 1357 udelay(2);
1412 udelay(2);
1413 1358
1414 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 1359 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1415 REG_WRITE(ah, AR_RC, 0); 1360 REG_WRITE(ah, AR_RC, 0);
@@ -1485,7 +1430,6 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1485 if (AR_SREV_9330(ah)) 1430 if (AR_SREV_9330(ah))
1486 ar9003_hw_internal_regulator_apply(ah); 1431 ar9003_hw_internal_regulator_apply(ah);
1487 ath9k_hw_init_pll(ah, chan); 1432 ath9k_hw_init_pll(ah, chan);
1488 ath9k_hw_set_rfmode(ah, chan);
1489 1433
1490 return true; 1434 return true;
1491} 1435}
@@ -1501,8 +1445,9 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1501 int r; 1445 int r;
1502 1446
1503 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { 1447 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
1504 band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); 1448 u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags;
1505 mode_diff = (chan->channelFlags != ah->curchan->channelFlags); 1449 band_switch = !!(flags_diff & CHANNEL_5GHZ);
1450 mode_diff = !!(flags_diff & ~CHANNEL_HT);
1506 } 1451 }
1507 1452
1508 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 1453 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1573,76 +1518,6 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
1573 } 1518 }
1574} 1519}
1575 1520
1576static bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states,
1577 int *hang_state, int *hang_pos)
1578{
1579 static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */
1580 u32 chain_state, dcs_pos, i;
1581
1582 for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) {
1583 chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f;
1584 for (i = 0; i < 3; i++) {
1585 if (chain_state == dcu_chain_state[i]) {
1586 *hang_state = chain_state;
1587 *hang_pos = dcs_pos;
1588 return true;
1589 }
1590 }
1591 }
1592 return false;
1593}
1594
1595#define DCU_COMPLETE_STATE 1
1596#define DCU_COMPLETE_STATE_MASK 0x3
1597#define NUM_STATUS_READS 50
1598static bool ath9k_hw_detect_mac_hang(struct ath_hw *ah)
1599{
1600 u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4;
1601 u32 i, hang_pos, hang_state, num_state = 6;
1602
1603 comp_state = REG_READ(ah, AR_DMADBG_6);
1604
1605 if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) {
1606 ath_dbg(ath9k_hw_common(ah), RESET,
1607 "MAC Hang signature not found at DCU complete\n");
1608 return false;
1609 }
1610
1611 chain_state = REG_READ(ah, dcs_reg);
1612 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
1613 goto hang_check_iter;
1614
1615 dcs_reg = AR_DMADBG_5;
1616 num_state = 4;
1617 chain_state = REG_READ(ah, dcs_reg);
1618 if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos))
1619 goto hang_check_iter;
1620
1621 ath_dbg(ath9k_hw_common(ah), RESET,
1622 "MAC Hang signature 1 not found\n");
1623 return false;
1624
1625hang_check_iter:
1626 ath_dbg(ath9k_hw_common(ah), RESET,
1627 "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n",
1628 chain_state, comp_state, hang_state, hang_pos);
1629
1630 for (i = 0; i < NUM_STATUS_READS; i++) {
1631 chain_state = REG_READ(ah, dcs_reg);
1632 chain_state = (chain_state >> (5 * hang_pos)) & 0x1f;
1633 comp_state = REG_READ(ah, AR_DMADBG_6);
1634
1635 if (((comp_state & DCU_COMPLETE_STATE_MASK) !=
1636 DCU_COMPLETE_STATE) ||
1637 (chain_state != hang_state))
1638 return false;
1639 }
1640
1641 ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n");
1642
1643 return true;
1644}
1645
1646void ath9k_hw_check_nav(struct ath_hw *ah) 1521void ath9k_hw_check_nav(struct ath_hw *ah)
1647{ 1522{
1648 struct ath_common *common = ath9k_hw_common(ah); 1523 struct ath_common *common = ath9k_hw_common(ah);
@@ -1717,7 +1592,6 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah,
1717 1592
1718 REG_RMW(ah, AR_STA_ID1, macStaId1 1593 REG_RMW(ah, AR_STA_ID1, macStaId1
1719 | AR_STA_ID1_RTS_USE_DEF 1594 | AR_STA_ID1_RTS_USE_DEF
1720 | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
1721 | ah->sta_id1_defaults, 1595 | ah->sta_id1_defaults,
1722 ~AR_STA_ID1_SADH_MASK); 1596 ~AR_STA_ID1_SADH_MASK);
1723 ath_hw_setbssidmask(common); 1597 ath_hw_setbssidmask(common);
@@ -1776,7 +1650,7 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
1776 } 1650 }
1777#ifdef __BIG_ENDIAN 1651#ifdef __BIG_ENDIAN
1778 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || 1652 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
1779 AR_SREV_9550(ah)) 1653 AR_SREV_9550(ah) || AR_SREV_9531(ah))
1780 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); 1654 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
1781 else 1655 else
1782 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 1656 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
@@ -1814,7 +1688,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1814 * If cross-band fcc is not supoprted, bail out if channelFlags differ. 1688 * If cross-band fcc is not supoprted, bail out if channelFlags differ.
1815 */ 1689 */
1816 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && 1690 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
1817 chan->channelFlags != ah->curchan->channelFlags) 1691 ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT))
1818 goto fail; 1692 goto fail;
1819 1693
1820 if (!ath9k_hw_check_alive(ah)) 1694 if (!ath9k_hw_check_alive(ah))
@@ -1855,10 +1729,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1855 struct ath9k_hw_cal_data *caldata, bool fastcc) 1729 struct ath9k_hw_cal_data *caldata, bool fastcc)
1856{ 1730{
1857 struct ath_common *common = ath9k_hw_common(ah); 1731 struct ath_common *common = ath9k_hw_common(ah);
1732 struct timespec ts;
1858 u32 saveLedState; 1733 u32 saveLedState;
1859 u32 saveDefAntenna; 1734 u32 saveDefAntenna;
1860 u32 macStaId1; 1735 u32 macStaId1;
1861 u64 tsf = 0; 1736 u64 tsf = 0;
1737 s64 usec = 0;
1862 int r; 1738 int r;
1863 bool start_mci_reset = false; 1739 bool start_mci_reset = false;
1864 bool save_fullsleep = ah->chip_fullsleep; 1740 bool save_fullsleep = ah->chip_fullsleep;
@@ -1901,10 +1777,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1901 1777
1902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1778 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
1903 1779
1904 /* For chips on which RTC reset is done, save TSF before it gets cleared */ 1780 /* Save TSF before chip reset, a cold reset clears it */
1905 if (AR_SREV_9100(ah) || 1781 tsf = ath9k_hw_gettsf64(ah);
1906 (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 1782 getrawmonotonic(&ts);
1907 tsf = ath9k_hw_gettsf64(ah); 1783 usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
1908 1784
1909 saveLedState = REG_READ(ah, AR_CFG_LED) & 1785 saveLedState = REG_READ(ah, AR_CFG_LED) &
1910 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 1786 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1937,8 +1813,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1937 } 1813 }
1938 1814
1939 /* Restore TSF */ 1815 /* Restore TSF */
1940 if (tsf) 1816 getrawmonotonic(&ts);
1941 ath9k_hw_settsf64(ah, tsf); 1817 usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000 - usec;
1818 ath9k_hw_settsf64(ah, tsf + usec);
1942 1819
1943 if (AR_SREV_9280_20_OR_LATER(ah)) 1820 if (AR_SREV_9280_20_OR_LATER(ah))
1944 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1821 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
@@ -1950,6 +1827,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1950 if (r) 1827 if (r)
1951 return r; 1828 return r;
1952 1829
1830 ath9k_hw_set_rfmode(ah, chan);
1831
1953 if (ath9k_hw_mci_is_enabled(ah)) 1832 if (ath9k_hw_mci_is_enabled(ah))
1954 ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); 1833 ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep);
1955 1834
@@ -2005,8 +1884,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2005 REG_WRITE(ah, AR_OBS, 8); 1884 REG_WRITE(ah, AR_OBS, 8);
2006 1885
2007 if (ah->config.rx_intr_mitigation) { 1886 if (ah->config.rx_intr_mitigation) {
2008 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 1887 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
2009 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 1888 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
2010 } 1889 }
2011 1890
2012 if (ah->config.tx_intr_mitigation) { 1891 if (ah->config.tx_intr_mitigation) {
@@ -2044,10 +1923,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2044 ath9k_hw_loadnf(ah, chan); 1923 ath9k_hw_loadnf(ah, chan);
2045 ath9k_hw_start_nfcal(ah, true); 1924 ath9k_hw_start_nfcal(ah, true);
2046 1925
2047 if (AR_SREV_9300_20_OR_LATER(ah)) { 1926 if (AR_SREV_9300_20_OR_LATER(ah))
2048 ar9003_hw_bb_watchdog_config(ah); 1927 ar9003_hw_bb_watchdog_config(ah);
1928
1929 if (ah->config.hw_hang_checks & HW_PHYRESTART_CLC_WAR)
2049 ar9003_hw_disable_phy_restart(ah); 1930 ar9003_hw_disable_phy_restart(ah);
2050 }
2051 1931
2052 ath9k_hw_apply_gpio_override(ah); 1932 ath9k_hw_apply_gpio_override(ah);
2053 1933
@@ -2171,7 +2051,11 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah)
2171 2051
2172 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, 2052 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
2173 AR_RTC_FORCE_WAKE_EN); 2053 AR_RTC_FORCE_WAKE_EN);
2174 udelay(50); 2054
2055 if (AR_SREV_9100(ah))
2056 udelay(10000);
2057 else
2058 udelay(50);
2175 2059
2176 for (i = POWER_UP_TIME / 50; i > 0; i--) { 2060 for (i = POWER_UP_TIME / 50; i > 0; i--) {
2177 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; 2061 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
@@ -2260,9 +2144,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2260 case NL80211_IFTYPE_ADHOC: 2144 case NL80211_IFTYPE_ADHOC:
2261 REG_SET_BIT(ah, AR_TXCFG, 2145 REG_SET_BIT(ah, AR_TXCFG,
2262 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 2146 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
2263 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
2264 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
2265 flags |= AR_NDP_TIMER_EN;
2266 case NL80211_IFTYPE_MESH_POINT: 2147 case NL80211_IFTYPE_MESH_POINT:
2267 case NL80211_IFTYPE_AP: 2148 case NL80211_IFTYPE_AP:
2268 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); 2149 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
@@ -2283,7 +2164,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2283 REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period); 2164 REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
2284 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period); 2165 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
2285 REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period); 2166 REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
2286 REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
2287 2167
2288 REGWRITE_BUFFER_FLUSH(ah); 2168 REGWRITE_BUFFER_FLUSH(ah);
2289 2169
@@ -2300,12 +2180,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
2300 2180
2301 ENABLE_REGWRITE_BUFFER(ah); 2181 ENABLE_REGWRITE_BUFFER(ah);
2302 2182
2303 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); 2183 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, bs->bs_nexttbtt);
2304 2184 REG_WRITE(ah, AR_BEACON_PERIOD, bs->bs_intval);
2305 REG_WRITE(ah, AR_BEACON_PERIOD, 2185 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bs->bs_intval);
2306 TU_TO_USEC(bs->bs_intval));
2307 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
2308 TU_TO_USEC(bs->bs_intval));
2309 2186
2310 REGWRITE_BUFFER_FLUSH(ah); 2187 REGWRITE_BUFFER_FLUSH(ah);
2311 2188
@@ -2333,9 +2210,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
2333 2210
2334 ENABLE_REGWRITE_BUFFER(ah); 2211 ENABLE_REGWRITE_BUFFER(ah);
2335 2212
2336 REG_WRITE(ah, AR_NEXT_DTIM, 2213 REG_WRITE(ah, AR_NEXT_DTIM, bs->bs_nextdtim - SLEEP_SLOP);
2337 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); 2214 REG_WRITE(ah, AR_NEXT_TIM, nextTbtt - SLEEP_SLOP);
2338 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
2339 2215
2340 REG_WRITE(ah, AR_SLEEP1, 2216 REG_WRITE(ah, AR_SLEEP1,
2341 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT) 2217 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
@@ -2349,8 +2225,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
2349 REG_WRITE(ah, AR_SLEEP2, 2225 REG_WRITE(ah, AR_SLEEP2,
2350 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT)); 2226 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
2351 2227
2352 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); 2228 REG_WRITE(ah, AR_TIM_PERIOD, beaconintval);
2353 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); 2229 REG_WRITE(ah, AR_DTIM_PERIOD, dtimperiod);
2354 2230
2355 REGWRITE_BUFFER_FLUSH(ah); 2231 REGWRITE_BUFFER_FLUSH(ah);
2356 2232
@@ -2608,13 +2484,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2608 ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 2484 ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
2609 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; 2485 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
2610 2486
2611 /*
2612 * Fast channel change across bands is available
2613 * only for AR9462 and AR9565.
2614 */
2615 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
2616 pCap->hw_caps |= ATH9K_HW_CAP_FCC_BAND_SWITCH;
2617
2618 return 0; 2487 return 0;
2619} 2488}
2620 2489
@@ -2986,20 +2855,6 @@ static const struct ath_gen_timer_configuration gen_tmr_configuration[] =
2986 2855
2987/* HW generic timer primitives */ 2856/* HW generic timer primitives */
2988 2857
2989/* compute and clear index of rightmost 1 */
2990static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
2991{
2992 u32 b;
2993
2994 b = *mask;
2995 b &= (0-b);
2996 *mask &= ~b;
2997 b *= debruijn32;
2998 b >>= 27;
2999
3000 return timer_table->gen_timer_index[b];
3001}
3002
3003u32 ath9k_hw_gettsf32(struct ath_hw *ah) 2858u32 ath9k_hw_gettsf32(struct ath_hw *ah)
3004{ 2859{
3005 return REG_READ(ah, AR_TSF_L32); 2860 return REG_READ(ah, AR_TSF_L32);
@@ -3015,6 +2870,10 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
3015 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 2870 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
3016 struct ath_gen_timer *timer; 2871 struct ath_gen_timer *timer;
3017 2872
2873 if ((timer_index < AR_FIRST_NDP_TIMER) ||
2874 (timer_index >= ATH_MAX_GEN_TIMER))
2875 return NULL;
2876
3018 timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); 2877 timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
3019 if (timer == NULL) 2878 if (timer == NULL)
3020 return NULL; 2879 return NULL;
@@ -3032,23 +2891,13 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
3032 2891
3033void ath9k_hw_gen_timer_start(struct ath_hw *ah, 2892void ath9k_hw_gen_timer_start(struct ath_hw *ah,
3034 struct ath_gen_timer *timer, 2893 struct ath_gen_timer *timer,
3035 u32 trig_timeout, 2894 u32 timer_next,
3036 u32 timer_period) 2895 u32 timer_period)
3037{ 2896{
3038 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 2897 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
3039 u32 tsf, timer_next; 2898 u32 mask = 0;
3040
3041 BUG_ON(!timer_period);
3042
3043 set_bit(timer->index, &timer_table->timer_mask.timer_bits);
3044 2899
3045 tsf = ath9k_hw_gettsf32(ah); 2900 timer_table->timer_mask |= BIT(timer->index);
3046
3047 timer_next = tsf + trig_timeout;
3048
3049 ath_dbg(ath9k_hw_common(ah), BTCOEX,
3050 "current tsf %x period %x timer_next %x\n",
3051 tsf, timer_period, timer_next);
3052 2901
3053 /* 2902 /*
3054 * Program generic timer registers 2903 * Program generic timer registers
@@ -3074,10 +2923,19 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
3074 (1 << timer->index)); 2923 (1 << timer->index));
3075 } 2924 }
3076 2925
3077 /* Enable both trigger and thresh interrupt masks */ 2926 if (timer->trigger)
3078 REG_SET_BIT(ah, AR_IMR_S5, 2927 mask |= SM(AR_GENTMR_BIT(timer->index),
3079 (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | 2928 AR_IMR_S5_GENTIMER_TRIG);
3080 SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); 2929 if (timer->overflow)
2930 mask |= SM(AR_GENTMR_BIT(timer->index),
2931 AR_IMR_S5_GENTIMER_THRESH);
2932
2933 REG_SET_BIT(ah, AR_IMR_S5, mask);
2934
2935 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
2936 ah->imask |= ATH9K_INT_GENTIMER;
2937 ath9k_hw_set_interrupts(ah);
2938 }
3081} 2939}
3082EXPORT_SYMBOL(ath9k_hw_gen_timer_start); 2940EXPORT_SYMBOL(ath9k_hw_gen_timer_start);
3083 2941
@@ -3085,11 +2943,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
3085{ 2943{
3086 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 2944 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
3087 2945
3088 if ((timer->index < AR_FIRST_NDP_TIMER) ||
3089 (timer->index >= ATH_MAX_GEN_TIMER)) {
3090 return;
3091 }
3092
3093 /* Clear generic timer enable bits. */ 2946 /* Clear generic timer enable bits. */
3094 REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, 2947 REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
3095 gen_tmr_configuration[timer->index].mode_mask); 2948 gen_tmr_configuration[timer->index].mode_mask);
@@ -3109,7 +2962,12 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
3109 (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | 2962 (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
3110 SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); 2963 SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
3111 2964
3112 clear_bit(timer->index, &timer_table->timer_mask.timer_bits); 2965 timer_table->timer_mask &= ~BIT(timer->index);
2966
2967 if (timer_table->timer_mask == 0) {
2968 ah->imask &= ~ATH9K_INT_GENTIMER;
2969 ath9k_hw_set_interrupts(ah);
2970 }
3113} 2971}
3114EXPORT_SYMBOL(ath9k_hw_gen_timer_stop); 2972EXPORT_SYMBOL(ath9k_hw_gen_timer_stop);
3115 2973
@@ -3130,32 +2988,32 @@ void ath_gen_timer_isr(struct ath_hw *ah)
3130{ 2988{
3131 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 2989 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
3132 struct ath_gen_timer *timer; 2990 struct ath_gen_timer *timer;
3133 struct ath_common *common = ath9k_hw_common(ah); 2991 unsigned long trigger_mask, thresh_mask;
3134 u32 trigger_mask, thresh_mask, index; 2992 unsigned int index;
3135 2993
3136 /* get hardware generic timer interrupt status */ 2994 /* get hardware generic timer interrupt status */
3137 trigger_mask = ah->intr_gen_timer_trigger; 2995 trigger_mask = ah->intr_gen_timer_trigger;
3138 thresh_mask = ah->intr_gen_timer_thresh; 2996 thresh_mask = ah->intr_gen_timer_thresh;
3139 trigger_mask &= timer_table->timer_mask.val; 2997 trigger_mask &= timer_table->timer_mask;
3140 thresh_mask &= timer_table->timer_mask.val; 2998 thresh_mask &= timer_table->timer_mask;
3141
3142 trigger_mask &= ~thresh_mask;
3143 2999
3144 while (thresh_mask) { 3000 for_each_set_bit(index, &thresh_mask, ARRAY_SIZE(timer_table->timers)) {
3145 index = rightmost_index(timer_table, &thresh_mask);
3146 timer = timer_table->timers[index]; 3001 timer = timer_table->timers[index];
3147 BUG_ON(!timer); 3002 if (!timer)
3148 ath_dbg(common, BTCOEX, "TSF overflow for Gen timer %d\n", 3003 continue;
3149 index); 3004 if (!timer->overflow)
3005 continue;
3006
3007 trigger_mask &= ~BIT(index);
3150 timer->overflow(timer->arg); 3008 timer->overflow(timer->arg);
3151 } 3009 }
3152 3010
3153 while (trigger_mask) { 3011 for_each_set_bit(index, &trigger_mask, ARRAY_SIZE(timer_table->timers)) {
3154 index = rightmost_index(timer_table, &trigger_mask);
3155 timer = timer_table->timers[index]; 3012 timer = timer_table->timers[index];
3156 BUG_ON(!timer); 3013 if (!timer)
3157 ath_dbg(common, BTCOEX, 3014 continue;
3158 "Gen timer[%d] trigger\n", index); 3015 if (!timer->trigger)
3016 continue;
3159 timer->trigger(timer->arg); 3017 timer->trigger(timer->arg);
3160 } 3018 }
3161} 3019}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index a2c9a5dbac6b..0acd4b5a4892 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -52,6 +52,7 @@
52#define AR9300_DEVID_QCA955X 0x0038 52#define AR9300_DEVID_QCA955X 0x0038
53#define AR9485_DEVID_AR1111 0x0037 53#define AR9485_DEVID_AR1111 0x0037
54#define AR9300_DEVID_AR9565 0x0036 54#define AR9300_DEVID_AR9565 0x0036
55#define AR9300_DEVID_AR953X 0x003d
55 56
56#define AR5416_AR9100_DEVID 0x000b 57#define AR5416_AR9100_DEVID 0x000b
57 58
@@ -168,7 +169,7 @@
168#define CAB_TIMEOUT_VAL 10 169#define CAB_TIMEOUT_VAL 10
169#define BEACON_TIMEOUT_VAL 10 170#define BEACON_TIMEOUT_VAL 10
170#define MIN_BEACON_TIMEOUT_VAL 1 171#define MIN_BEACON_TIMEOUT_VAL 1
171#define SLEEP_SLOP 3 172#define SLEEP_SLOP TU_TO_USEC(3)
172 173
173#define INIT_CONFIG_STATUS 0x00000000 174#define INIT_CONFIG_STATUS 0x00000000
174#define INIT_RSSI_THR 0x00000700 175#define INIT_RSSI_THR 0x00000700
@@ -277,14 +278,25 @@ struct ath9k_hw_capabilities {
277 u8 txs_len; 278 u8 txs_len;
278}; 279};
279 280
281#define AR_NO_SPUR 0x8000
282#define AR_BASE_FREQ_2GHZ 2300
283#define AR_BASE_FREQ_5GHZ 4900
284#define AR_SPUR_FEEQ_BOUND_HT40 19
285#define AR_SPUR_FEEQ_BOUND_HT20 10
286
287enum ath9k_hw_hang_checks {
288 HW_BB_WATCHDOG = BIT(0),
289 HW_PHYRESTART_CLC_WAR = BIT(1),
290 HW_BB_RIFS_HANG = BIT(2),
291 HW_BB_DFS_HANG = BIT(3),
292 HW_BB_RX_CLEAR_STUCK_HANG = BIT(4),
293 HW_MAC_HANG = BIT(5),
294};
295
280struct ath9k_ops_config { 296struct ath9k_ops_config {
281 int dma_beacon_response_time; 297 int dma_beacon_response_time;
282 int sw_beacon_response_time; 298 int sw_beacon_response_time;
283 int additional_swba_backoff;
284 int ack_6mb;
285 u32 cwm_ignore_extcca; 299 u32 cwm_ignore_extcca;
286 bool pcieSerDesWrite;
287 u8 pcie_clock_req;
288 u32 pcie_waen; 300 u32 pcie_waen;
289 u8 analog_shiftreg; 301 u8 analog_shiftreg;
290 u32 ofdm_trig_low; 302 u32 ofdm_trig_low;
@@ -295,20 +307,11 @@ struct ath9k_ops_config {
295 int serialize_regmode; 307 int serialize_regmode;
296 bool rx_intr_mitigation; 308 bool rx_intr_mitigation;
297 bool tx_intr_mitigation; 309 bool tx_intr_mitigation;
298#define SPUR_DISABLE 0
299#define SPUR_ENABLE_IOCTL 1
300#define SPUR_ENABLE_EEPROM 2
301#define AR_SPUR_5413_1 1640
302#define AR_SPUR_5413_2 1200
303#define AR_NO_SPUR 0x8000
304#define AR_BASE_FREQ_2GHZ 2300
305#define AR_BASE_FREQ_5GHZ 4900
306#define AR_SPUR_FEEQ_BOUND_HT40 19
307#define AR_SPUR_FEEQ_BOUND_HT20 10
308 int spurmode;
309 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
310 u8 max_txtrig_level; 310 u8 max_txtrig_level;
311 u16 ani_poll_interval; /* ANI poll interval in ms */ 311 u16 ani_poll_interval; /* ANI poll interval in ms */
312 u16 hw_hang_checks;
313 u16 rimt_first;
314 u16 rimt_last;
312 315
313 /* Platform specific config */ 316 /* Platform specific config */
314 u32 aspm_l1_fix; 317 u32 aspm_l1_fix;
@@ -317,6 +320,7 @@ struct ath9k_ops_config {
317 bool xatten_margin_cfg; 320 bool xatten_margin_cfg;
318 bool alt_mingainidx; 321 bool alt_mingainidx;
319 bool no_pll_pwrsave; 322 bool no_pll_pwrsave;
323 bool tx_gain_buffalo;
320}; 324};
321 325
322enum ath9k_int { 326enum ath9k_int {
@@ -460,10 +464,6 @@ struct ath9k_beacon_state {
460 u32 bs_intval; 464 u32 bs_intval;
461#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ 465#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
462 u32 bs_dtimperiod; 466 u32 bs_dtimperiod;
463 u16 bs_cfpperiod;
464 u16 bs_cfpmaxduration;
465 u32 bs_cfpnext;
466 u16 bs_timoffset;
467 u16 bs_bmissthreshold; 467 u16 bs_bmissthreshold;
468 u32 bs_sleepduration; 468 u32 bs_sleepduration;
469 u32 bs_tsfoor_threshold; 469 u32 bs_tsfoor_threshold;
@@ -499,12 +499,6 @@ struct ath9k_hw_version {
499 499
500#define AR_GENTMR_BIT(_index) (1 << (_index)) 500#define AR_GENTMR_BIT(_index) (1 << (_index))
501 501
502/*
503 * Using de Bruijin sequence to look up 1's index in a 32 bit number
504 * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
505 */
506#define debruijn32 0x077CB531U
507
508struct ath_gen_timer_configuration { 502struct ath_gen_timer_configuration {
509 u32 next_addr; 503 u32 next_addr;
510 u32 period_addr; 504 u32 period_addr;
@@ -520,12 +514,8 @@ struct ath_gen_timer {
520}; 514};
521 515
522struct ath_gen_timer_table { 516struct ath_gen_timer_table {
523 u32 gen_timer_index[32];
524 struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER]; 517 struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER];
525 union { 518 u16 timer_mask;
526 unsigned long timer_bits;
527 u16 val;
528 } timer_mask;
529}; 519};
530 520
531struct ath_hw_antcomb_conf { 521struct ath_hw_antcomb_conf {
@@ -596,6 +586,10 @@ struct ath_hw_radar_conf {
596 * register settings through the register initialization. 586 * register settings through the register initialization.
597 */ 587 */
598struct ath_hw_private_ops { 588struct ath_hw_private_ops {
589 void (*init_hang_checks)(struct ath_hw *ah);
590 bool (*detect_mac_hang)(struct ath_hw *ah);
591 bool (*detect_bb_hang)(struct ath_hw *ah);
592
599 /* Calibration ops */ 593 /* Calibration ops */
600 void (*init_cal_settings)(struct ath_hw *ah); 594 void (*init_cal_settings)(struct ath_hw *ah);
601 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); 595 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
@@ -690,7 +684,8 @@ struct ath_hw_ops {
690 struct ath9k_channel *chan, 684 struct ath9k_channel *chan,
691 u8 rxchainmask, 685 u8 rxchainmask,
692 bool longcal); 686 bool longcal);
693 bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked); 687 bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked,
688 u32 *sync_cause_p);
694 void (*set_txdesc)(struct ath_hw *ah, void *ds, 689 void (*set_txdesc)(struct ath_hw *ah, void *ds,
695 struct ath_tx_info *i); 690 struct ath_tx_info *i);
696 int (*proc_txdesc)(struct ath_hw *ah, void *ds, 691 int (*proc_txdesc)(struct ath_hw *ah, void *ds,
@@ -786,7 +781,6 @@ struct ath_hw {
786 u32 txurn_interrupt_mask; 781 u32 txurn_interrupt_mask;
787 atomic_t intr_ref_cnt; 782 atomic_t intr_ref_cnt;
788 bool chip_fullsleep; 783 bool chip_fullsleep;
789 u32 atim_window;
790 u32 modes_index; 784 u32 modes_index;
791 785
792 /* Calibration */ 786 /* Calibration */
@@ -865,6 +859,7 @@ struct ath_hw {
865 u32 gpio_mask; 859 u32 gpio_mask;
866 u32 gpio_val; 860 u32 gpio_val;
867 861
862 struct ar5416IniArray ini_dfs;
868 struct ar5416IniArray iniModes; 863 struct ar5416IniArray iniModes;
869 struct ar5416IniArray iniCommon; 864 struct ar5416IniArray iniCommon;
870 struct ar5416IniArray iniBB_RfGain; 865 struct ar5416IniArray iniBB_RfGain;
@@ -921,7 +916,7 @@ struct ath_hw {
921 /* Enterprise mode cap */ 916 /* Enterprise mode cap */
922 u32 ent_mode; 917 u32 ent_mode;
923 918
924#ifdef CONFIG_PM_SLEEP 919#ifdef CONFIG_ATH9K_WOW
925 u32 wow_event_mask; 920 u32 wow_event_mask;
926#endif 921#endif
927 bool is_clk_25mhz; 922 bool is_clk_25mhz;
@@ -1017,13 +1012,6 @@ bool ath9k_hw_check_alive(struct ath_hw *ah);
1017 1012
1018bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 1013bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
1019 1014
1020#ifdef CONFIG_ATH9K_DEBUGFS
1021void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
1022#else
1023static inline void ath9k_debug_sync_cause(struct ath_common *common,
1024 u32 sync_cause) {}
1025#endif
1026
1027/* Generic hw timer primitives */ 1015/* Generic hw timer primitives */
1028struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 1016struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
1029 void (*trigger)(void *), 1017 void (*trigger)(void *),
@@ -1058,6 +1046,7 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
1058 * Code specific to AR9003, we stuff these here to avoid callbacks 1046 * Code specific to AR9003, we stuff these here to avoid callbacks
1059 * for older families 1047 * for older families
1060 */ 1048 */
1049bool ar9003_hw_bb_watchdog_check(struct ath_hw *ah);
1061void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); 1050void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
1062void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); 1051void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
1063void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); 1052void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
@@ -1127,7 +1116,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
1127#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 1116#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
1128 1117
1129 1118
1130#ifdef CONFIG_PM_SLEEP 1119#ifdef CONFIG_ATH9K_WOW
1131const char *ath9k_hw_wow_event_to_string(u32 wow_event); 1120const char *ath9k_hw_wow_event_to_string(u32 wow_event);
1132void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 1121void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
1133 u8 *user_mask, int pattern_count, 1122 u8 *user_mask, int pattern_count,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 710192ed27ed..c36de303c8f3 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -470,7 +470,6 @@ static int ath9k_init_queues(struct ath_softc *sc)
470 470
471 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); 471 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
472 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); 472 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
473
474 ath_cabq_update(sc); 473 ath_cabq_update(sc);
475 474
476 sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0); 475 sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
@@ -554,7 +553,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
554 sc->spec_config.fft_period = 0xF; 553 sc->spec_config.fft_period = 0xF;
555} 554}
556 555
557static void ath9k_init_platform(struct ath_softc *sc) 556static void ath9k_init_pcoem_platform(struct ath_softc *sc)
558{ 557{
559 struct ath_hw *ah = sc->sc_ah; 558 struct ath_hw *ah = sc->sc_ah;
560 struct ath9k_hw_capabilities *pCap = &ah->caps; 559 struct ath9k_hw_capabilities *pCap = &ah->caps;
@@ -589,6 +588,9 @@ static void ath9k_init_platform(struct ath_softc *sc)
589 if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) 588 if (sc->driver_data & ATH9K_PCI_AR9565_2ANT)
590 ath_info(common, "WB335 2-ANT card detected\n"); 589 ath_info(common, "WB335 2-ANT card detected\n");
591 590
591 if (sc->driver_data & ATH9K_PCI_KILLER)
592 ath_info(common, "Killer Wireless card detected\n");
593
592 /* 594 /*
593 * Some WB335 cards do not support antenna diversity. Since 595 * Some WB335 cards do not support antenna diversity. Since
594 * we use a hardcoded value for AR9565 instead of using the 596 * we use a hardcoded value for AR9565 instead of using the
@@ -661,6 +663,27 @@ static void ath9k_eeprom_release(struct ath_softc *sc)
661 release_firmware(sc->sc_ah->eeprom_blob); 663 release_firmware(sc->sc_ah->eeprom_blob);
662} 664}
663 665
666static int ath9k_init_soc_platform(struct ath_softc *sc)
667{
668 struct ath9k_platform_data *pdata = sc->dev->platform_data;
669 struct ath_hw *ah = sc->sc_ah;
670 int ret = 0;
671
672 if (!pdata)
673 return 0;
674
675 if (pdata->eeprom_name) {
676 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
677 if (ret)
678 return ret;
679 }
680
681 if (pdata->tx_gain_buffalo)
682 ah->config.tx_gain_buffalo = true;
683
684 return ret;
685}
686
664static int ath9k_init_softc(u16 devid, struct ath_softc *sc, 687static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
665 const struct ath_bus_ops *bus_ops) 688 const struct ath_bus_ops *bus_ops)
666{ 689{
@@ -681,13 +704,13 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
681 ah->reg_ops.read = ath9k_ioread32; 704 ah->reg_ops.read = ath9k_ioread32;
682 ah->reg_ops.write = ath9k_iowrite32; 705 ah->reg_ops.write = ath9k_iowrite32;
683 ah->reg_ops.rmw = ath9k_reg_rmw; 706 ah->reg_ops.rmw = ath9k_reg_rmw;
684 atomic_set(&ah->intr_ref_cnt, -1);
685 sc->sc_ah = ah; 707 sc->sc_ah = ah;
686 pCap = &ah->caps; 708 pCap = &ah->caps;
687 709
688 common = ath9k_hw_common(ah); 710 common = ath9k_hw_common(ah);
689 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); 711 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
690 sc->tx99_power = MAX_RATE_POWER + 1; 712 sc->tx99_power = MAX_RATE_POWER + 1;
713 init_waitqueue_head(&sc->tx_wait);
691 714
692 if (!pdata) { 715 if (!pdata) {
693 ah->ah_flags |= AH_USE_EEPROM; 716 ah->ah_flags |= AH_USE_EEPROM;
@@ -713,7 +736,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
713 /* 736 /*
714 * Platform quirks. 737 * Platform quirks.
715 */ 738 */
716 ath9k_init_platform(sc); 739 ath9k_init_pcoem_platform(sc);
740
741 ret = ath9k_init_soc_platform(sc);
742 if (ret)
743 return ret;
717 744
718 /* 745 /*
719 * Enable WLAN/BT RX Antenna diversity only when: 746 * Enable WLAN/BT RX Antenna diversity only when:
@@ -727,7 +754,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
727 common->bt_ant_diversity = 1; 754 common->bt_ant_diversity = 1;
728 755
729 spin_lock_init(&common->cc_lock); 756 spin_lock_init(&common->cc_lock);
730
731 spin_lock_init(&sc->sc_serial_rw); 757 spin_lock_init(&sc->sc_serial_rw);
732 spin_lock_init(&sc->sc_pm_lock); 758 spin_lock_init(&sc->sc_pm_lock);
733 mutex_init(&sc->mutex); 759 mutex_init(&sc->mutex);
@@ -735,11 +761,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
735 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 761 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
736 (unsigned long)sc); 762 (unsigned long)sc);
737 763
764 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
738 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 765 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
739 INIT_WORK(&sc->hw_check_work, ath_hw_check);
740 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); 766 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
741 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); 767 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
742 setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc);
743 768
744 /* 769 /*
745 * Cache line size is used to size and align various 770 * Cache line size is used to size and align various
@@ -748,12 +773,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
748 ath_read_cachesize(common, &csz); 773 ath_read_cachesize(common, &csz);
749 common->cachelsz = csz << 2; /* convert to bytes */ 774 common->cachelsz = csz << 2; /* convert to bytes */
750 775
751 if (pdata && pdata->eeprom_name) {
752 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
753 if (ret)
754 return ret;
755 }
756
757 /* Initializes the hardware for all supported chipsets */ 776 /* Initializes the hardware for all supported chipsets */
758 ret = ath9k_hw_init(ah); 777 ret = ath9k_hw_init(ah);
759 if (ret) 778 if (ret)
@@ -851,6 +870,9 @@ static const struct ieee80211_iface_limit if_limits[] = {
851 870
852static const struct ieee80211_iface_limit if_dfs_limits[] = { 871static const struct ieee80211_iface_limit if_dfs_limits[] = {
853 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | 872 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
873#ifdef CONFIG_MAC80211_MESH
874 BIT(NL80211_IFTYPE_MESH_POINT) |
875#endif
854 BIT(NL80211_IFTYPE_ADHOC) }, 876 BIT(NL80211_IFTYPE_ADHOC) },
855}; 877};
856 878
@@ -873,16 +895,7 @@ static const struct ieee80211_iface_combination if_comb[] = {
873 } 895 }
874}; 896};
875 897
876#ifdef CONFIG_PM 898static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
877static const struct wiphy_wowlan_support ath9k_wowlan_support = {
878 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
879 .n_patterns = MAX_NUM_USER_PATTERN,
880 .pattern_min_len = 1,
881 .pattern_max_len = MAX_PATTERN_SIZE,
882};
883#endif
884
885void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
886{ 899{
887 struct ath_hw *ah = sc->sc_ah; 900 struct ath_hw *ah = sc->sc_ah;
888 struct ath_common *common = ath9k_hw_common(ah); 901 struct ath_common *common = ath9k_hw_common(ah);
@@ -931,19 +944,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
931 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; 944 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
932 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 945 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
933 946
934#ifdef CONFIG_PM_SLEEP
935 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
936 (sc->driver_data & ATH9K_PCI_WOW) &&
937 device_can_wakeup(sc->dev))
938 hw->wiphy->wowlan = &ath9k_wowlan_support;
939
940 atomic_set(&sc->wow_sleep_proc_intr, -1);
941 atomic_set(&sc->wow_got_bmiss_intr, -1);
942#endif
943
944 hw->queues = 4; 947 hw->queues = 4;
945 hw->max_rates = 4; 948 hw->max_rates = 4;
946 hw->channel_change_time = 5000;
947 hw->max_listen_interval = 1; 949 hw->max_listen_interval = 1;
948 hw->max_rate_tries = 10; 950 hw->max_rate_tries = 10;
949 hw->sta_data_size = sizeof(struct ath_node); 951 hw->sta_data_size = sizeof(struct ath_node);
@@ -966,6 +968,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
966 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 968 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
967 &sc->sbands[IEEE80211_BAND_5GHZ]; 969 &sc->sbands[IEEE80211_BAND_5GHZ];
968 970
971 ath9k_init_wow(hw);
969 ath9k_reload_chainmask_settings(sc); 972 ath9k_reload_chainmask_settings(sc);
970 973
971 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 974 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
@@ -1064,6 +1067,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
1064 if (ATH_TXQ_SETUP(sc, i)) 1067 if (ATH_TXQ_SETUP(sc, i))
1065 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1068 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1066 1069
1070 del_timer_sync(&sc->sleep_timer);
1067 ath9k_hw_deinit(sc->sc_ah); 1071 ath9k_hw_deinit(sc->sc_ah);
1068 if (sc->dfs_detector != NULL) 1072 if (sc->dfs_detector != NULL)
1069 sc->dfs_detector->exit(sc->dfs_detector); 1073 sc->dfs_detector->exit(sc->dfs_detector);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index aed7e29dc50f..30dcef5aba10 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -65,50 +65,26 @@ void ath_tx_complete_poll_work(struct work_struct *work)
65/* 65/*
66 * Checks if the BB/MAC is hung. 66 * Checks if the BB/MAC is hung.
67 */ 67 */
68void ath_hw_check(struct work_struct *work) 68bool ath_hw_check(struct ath_softc *sc)
69{ 69{
70 struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
71 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 70 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
72 unsigned long flags;
73 int busy;
74 u8 is_alive, nbeacon = 1;
75 enum ath_reset_type type; 71 enum ath_reset_type type;
72 bool is_alive;
76 73
77 ath9k_ps_wakeup(sc); 74 ath9k_ps_wakeup(sc);
75
78 is_alive = ath9k_hw_check_alive(sc->sc_ah); 76 is_alive = ath9k_hw_check_alive(sc->sc_ah);
79 77
80 if ((is_alive && !AR_SREV_9300(sc->sc_ah)) || sc->tx99_state) 78 if (!is_alive) {
81 goto out;
82 else if (!is_alive && AR_SREV_9300(sc->sc_ah)) {
83 ath_dbg(common, RESET, 79 ath_dbg(common, RESET,
84 "DCU stuck is detected. Schedule chip reset\n"); 80 "HW hang detected, schedule chip reset\n");
85 type = RESET_TYPE_MAC_HANG; 81 type = RESET_TYPE_MAC_HANG;
86 goto sched_reset; 82 ath9k_queue_reset(sc, type);
87 }
88
89 spin_lock_irqsave(&common->cc_lock, flags);
90 busy = ath_update_survey_stats(sc);
91 spin_unlock_irqrestore(&common->cc_lock, flags);
92
93 ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n",
94 busy, sc->hw_busy_count + 1);
95 if (busy >= 99) {
96 if (++sc->hw_busy_count >= 3) {
97 type = RESET_TYPE_BB_HANG;
98 goto sched_reset;
99 }
100 } else if (busy >= 0) {
101 sc->hw_busy_count = 0;
102 nbeacon = 3;
103 } 83 }
104 84
105 ath_start_rx_poll(sc, nbeacon);
106 goto out;
107
108sched_reset:
109 ath9k_queue_reset(sc, type);
110out:
111 ath9k_ps_restore(sc); 85 ath9k_ps_restore(sc);
86
87 return is_alive;
112} 88}
113 89
114/* 90/*
@@ -162,29 +138,6 @@ void ath_hw_pll_work(struct work_struct *work)
162} 138}
163 139
164/* 140/*
165 * RX Polling - monitors baseband hangs.
166 */
167void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon)
168{
169 if (!AR_SREV_9300(sc->sc_ah))
170 return;
171
172 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
173 return;
174
175 mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies
176 (nbeacon * sc->cur_beacon_conf.beacon_interval));
177}
178
179void ath_rx_poll(unsigned long data)
180{
181 struct ath_softc *sc = (struct ath_softc *)data;
182
183 if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
184 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
185}
186
187/*
188 * PA Pre-distortion. 141 * PA Pre-distortion.
189 */ 142 */
190static void ath_paprd_activate(struct ath_softc *sc) 143static void ath_paprd_activate(struct ath_softc *sc)
@@ -409,10 +362,10 @@ void ath_ani_calibrate(unsigned long data)
409 362
410 /* Call ANI routine if necessary */ 363 /* Call ANI routine if necessary */
411 if (aniflag) { 364 if (aniflag) {
412 spin_lock_irqsave(&common->cc_lock, flags); 365 spin_lock(&common->cc_lock);
413 ath9k_hw_ani_monitor(ah, ah->curchan); 366 ath9k_hw_ani_monitor(ah, ah->curchan);
414 ath_update_survey_stats(sc); 367 ath_update_survey_stats(sc);
415 spin_unlock_irqrestore(&common->cc_lock, flags); 368 spin_unlock(&common->cc_lock);
416 } 369 }
417 370
418 /* Perform calibration if necessary */ 371 /* Perform calibration if necessary */
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 6a18f9d3e9cc..5f727588ca27 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -481,8 +481,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
481 | AR_Q_MISC_CBR_INCR_DIS0); 481 | AR_Q_MISC_CBR_INCR_DIS0);
482 value = (qi->tqi_readyTime - 482 value = (qi->tqi_readyTime -
483 (ah->config.sw_beacon_response_time - 483 (ah->config.sw_beacon_response_time -
484 ah->config.dma_beacon_response_time) - 484 ah->config.dma_beacon_response_time)) * 1024;
485 ah->config.additional_swba_backoff) * 1024;
486 REG_WRITE(ah, AR_QRDYTIMECFG(q), 485 REG_WRITE(ah, AR_QRDYTIMECFG(q),
487 value | AR_Q_RDYTIMECFG_EN); 486 value | AR_Q_RDYTIMECFG_EN);
488 REG_SET_BIT(ah, AR_DMISC(q), 487 REG_SET_BIT(ah, AR_DMISC(q),
@@ -550,25 +549,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
550 549
551 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { 550 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
552 rs->rs_rssi = ATH9K_RSSI_BAD; 551 rs->rs_rssi = ATH9K_RSSI_BAD;
553 rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; 552 rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
554 rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; 553 rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
555 rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; 554 rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
556 rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; 555 rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
557 rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; 556 rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
558 rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; 557 rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
559 } else { 558 } else {
560 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 559 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
561 rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, 560 rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
562 AR_RxRSSIAnt00); 561 AR_RxRSSIAnt00);
563 rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, 562 rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
564 AR_RxRSSIAnt01); 563 AR_RxRSSIAnt01);
565 rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, 564 rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
566 AR_RxRSSIAnt02); 565 AR_RxRSSIAnt02);
567 rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, 566 rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
568 AR_RxRSSIAnt10); 567 AR_RxRSSIAnt10);
569 rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, 568 rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
570 AR_RxRSSIAnt11); 569 AR_RxRSSIAnt11);
571 rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, 570 rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
572 AR_RxRSSIAnt12); 571 AR_RxRSSIAnt12);
573 } 572 }
574 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 573 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
@@ -923,11 +922,29 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah)
923 mask2 |= AR_IMR_S2_CST; 922 mask2 |= AR_IMR_S2_CST;
924 } 923 }
925 924
925 if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) {
926 if (ints & ATH9K_INT_BB_WATCHDOG) {
927 mask |= AR_IMR_BCNMISC;
928 mask2 |= AR_IMR_S2_BB_WATCHDOG;
929 }
930 }
931
926 ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask); 932 ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask);
927 REG_WRITE(ah, AR_IMR, mask); 933 REG_WRITE(ah, AR_IMR, mask);
928 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | 934 ah->imrs2_reg &= ~(AR_IMR_S2_TIM |
929 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | 935 AR_IMR_S2_DTIM |
930 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); 936 AR_IMR_S2_DTIMSYNC |
937 AR_IMR_S2_CABEND |
938 AR_IMR_S2_CABTO |
939 AR_IMR_S2_TSFOOR |
940 AR_IMR_S2_GTT |
941 AR_IMR_S2_CST);
942
943 if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) {
944 if (ints & ATH9K_INT_BB_WATCHDOG)
945 ah->imrs2_reg &= ~AR_IMR_S2_BB_WATCHDOG;
946 }
947
931 ah->imrs2_reg |= mask2; 948 ah->imrs2_reg |= mask2;
932 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 949 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
933 950
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index e3eed81f2439..10271373a0cd 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -133,12 +133,8 @@ struct ath_rx_status {
133 u8 rs_rate; 133 u8 rs_rate;
134 u8 rs_antenna; 134 u8 rs_antenna;
135 u8 rs_more; 135 u8 rs_more;
136 int8_t rs_rssi_ctl0; 136 int8_t rs_rssi_ctl[3];
137 int8_t rs_rssi_ctl1; 137 int8_t rs_rssi_ext[3];
138 int8_t rs_rssi_ctl2;
139 int8_t rs_rssi_ext0;
140 int8_t rs_rssi_ext1;
141 int8_t rs_rssi_ext2;
142 u8 rs_isaggr; 138 u8 rs_isaggr;
143 u8 rs_firstaggr; 139 u8 rs_firstaggr;
144 u8 rs_moreaggr; 140 u8 rs_moreaggr;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 21aa09e0e825..5924f72dd493 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
82 return ret; 82 return ret;
83} 83}
84 84
85void ath_ps_full_sleep(unsigned long data)
86{
87 struct ath_softc *sc = (struct ath_softc *) data;
88 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
89 bool reset;
90
91 spin_lock(&common->cc_lock);
92 ath_hw_cycle_counters_update(common);
93 spin_unlock(&common->cc_lock);
94
95 ath9k_hw_setrxabort(sc->sc_ah, 1);
96 ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
97
98 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
99}
100
85void ath9k_ps_wakeup(struct ath_softc *sc) 101void ath9k_ps_wakeup(struct ath_softc *sc)
86{ 102{
87 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 103 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
92 if (++sc->ps_usecount != 1) 108 if (++sc->ps_usecount != 1)
93 goto unlock; 109 goto unlock;
94 110
111 del_timer_sync(&sc->sleep_timer);
95 power_mode = sc->sc_ah->power_mode; 112 power_mode = sc->sc_ah->power_mode;
96 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 113 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
97 114
@@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc *sc)
117 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 134 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
118 enum ath9k_power_mode mode; 135 enum ath9k_power_mode mode;
119 unsigned long flags; 136 unsigned long flags;
120 bool reset;
121 137
122 spin_lock_irqsave(&sc->sc_pm_lock, flags); 138 spin_lock_irqsave(&sc->sc_pm_lock, flags);
123 if (--sc->ps_usecount != 0) 139 if (--sc->ps_usecount != 0)
124 goto unlock; 140 goto unlock;
125 141
126 if (sc->ps_idle) { 142 if (sc->ps_idle) {
127 ath9k_hw_setrxabort(sc->sc_ah, 1); 143 mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
128 ath9k_hw_stopdmarecv(sc->sc_ah, &reset); 144 goto unlock;
129 mode = ATH9K_PM_FULL_SLEEP; 145 }
130 } else if (sc->ps_enabled && 146
147 if (sc->ps_enabled &&
131 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 148 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
132 PS_WAIT_FOR_CAB | 149 PS_WAIT_FOR_CAB |
133 PS_WAIT_FOR_PSPOLL_DATA | 150 PS_WAIT_FOR_PSPOLL_DATA |
@@ -153,7 +170,6 @@ void ath9k_ps_restore(struct ath_softc *sc)
153static void __ath_cancel_work(struct ath_softc *sc) 170static void __ath_cancel_work(struct ath_softc *sc)
154{ 171{
155 cancel_work_sync(&sc->paprd_work); 172 cancel_work_sync(&sc->paprd_work);
156 cancel_work_sync(&sc->hw_check_work);
157 cancel_delayed_work_sync(&sc->tx_complete_work); 173 cancel_delayed_work_sync(&sc->tx_complete_work);
158 cancel_delayed_work_sync(&sc->hw_pll_work); 174 cancel_delayed_work_sync(&sc->hw_pll_work);
159 175
@@ -163,13 +179,13 @@ static void __ath_cancel_work(struct ath_softc *sc)
163#endif 179#endif
164} 180}
165 181
166static void ath_cancel_work(struct ath_softc *sc) 182void ath_cancel_work(struct ath_softc *sc)
167{ 183{
168 __ath_cancel_work(sc); 184 __ath_cancel_work(sc);
169 cancel_work_sync(&sc->hw_reset_work); 185 cancel_work_sync(&sc->hw_reset_work);
170} 186}
171 187
172static void ath_restart_work(struct ath_softc *sc) 188void ath_restart_work(struct ath_softc *sc)
173{ 189{
174 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 190 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
175 191
@@ -177,7 +193,6 @@ static void ath_restart_work(struct ath_softc *sc)
177 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, 193 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
178 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); 194 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
179 195
180 ath_start_rx_poll(sc, 3);
181 ath_start_ani(sc); 196 ath_start_ani(sc);
182} 197}
183 198
@@ -187,11 +202,7 @@ static bool ath_prepare_reset(struct ath_softc *sc)
187 bool ret = true; 202 bool ret = true;
188 203
189 ieee80211_stop_queues(sc->hw); 204 ieee80211_stop_queues(sc->hw);
190
191 sc->hw_busy_count = 0;
192 ath_stop_ani(sc); 205 ath_stop_ani(sc);
193 del_timer_sync(&sc->rx_poll_timer);
194
195 ath9k_hw_disable_interrupts(ah); 206 ath9k_hw_disable_interrupts(ah);
196 207
197 if (!ath_drain_all_txq(sc)) 208 if (!ath_drain_all_txq(sc))
@@ -247,6 +258,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
247 } 258 }
248 } 259 }
249 260
261 sc->gtt_cnt = 0;
250 ieee80211_wake_queues(sc->hw); 262 ieee80211_wake_queues(sc->hw);
251 263
252 return true; 264 return true;
@@ -319,7 +331,6 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand
319 struct ieee80211_hw *hw = sc->hw; 331 struct ieee80211_hw *hw = sc->hw;
320 struct ath9k_channel *hchan; 332 struct ath9k_channel *hchan;
321 struct ieee80211_channel *chan = chandef->chan; 333 struct ieee80211_channel *chan = chandef->chan;
322 unsigned long flags;
323 bool offchannel; 334 bool offchannel;
324 int pos = chan->hw_value; 335 int pos = chan->hw_value;
325 int old_pos = -1; 336 int old_pos = -1;
@@ -337,9 +348,9 @@ static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chand
337 chan->center_freq, chandef->width); 348 chan->center_freq, chandef->width);
338 349
339 /* update survey stats for the old channel before switching */ 350 /* update survey stats for the old channel before switching */
340 spin_lock_irqsave(&common->cc_lock, flags); 351 spin_lock_bh(&common->cc_lock);
341 ath_update_survey_stats(sc); 352 ath_update_survey_stats(sc);
342 spin_unlock_irqrestore(&common->cc_lock, flags); 353 spin_unlock_bh(&common->cc_lock);
343 354
344 ath9k_cmn_get_channel(hw, ah, chandef); 355 ath9k_cmn_get_channel(hw, ah, chandef);
345 356
@@ -410,12 +421,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
410 an->vif = vif; 421 an->vif = vif;
411 422
412 ath_tx_node_init(sc, an); 423 ath_tx_node_init(sc, an);
413
414 if (sta->ht_cap.ht_supported) {
415 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
416 sta->ht_cap.ampdu_factor);
417 an->mpdudensity = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
418 }
419} 424}
420 425
421static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) 426static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -437,14 +442,8 @@ void ath9k_tasklet(unsigned long data)
437 ath9k_ps_wakeup(sc); 442 ath9k_ps_wakeup(sc);
438 spin_lock(&sc->sc_pcu_lock); 443 spin_lock(&sc->sc_pcu_lock);
439 444
440 if ((status & ATH9K_INT_FATAL) || 445 if (status & ATH9K_INT_FATAL) {
441 (status & ATH9K_INT_BB_WATCHDOG)) { 446 type = RESET_TYPE_FATAL_INT;
442
443 if (status & ATH9K_INT_FATAL)
444 type = RESET_TYPE_FATAL_INT;
445 else
446 type = RESET_TYPE_BB_WATCHDOG;
447
448 ath9k_queue_reset(sc, type); 447 ath9k_queue_reset(sc, type);
449 448
450 /* 449 /*
@@ -456,6 +455,41 @@ void ath9k_tasklet(unsigned long data)
456 goto out; 455 goto out;
457 } 456 }
458 457
458 if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
459 (status & ATH9K_INT_BB_WATCHDOG)) {
460 spin_lock(&common->cc_lock);
461 ath_hw_cycle_counters_update(common);
462 ar9003_hw_bb_watchdog_dbg_info(ah);
463 spin_unlock(&common->cc_lock);
464
465 if (ar9003_hw_bb_watchdog_check(ah)) {
466 type = RESET_TYPE_BB_WATCHDOG;
467 ath9k_queue_reset(sc, type);
468
469 /*
470 * Increment the ref. counter here so that
471 * interrupts are enabled in the reset routine.
472 */
473 atomic_inc(&ah->intr_ref_cnt);
474 ath_dbg(common, ANY,
475 "BB_WATCHDOG: Skipping interrupts\n");
476 goto out;
477 }
478 }
479
480 if (status & ATH9K_INT_GTT) {
481 sc->gtt_cnt++;
482
483 if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
484 type = RESET_TYPE_TX_GTT;
485 ath9k_queue_reset(sc, type);
486 atomic_inc(&ah->intr_ref_cnt);
487 ath_dbg(common, ANY,
488 "GTT: Skipping interrupts\n");
489 goto out;
490 }
491 }
492
459 spin_lock_irqsave(&sc->sc_pm_lock, flags); 493 spin_lock_irqsave(&sc->sc_pm_lock, flags);
460 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { 494 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
461 /* 495 /*
@@ -483,12 +517,26 @@ void ath9k_tasklet(unsigned long data)
483 } 517 }
484 518
485 if (status & ATH9K_INT_TX) { 519 if (status & ATH9K_INT_TX) {
486 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 520 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
521 /*
522 * For EDMA chips, TX completion is enabled for the
523 * beacon queue, so if a beacon has been transmitted
524 * successfully after a GTT interrupt, the GTT counter
525 * gets reset to zero here.
526 */
527 sc->gtt_cnt = 0;
528
487 ath_tx_edma_tasklet(sc); 529 ath_tx_edma_tasklet(sc);
488 else 530 } else {
489 ath_tx_tasklet(sc); 531 ath_tx_tasklet(sc);
532 }
533
534 wake_up(&sc->tx_wait);
490 } 535 }
491 536
537 if (status & ATH9K_INT_GENTIMER)
538 ath_gen_timer_isr(sc->sc_ah);
539
492 ath9k_btcoex_handle_interrupt(sc, status); 540 ath9k_btcoex_handle_interrupt(sc, status);
493 541
494 /* re-enable hardware interrupt */ 542 /* re-enable hardware interrupt */
@@ -511,14 +559,15 @@ irqreturn_t ath_isr(int irq, void *dev)
511 ATH9K_INT_TX | \ 559 ATH9K_INT_TX | \
512 ATH9K_INT_BMISS | \ 560 ATH9K_INT_BMISS | \
513 ATH9K_INT_CST | \ 561 ATH9K_INT_CST | \
562 ATH9K_INT_GTT | \
514 ATH9K_INT_TSFOOR | \ 563 ATH9K_INT_TSFOOR | \
515 ATH9K_INT_GENTIMER | \ 564 ATH9K_INT_GENTIMER | \
516 ATH9K_INT_MCI) 565 ATH9K_INT_MCI)
517 566
518 struct ath_softc *sc = dev; 567 struct ath_softc *sc = dev;
519 struct ath_hw *ah = sc->sc_ah; 568 struct ath_hw *ah = sc->sc_ah;
520 struct ath_common *common = ath9k_hw_common(ah);
521 enum ath9k_int status; 569 enum ath9k_int status;
570 u32 sync_cause = 0;
522 bool sched = false; 571 bool sched = false;
523 572
524 /* 573 /*
@@ -545,7 +594,8 @@ irqreturn_t ath_isr(int irq, void *dev)
545 * bits we haven't explicitly enabled so we mask the 594 * bits we haven't explicitly enabled so we mask the
546 * value to insure we only process bits we requested. 595 * value to insure we only process bits we requested.
547 */ 596 */
548 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ 597 ath9k_hw_getisr(ah, &status, &sync_cause); /* NB: clears ISR too */
598 ath9k_debug_sync_cause(sc, sync_cause);
549 status &= ah->imask; /* discard unasked-for bits */ 599 status &= ah->imask; /* discard unasked-for bits */
550 600
551 /* 601 /*
@@ -569,25 +619,19 @@ irqreturn_t ath_isr(int irq, void *dev)
569 !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) 619 !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
570 goto chip_reset; 620 goto chip_reset;
571 621
572 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 622 if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
573 (status & ATH9K_INT_BB_WATCHDOG)) { 623 (status & ATH9K_INT_BB_WATCHDOG))
574
575 spin_lock(&common->cc_lock);
576 ath_hw_cycle_counters_update(common);
577 ar9003_hw_bb_watchdog_dbg_info(ah);
578 spin_unlock(&common->cc_lock);
579
580 goto chip_reset; 624 goto chip_reset;
581 } 625
582#ifdef CONFIG_PM_SLEEP 626#ifdef CONFIG_ATH9K_WOW
583 if (status & ATH9K_INT_BMISS) { 627 if (status & ATH9K_INT_BMISS) {
584 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { 628 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
585 ath_dbg(common, ANY, "during WoW we got a BMISS\n");
586 atomic_inc(&sc->wow_got_bmiss_intr); 629 atomic_inc(&sc->wow_got_bmiss_intr);
587 atomic_dec(&sc->wow_sleep_proc_intr); 630 atomic_dec(&sc->wow_sleep_proc_intr);
588 } 631 }
589 } 632 }
590#endif 633#endif
634
591 if (status & ATH9K_INT_SWBA) 635 if (status & ATH9K_INT_SWBA)
592 tasklet_schedule(&sc->bcon_tasklet); 636 tasklet_schedule(&sc->bcon_tasklet);
593 637
@@ -627,7 +671,7 @@ chip_reset:
627#undef SCHED_INTR 671#undef SCHED_INTR
628} 672}
629 673
630static int ath_reset(struct ath_softc *sc) 674int ath_reset(struct ath_softc *sc)
631{ 675{
632 int r; 676 int r;
633 677
@@ -705,12 +749,19 @@ static int ath9k_start(struct ieee80211_hw *hw)
705 749
706 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 750 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
707 ah->imask |= ATH9K_INT_RXHP | 751 ah->imask |= ATH9K_INT_RXHP |
708 ATH9K_INT_RXLP | 752 ATH9K_INT_RXLP;
709 ATH9K_INT_BB_WATCHDOG;
710 else 753 else
711 ah->imask |= ATH9K_INT_RX; 754 ah->imask |= ATH9K_INT_RX;
712 755
713 ah->imask |= ATH9K_INT_GTT; 756 if (ah->config.hw_hang_checks & HW_BB_WATCHDOG)
757 ah->imask |= ATH9K_INT_BB_WATCHDOG;
758
759 /*
760 * Enable GTT interrupts only for AR9003/AR9004 chips
761 * for now.
762 */
763 if (AR_SREV_9300_20_OR_LATER(ah))
764 ah->imask |= ATH9K_INT_GTT;
714 765
715 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) 766 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
716 ah->imask |= ATH9K_INT_CST; 767 ah->imask |= ATH9K_INT_CST;
@@ -735,6 +786,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
735 */ 786 */
736 ath9k_cmn_init_crypto(sc->sc_ah); 787 ath9k_cmn_init_crypto(sc->sc_ah);
737 788
789 ath9k_hw_reset_tsf(ah);
790
738 spin_unlock_bh(&sc->sc_pcu_lock); 791 spin_unlock_bh(&sc->sc_pcu_lock);
739 792
740 mutex_unlock(&sc->mutex); 793 mutex_unlock(&sc->mutex);
@@ -831,7 +884,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
831 mutex_lock(&sc->mutex); 884 mutex_lock(&sc->mutex);
832 885
833 ath_cancel_work(sc); 886 ath_cancel_work(sc);
834 del_timer_sync(&sc->rx_poll_timer);
835 887
836 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 888 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
837 ath_dbg(common, ANY, "Device not present\n"); 889 ath_dbg(common, ANY, "Device not present\n");
@@ -1636,13 +1688,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1636 } 1688 }
1637 1689
1638 if ((changed & BSS_CHANGED_BEACON_ENABLED) || 1690 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1639 (changed & BSS_CHANGED_BEACON_INT)) { 1691 (changed & BSS_CHANGED_BEACON_INT))
1640 if (ah->opmode == NL80211_IFTYPE_AP && 1692 ath9k_beacon_config(sc, vif, changed);
1641 bss_conf->enable_beacon)
1642 ath9k_set_tsfadjust(sc, vif);
1643 if (ath9k_allow_beacon_config(sc, vif))
1644 ath9k_beacon_config(sc, vif, changed);
1645 }
1646 1693
1647 if (changed & BSS_CHANGED_ERP_SLOT) { 1694 if (changed & BSS_CHANGED_ERP_SLOT) {
1648 if (bss_conf->use_short_slot) 1695 if (bss_conf->use_short_slot)
@@ -1767,13 +1814,12 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1767 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1814 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1768 struct ieee80211_supported_band *sband; 1815 struct ieee80211_supported_band *sband;
1769 struct ieee80211_channel *chan; 1816 struct ieee80211_channel *chan;
1770 unsigned long flags;
1771 int pos; 1817 int pos;
1772 1818
1773 if (config_enabled(CONFIG_ATH9K_TX99)) 1819 if (config_enabled(CONFIG_ATH9K_TX99))
1774 return -EOPNOTSUPP; 1820 return -EOPNOTSUPP;
1775 1821
1776 spin_lock_irqsave(&common->cc_lock, flags); 1822 spin_lock_bh(&common->cc_lock);
1777 if (idx == 0) 1823 if (idx == 0)
1778 ath_update_survey_stats(sc); 1824 ath_update_survey_stats(sc);
1779 1825
@@ -1787,7 +1833,7 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1787 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; 1833 sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
1788 1834
1789 if (!sband || idx >= sband->n_channels) { 1835 if (!sband || idx >= sband->n_channels) {
1790 spin_unlock_irqrestore(&common->cc_lock, flags); 1836 spin_unlock_bh(&common->cc_lock);
1791 return -ENOENT; 1837 return -ENOENT;
1792 } 1838 }
1793 1839
@@ -1795,7 +1841,7 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1795 pos = chan->hw_value; 1841 pos = chan->hw_value;
1796 memcpy(survey, &sc->survey[pos], sizeof(*survey)); 1842 memcpy(survey, &sc->survey[pos], sizeof(*survey));
1797 survey->channel = chan; 1843 survey->channel = chan;
1798 spin_unlock_irqrestore(&common->cc_lock, flags); 1844 spin_unlock_bh(&common->cc_lock);
1799 1845
1800 return 0; 1846 return 0;
1801} 1847}
@@ -1818,13 +1864,31 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
1818 mutex_unlock(&sc->mutex); 1864 mutex_unlock(&sc->mutex);
1819} 1865}
1820 1866
1867static bool ath9k_has_tx_pending(struct ath_softc *sc)
1868{
1869 int i, npend;
1870
1871 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1872 if (!ATH_TXQ_SETUP(sc, i))
1873 continue;
1874
1875 if (!sc->tx.txq[i].axq_depth)
1876 continue;
1877
1878 npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
1879 if (npend)
1880 break;
1881 }
1882
1883 return !!npend;
1884}
1885
1821static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1886static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1822{ 1887{
1823 struct ath_softc *sc = hw->priv; 1888 struct ath_softc *sc = hw->priv;
1824 struct ath_hw *ah = sc->sc_ah; 1889 struct ath_hw *ah = sc->sc_ah;
1825 struct ath_common *common = ath9k_hw_common(ah); 1890 struct ath_common *common = ath9k_hw_common(ah);
1826 int timeout = 200; /* ms */ 1891 int timeout = HZ / 5; /* 200 ms */
1827 int i, j;
1828 bool drain_txq; 1892 bool drain_txq;
1829 1893
1830 mutex_lock(&sc->mutex); 1894 mutex_lock(&sc->mutex);
@@ -1842,25 +1906,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1842 return; 1906 return;
1843 } 1907 }
1844 1908
1845 for (j = 0; j < timeout; j++) { 1909 if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
1846 bool npend = false; 1910 timeout) > 0)
1847 1911 drop = false;
1848 if (j)
1849 usleep_range(1000, 2000);
1850
1851 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1852 if (!ATH_TXQ_SETUP(sc, i))
1853 continue;
1854
1855 npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
1856
1857 if (npend)
1858 break;
1859 }
1860
1861 if (!npend)
1862 break;
1863 }
1864 1912
1865 if (drop) { 1913 if (drop) {
1866 ath9k_ps_wakeup(sc); 1914 ath9k_ps_wakeup(sc);
@@ -2022,333 +2070,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
2022 return 0; 2070 return 0;
2023} 2071}
2024 2072
2025#ifdef CONFIG_PM_SLEEP
2026
2027static void ath9k_wow_map_triggers(struct ath_softc *sc,
2028 struct cfg80211_wowlan *wowlan,
2029 u32 *wow_triggers)
2030{
2031 if (wowlan->disconnect)
2032 *wow_triggers |= AH_WOW_LINK_CHANGE |
2033 AH_WOW_BEACON_MISS;
2034 if (wowlan->magic_pkt)
2035 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
2036
2037 if (wowlan->n_patterns)
2038 *wow_triggers |= AH_WOW_USER_PATTERN_EN;
2039
2040 sc->wow_enabled = *wow_triggers;
2041
2042}
2043
2044static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2045{
2046 struct ath_hw *ah = sc->sc_ah;
2047 struct ath_common *common = ath9k_hw_common(ah);
2048 int pattern_count = 0;
2049 int i, byte_cnt;
2050 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
2051 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
2052
2053 memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
2054 memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
2055
2056 /*
2057 * Create Dissassociate / Deauthenticate packet filter
2058 *
2059 * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
2060 * +--------------+----------+---------+--------+--------+----
2061 * + Frame Control+ Duration + DA + SA + BSSID +
2062 * +--------------+----------+---------+--------+--------+----
2063 *
2064 * The above is the management frame format for disassociate/
2065 * deauthenticate pattern, from this we need to match the first byte
2066 * of 'Frame Control' and DA, SA, and BSSID fields
2067 * (skipping 2nd byte of FC and Duration feild.
2068 *
2069 * Disassociate pattern
2070 * --------------------
2071 * Frame control = 00 00 1010
2072 * DA, SA, BSSID = x:x:x:x:x:x
2073 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2074 * | x:x:x:x:x:x -- 22 bytes
2075 *
2076 * Deauthenticate pattern
2077 * ----------------------
2078 * Frame control = 00 00 1100
2079 * DA, SA, BSSID = x:x:x:x:x:x
2080 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2081 * | x:x:x:x:x:x -- 22 bytes
2082 */
2083
2084 /* Create Disassociate Pattern first */
2085
2086 byte_cnt = 0;
2087
2088 /* Fill out the mask with all FF's */
2089
2090 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
2091 dis_deauth_mask[i] = 0xff;
2092
2093 /* copy the first byte of frame control field */
2094 dis_deauth_pattern[byte_cnt] = 0xa0;
2095 byte_cnt++;
2096
2097 /* skip 2nd byte of frame control and Duration field */
2098 byte_cnt += 3;
2099
2100 /*
2101 * need not match the destination mac address, it can be a broadcast
2102 * mac address or an unicast to this station
2103 */
2104 byte_cnt += 6;
2105
2106 /* copy the source mac address */
2107 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2108
2109 byte_cnt += 6;
2110
2111 /* copy the bssid, its same as the source mac address */
2112
2113 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2114
2115 /* Create Disassociate pattern mask */
2116
2117 dis_deauth_mask[0] = 0xfe;
2118 dis_deauth_mask[1] = 0x03;
2119 dis_deauth_mask[2] = 0xc0;
2120
2121 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
2122
2123 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2124 pattern_count, byte_cnt);
2125
2126 pattern_count++;
2127 /*
2128 * for de-authenticate pattern, only the first byte of the frame
2129 * control field gets changed from 0xA0 to 0xC0
2130 */
2131 dis_deauth_pattern[0] = 0xC0;
2132
2133 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2134 pattern_count, byte_cnt);
2135
2136}
2137
2138static void ath9k_wow_add_pattern(struct ath_softc *sc,
2139 struct cfg80211_wowlan *wowlan)
2140{
2141 struct ath_hw *ah = sc->sc_ah;
2142 struct ath9k_wow_pattern *wow_pattern = NULL;
2143 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
2144 int mask_len;
2145 s8 i = 0;
2146
2147 if (!wowlan->n_patterns)
2148 return;
2149
2150 /*
2151 * Add the new user configured patterns
2152 */
2153 for (i = 0; i < wowlan->n_patterns; i++) {
2154
2155 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
2156
2157 if (!wow_pattern)
2158 return;
2159
2160 /*
2161 * TODO: convert the generic user space pattern to
2162 * appropriate chip specific/802.11 pattern.
2163 */
2164
2165 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
2166 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
2167 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
2168 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
2169 patterns[i].pattern_len);
2170 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
2171 wow_pattern->pattern_len = patterns[i].pattern_len;
2172
2173 /*
2174 * just need to take care of deauth and disssoc pattern,
2175 * make sure we don't overwrite them.
2176 */
2177
2178 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
2179 wow_pattern->mask_bytes,
2180 i + 2,
2181 wow_pattern->pattern_len);
2182 kfree(wow_pattern);
2183
2184 }
2185
2186}
2187
2188static int ath9k_suspend(struct ieee80211_hw *hw,
2189 struct cfg80211_wowlan *wowlan)
2190{
2191 struct ath_softc *sc = hw->priv;
2192 struct ath_hw *ah = sc->sc_ah;
2193 struct ath_common *common = ath9k_hw_common(ah);
2194 u32 wow_triggers_enabled = 0;
2195 int ret = 0;
2196
2197 mutex_lock(&sc->mutex);
2198
2199 ath_cancel_work(sc);
2200 ath_stop_ani(sc);
2201 del_timer_sync(&sc->rx_poll_timer);
2202
2203 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
2204 ath_dbg(common, ANY, "Device not present\n");
2205 ret = -EINVAL;
2206 goto fail_wow;
2207 }
2208
2209 if (WARN_ON(!wowlan)) {
2210 ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
2211 ret = -EINVAL;
2212 goto fail_wow;
2213 }
2214
2215 if (!device_can_wakeup(sc->dev)) {
2216 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
2217 ret = 1;
2218 goto fail_wow;
2219 }
2220
2221 /*
2222 * none of the sta vifs are associated
2223 * and we are not currently handling multivif
2224 * cases, for instance we have to seperately
2225 * configure 'keep alive frame' for each
2226 * STA.
2227 */
2228
2229 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
2230 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
2231 ret = 1;
2232 goto fail_wow;
2233 }
2234
2235 if (sc->nvifs > 1) {
2236 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
2237 ret = 1;
2238 goto fail_wow;
2239 }
2240
2241 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
2242
2243 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
2244 wow_triggers_enabled);
2245
2246 ath9k_ps_wakeup(sc);
2247
2248 ath9k_stop_btcoex(sc);
2249
2250 /*
2251 * Enable wake up on recieving disassoc/deauth
2252 * frame by default.
2253 */
2254 ath9k_wow_add_disassoc_deauth_pattern(sc);
2255
2256 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
2257 ath9k_wow_add_pattern(sc, wowlan);
2258
2259 spin_lock_bh(&sc->sc_pcu_lock);
2260 /*
2261 * To avoid false wake, we enable beacon miss interrupt only
2262 * when we go to sleep. We save the current interrupt mask
2263 * so we can restore it after the system wakes up
2264 */
2265 sc->wow_intr_before_sleep = ah->imask;
2266 ah->imask &= ~ATH9K_INT_GLOBAL;
2267 ath9k_hw_disable_interrupts(ah);
2268 ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
2269 ath9k_hw_set_interrupts(ah);
2270 ath9k_hw_enable_interrupts(ah);
2271
2272 spin_unlock_bh(&sc->sc_pcu_lock);
2273
2274 /*
2275 * we can now sync irq and kill any running tasklets, since we already
2276 * disabled interrupts and not holding a spin lock
2277 */
2278 synchronize_irq(sc->irq);
2279 tasklet_kill(&sc->intr_tq);
2280
2281 ath9k_hw_wow_enable(ah, wow_triggers_enabled);
2282
2283 ath9k_ps_restore(sc);
2284 ath_dbg(common, ANY, "WoW enabled in ath9k\n");
2285 atomic_inc(&sc->wow_sleep_proc_intr);
2286
2287fail_wow:
2288 mutex_unlock(&sc->mutex);
2289 return ret;
2290}
2291
2292static int ath9k_resume(struct ieee80211_hw *hw)
2293{
2294 struct ath_softc *sc = hw->priv;
2295 struct ath_hw *ah = sc->sc_ah;
2296 struct ath_common *common = ath9k_hw_common(ah);
2297 u32 wow_status;
2298
2299 mutex_lock(&sc->mutex);
2300
2301 ath9k_ps_wakeup(sc);
2302
2303 spin_lock_bh(&sc->sc_pcu_lock);
2304
2305 ath9k_hw_disable_interrupts(ah);
2306 ah->imask = sc->wow_intr_before_sleep;
2307 ath9k_hw_set_interrupts(ah);
2308 ath9k_hw_enable_interrupts(ah);
2309
2310 spin_unlock_bh(&sc->sc_pcu_lock);
2311
2312 wow_status = ath9k_hw_wow_wakeup(ah);
2313
2314 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
2315 /*
2316 * some devices may not pick beacon miss
2317 * as the reason they woke up so we add
2318 * that here for that shortcoming.
2319 */
2320 wow_status |= AH_WOW_BEACON_MISS;
2321 atomic_dec(&sc->wow_got_bmiss_intr);
2322 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
2323 }
2324
2325 atomic_dec(&sc->wow_sleep_proc_intr);
2326
2327 if (wow_status) {
2328 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
2329 ath9k_hw_wow_event_to_string(wow_status), wow_status);
2330 }
2331
2332 ath_restart_work(sc);
2333 ath9k_start_btcoex(sc);
2334
2335 ath9k_ps_restore(sc);
2336 mutex_unlock(&sc->mutex);
2337
2338 return 0;
2339}
2340
2341static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
2342{
2343 struct ath_softc *sc = hw->priv;
2344
2345 mutex_lock(&sc->mutex);
2346 device_init_wakeup(sc->dev, 1);
2347 device_set_wakeup_enable(sc->dev, enabled);
2348 mutex_unlock(&sc->mutex);
2349}
2350
2351#endif
2352static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2073static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2353{ 2074{
2354 struct ath_softc *sc = hw->priv; 2075 struct ath_softc *sc = hw->priv;
@@ -2374,134 +2095,6 @@ static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
2374 sc->csa_vif = vif; 2095 sc->csa_vif = vif;
2375} 2096}
2376 2097
2377static void ath9k_tx99_stop(struct ath_softc *sc)
2378{
2379 struct ath_hw *ah = sc->sc_ah;
2380 struct ath_common *common = ath9k_hw_common(ah);
2381
2382 ath_drain_all_txq(sc);
2383 ath_startrecv(sc);
2384
2385 ath9k_hw_set_interrupts(ah);
2386 ath9k_hw_enable_interrupts(ah);
2387
2388 ieee80211_wake_queues(sc->hw);
2389
2390 kfree_skb(sc->tx99_skb);
2391 sc->tx99_skb = NULL;
2392 sc->tx99_state = false;
2393
2394 ath9k_hw_tx99_stop(sc->sc_ah);
2395 ath_dbg(common, XMIT, "TX99 stopped\n");
2396}
2397
2398static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
2399{
2400 static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
2401 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
2402 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
2403 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
2404 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
2405 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
2406 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
2407 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
2408 u32 len = 1200;
2409 struct ieee80211_hw *hw = sc->hw;
2410 struct ieee80211_hdr *hdr;
2411 struct ieee80211_tx_info *tx_info;
2412 struct sk_buff *skb;
2413
2414 skb = alloc_skb(len, GFP_KERNEL);
2415 if (!skb)
2416 return NULL;
2417
2418 skb_put(skb, len);
2419
2420 memset(skb->data, 0, len);
2421
2422 hdr = (struct ieee80211_hdr *)skb->data;
2423 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
2424 hdr->duration_id = 0;
2425
2426 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
2427 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
2428 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
2429
2430 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
2431
2432 tx_info = IEEE80211_SKB_CB(skb);
2433 memset(tx_info, 0, sizeof(*tx_info));
2434 tx_info->band = hw->conf.chandef.chan->band;
2435 tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
2436 tx_info->control.vif = sc->tx99_vif;
2437
2438 memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
2439
2440 return skb;
2441}
2442
2443void ath9k_tx99_deinit(struct ath_softc *sc)
2444{
2445 ath_reset(sc);
2446
2447 ath9k_ps_wakeup(sc);
2448 ath9k_tx99_stop(sc);
2449 ath9k_ps_restore(sc);
2450}
2451
2452int ath9k_tx99_init(struct ath_softc *sc)
2453{
2454 struct ieee80211_hw *hw = sc->hw;
2455 struct ath_hw *ah = sc->sc_ah;
2456 struct ath_common *common = ath9k_hw_common(ah);
2457 struct ath_tx_control txctl;
2458 int r;
2459
2460 if (sc->sc_flags & SC_OP_INVALID) {
2461 ath_err(common,
2462 "driver is in invalid state unable to use TX99");
2463 return -EINVAL;
2464 }
2465
2466 sc->tx99_skb = ath9k_build_tx99_skb(sc);
2467 if (!sc->tx99_skb)
2468 return -ENOMEM;
2469
2470 memset(&txctl, 0, sizeof(txctl));
2471 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
2472
2473 ath_reset(sc);
2474
2475 ath9k_ps_wakeup(sc);
2476
2477 ath9k_hw_disable_interrupts(ah);
2478 atomic_set(&ah->intr_ref_cnt, -1);
2479 ath_drain_all_txq(sc);
2480 ath_stoprecv(sc);
2481
2482 sc->tx99_state = true;
2483
2484 ieee80211_stop_queues(hw);
2485
2486 if (sc->tx99_power == MAX_RATE_POWER + 1)
2487 sc->tx99_power = MAX_RATE_POWER;
2488
2489 ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
2490 r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
2491 if (r) {
2492 ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
2493 return r;
2494 }
2495
2496 ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
2497 sc->tx99_power,
2498 sc->tx99_power / 2);
2499
2500 /* We leave the harware awake as it will be chugging on */
2501
2502 return 0;
2503}
2504
2505struct ieee80211_ops ath9k_ops = { 2098struct ieee80211_ops ath9k_ops = {
2506 .tx = ath9k_tx, 2099 .tx = ath9k_tx,
2507 .start = ath9k_start, 2100 .start = ath9k_start,
@@ -2532,7 +2125,7 @@ struct ieee80211_ops ath9k_ops = {
2532 .set_antenna = ath9k_set_antenna, 2125 .set_antenna = ath9k_set_antenna,
2533 .get_antenna = ath9k_get_antenna, 2126 .get_antenna = ath9k_get_antenna,
2534 2127
2535#ifdef CONFIG_PM_SLEEP 2128#ifdef CONFIG_ATH9K_WOW
2536 .suspend = ath9k_suspend, 2129 .suspend = ath9k_suspend,
2537 .resume = ath9k_resume, 2130 .resume = ath9k_resume,
2538 .set_wakeup = ath9k_set_wakeup, 2131 .set_wakeup = ath9k_set_wakeup,
@@ -2544,7 +2137,7 @@ struct ieee80211_ops ath9k_ops = {
2544 .get_et_strings = ath9k_get_et_strings, 2137 .get_et_strings = ath9k_get_et_strings,
2545#endif 2138#endif
2546 2139
2547#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) 2140#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_STATION_STATISTICS)
2548 .sta_add_debugfs = ath9k_sta_add_debugfs, 2141 .sta_add_debugfs = ath9k_sta_add_debugfs,
2549#endif 2142#endif
2550 .sw_scan_start = ath9k_sw_scan_start, 2143 .sw_scan_start = ath9k_sw_scan_start,
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 0ac1b5f04256..71799fcade54 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -200,7 +200,7 @@ skip_tuning:
200 if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) 200 if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE)
201 btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; 201 btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE;
202 202
203 btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 * 203 btcoex->btcoex_no_stomp = btcoex->btcoex_period *
204 (100 - btcoex->duty_cycle) / 100; 204 (100 - btcoex->duty_cycle) / 100;
205 205
206 ath9k_hw_btcoex_enable(sc->sc_ah); 206 ath9k_hw_btcoex_enable(sc->sc_ah);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b5656fce4ff5..55724b02316b 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -87,6 +87,19 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
87 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 87 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
88 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 88 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
89 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 89 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
90
91 /* Killer Wireless (3x3) */
92 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
93 0x0030,
94 0x1A56,
95 0x2000),
96 .driver_data = ATH9K_PCI_KILLER },
97 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
98 0x0030,
99 0x1A56,
100 0x2001),
101 .driver_data = ATH9K_PCI_KILLER },
102
90 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ 103 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
91 104
92 /* PCI-E CUS198 */ 105 /* PCI-E CUS198 */
@@ -354,6 +367,13 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
354 0x1783), 367 0x1783),
355 .driver_data = ATH9K_PCI_WOW }, 368 .driver_data = ATH9K_PCI_WOW },
356 369
370 /* Killer Wireless (2x2) */
371 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
372 0x0030,
373 0x1A56,
374 0x2003),
375 .driver_data = ATH9K_PCI_KILLER },
376
357 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ 377 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
358 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ 378 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
359 379
@@ -392,6 +412,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
392 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 412 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
393 0x0036, 413 0x0036,
394 0x11AD, /* LITEON */ 414 0x11AD, /* LITEON */
415 0x06B2),
416 .driver_data = ATH9K_PCI_AR9565_1ANT },
417 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
418 0x0036,
419 0x11AD, /* LITEON */
420 0x0842),
421 .driver_data = ATH9K_PCI_AR9565_1ANT },
422 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
423 0x0036,
424 0x11AD, /* LITEON */
395 0x6671), 425 0x6671),
396 .driver_data = ATH9K_PCI_AR9565_1ANT }, 426 .driver_data = ATH9K_PCI_AR9565_1ANT },
397 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 427 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
@@ -404,6 +434,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
404 0x1B9A, /* XAVI */ 434 0x1B9A, /* XAVI */
405 0x2812), 435 0x2812),
406 .driver_data = ATH9K_PCI_AR9565_1ANT }, 436 .driver_data = ATH9K_PCI_AR9565_1ANT },
437 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
438 0x0036,
439 0x1B9A, /* XAVI */
440 0x28A1),
441 .driver_data = ATH9K_PCI_AR9565_1ANT },
442 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
443 0x0036,
444 PCI_VENDOR_ID_AZWAVE,
445 0x218A),
446 .driver_data = ATH9K_PCI_AR9565_1ANT },
407 447
408 /* WB335 1-ANT / Antenna Diversity */ 448 /* WB335 1-ANT / Antenna Diversity */
409 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 449 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
@@ -448,13 +488,18 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
448 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 488 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
449 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 489 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
450 0x0036, 490 0x0036,
451 PCI_VENDOR_ID_AZWAVE, 491 0x11AD, /* LITEON */
452 0x213A), 492 0x06A2),
453 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 493 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
454 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 494 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
455 0x0036, 495 0x0036,
456 PCI_VENDOR_ID_LENOVO, 496 0x11AD, /* LITEON */
457 0x3026), 497 0x0682),
498 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
499 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
500 0x0036,
501 PCI_VENDOR_ID_AZWAVE,
502 0x213A),
458 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 503 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
459 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 504 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
460 0x0036, 505 0x0036,
@@ -468,38 +513,41 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
468 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 513 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
469 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 514 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
470 0x0036, 515 0x0036,
516 PCI_VENDOR_ID_HP,
517 0x2005),
518 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
519 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
520 0x0036,
471 PCI_VENDOR_ID_DELL, 521 PCI_VENDOR_ID_DELL,
472 0x020E), 522 0x020C),
473 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 523 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
474 524
475 /* WB335 2-ANT */ 525 /* WB335 2-ANT / Antenna-Diversity */
476 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 526 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
477 0x0036, 527 0x0036,
478 PCI_VENDOR_ID_SAMSUNG, 528 PCI_VENDOR_ID_SAMSUNG,
479 0x411A), 529 0x411A),
480 .driver_data = ATH9K_PCI_AR9565_2ANT }, 530 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
481 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 531 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
482 0x0036, 532 0x0036,
483 PCI_VENDOR_ID_SAMSUNG, 533 PCI_VENDOR_ID_SAMSUNG,
484 0x411B), 534 0x411B),
485 .driver_data = ATH9K_PCI_AR9565_2ANT }, 535 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
486 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 536 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
487 0x0036, 537 0x0036,
488 PCI_VENDOR_ID_SAMSUNG, 538 PCI_VENDOR_ID_SAMSUNG,
489 0x411C), 539 0x411C),
490 .driver_data = ATH9K_PCI_AR9565_2ANT }, 540 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
491 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 541 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
492 0x0036, 542 0x0036,
493 PCI_VENDOR_ID_SAMSUNG, 543 PCI_VENDOR_ID_SAMSUNG,
494 0x411D), 544 0x411D),
495 .driver_data = ATH9K_PCI_AR9565_2ANT }, 545 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
496 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 546 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
497 0x0036, 547 0x0036,
498 PCI_VENDOR_ID_SAMSUNG, 548 PCI_VENDOR_ID_SAMSUNG,
499 0x411E), 549 0x411E),
500 .driver_data = ATH9K_PCI_AR9565_2ANT }, 550 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
501
502 /* WB335 2-ANT / Antenna-Diversity */
503 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 551 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
504 0x0036, 552 0x0036,
505 PCI_VENDOR_ID_ATHEROS, 553 PCI_VENDOR_ID_ATHEROS,
@@ -527,11 +575,31 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
527 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 575 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
528 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 576 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
529 0x0036, 577 0x0036,
578 0x11AD, /* LITEON */
579 0x0832),
580 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
581 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
582 0x0036,
583 0x11AD, /* LITEON */
584 0x0692),
585 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
586 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
587 0x0036,
530 PCI_VENDOR_ID_AZWAVE, 588 PCI_VENDOR_ID_AZWAVE,
531 0x2130), 589 0x2130),
532 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 590 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
533 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 591 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
534 0x0036, 592 0x0036,
593 PCI_VENDOR_ID_AZWAVE,
594 0x213B),
595 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
596 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
597 0x0036,
598 PCI_VENDOR_ID_AZWAVE,
599 0x2182),
600 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
601 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
602 0x0036,
535 0x144F, /* ASKEY */ 603 0x144F, /* ASKEY */
536 0x7202), 604 0x7202),
537 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 605 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -542,9 +610,49 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
542 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 610 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
543 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 611 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
544 0x0036, 612 0x0036,
613 0x1B9A, /* XAVI */
614 0x28A2),
615 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
616 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
617 0x0036,
545 0x185F, /* WNC */ 618 0x185F, /* WNC */
546 0x3027), 619 0x3027),
547 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 620 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
621 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
622 0x0036,
623 0x185F, /* WNC */
624 0xA120),
625 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
626 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
627 0x0036,
628 PCI_VENDOR_ID_FOXCONN,
629 0xE07F),
630 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
631 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
632 0x0036,
633 PCI_VENDOR_ID_FOXCONN,
634 0xE081),
635 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
636 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
637 0x0036,
638 PCI_VENDOR_ID_LENOVO,
639 0x3026),
640 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
641 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
642 0x0036,
643 PCI_VENDOR_ID_LENOVO,
644 0x4026),
645 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
646 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
647 0x0036,
648 PCI_VENDOR_ID_ASUSTEK,
649 0x85F2),
650 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
651 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
652 0x0036,
653 PCI_VENDOR_ID_DELL,
654 0x020E),
655 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
548 656
549 /* PCI-E AR9565 (WB335) */ 657 /* PCI-E AR9565 (WB335) */
550 { PCI_VDEVICE(ATHEROS, 0x0036), 658 { PCI_VDEVICE(ATHEROS, 0x0036),
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 95ddca5495d4..a0ebdd000fc2 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
18#include <linux/relay.h>
19#include "ath9k.h" 18#include "ath9k.h"
20#include "ar9003_mac.h" 19#include "ar9003_mac.h"
21 20
@@ -420,7 +419,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
420 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; 419 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
421 } 420 }
422 421
423 if (AR_SREV_9550(sc->sc_ah)) 422 if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah))
424 rfilt |= ATH9K_RX_FILTER_4ADDRESS; 423 rfilt |= ATH9K_RX_FILTER_4ADDRESS;
425 424
426 return rfilt; 425 return rfilt;
@@ -851,20 +850,15 @@ static int ath9k_process_rate(struct ath_common *common,
851 enum ieee80211_band band; 850 enum ieee80211_band band;
852 unsigned int i = 0; 851 unsigned int i = 0;
853 struct ath_softc __maybe_unused *sc = common->priv; 852 struct ath_softc __maybe_unused *sc = common->priv;
853 struct ath_hw *ah = sc->sc_ah;
854 854
855 band = hw->conf.chandef.chan->band; 855 band = ah->curchan->chan->band;
856 sband = hw->wiphy->bands[band]; 856 sband = hw->wiphy->bands[band];
857 857
858 switch (hw->conf.chandef.width) { 858 if (IS_CHAN_QUARTER_RATE(ah->curchan))
859 case NL80211_CHAN_WIDTH_5:
860 rxs->flag |= RX_FLAG_5MHZ; 859 rxs->flag |= RX_FLAG_5MHZ;
861 break; 860 else if (IS_CHAN_HALF_RATE(ah->curchan))
862 case NL80211_CHAN_WIDTH_10:
863 rxs->flag |= RX_FLAG_10MHZ; 861 rxs->flag |= RX_FLAG_10MHZ;
864 break;
865 default:
866 break;
867 }
868 862
869 if (rx_stats->rs_rate & 0x80) { 863 if (rx_stats->rs_rate & 0x80) {
870 /* HT rate */ 864 /* HT rate */
@@ -906,6 +900,7 @@ static void ath9k_process_rssi(struct ath_common *common,
906 struct ath_hw *ah = common->ah; 900 struct ath_hw *ah = common->ah;
907 int last_rssi; 901 int last_rssi;
908 int rssi = rx_stats->rs_rssi; 902 int rssi = rx_stats->rs_rssi;
903 int i, j;
909 904
910 /* 905 /*
911 * RSSI is not available for subframes in an A-MPDU. 906 * RSSI is not available for subframes in an A-MPDU.
@@ -924,6 +919,20 @@ static void ath9k_process_rssi(struct ath_common *common,
924 return; 919 return;
925 } 920 }
926 921
922 for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
923 s8 rssi;
924
925 if (!(ah->rxchainmask & BIT(i)))
926 continue;
927
928 rssi = rx_stats->rs_rssi_ctl[i];
929 if (rssi != ATH9K_RSSI_BAD) {
930 rxs->chains |= BIT(j);
931 rxs->chain_signal[j] = ah->noise + rssi;
932 }
933 j++;
934 }
935
927 /* 936 /*
928 * Update Beacon RSSI, this is used by ANI. 937 * Update Beacon RSSI, this is used by ANI.
929 */ 938 */
@@ -960,201 +969,6 @@ static void ath9k_process_tsf(struct ath_rx_status *rs,
960 rxs->mactime += 0x100000000ULL; 969 rxs->mactime += 0x100000000ULL;
961} 970}
962 971
963#ifdef CONFIG_ATH9K_DEBUGFS
964static s8 fix_rssi_inv_only(u8 rssi_val)
965{
966 if (rssi_val == 128)
967 rssi_val = 0;
968 return (s8) rssi_val;
969}
970#endif
971
972/* returns 1 if this was a spectral frame, even if not handled. */
973static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
974 struct ath_rx_status *rs, u64 tsf)
975{
976#ifdef CONFIG_ATH9K_DEBUGFS
977 struct ath_hw *ah = sc->sc_ah;
978 u8 num_bins, *bins, *vdata = (u8 *)hdr;
979 struct fft_sample_ht20 fft_sample_20;
980 struct fft_sample_ht20_40 fft_sample_40;
981 struct fft_sample_tlv *tlv;
982 struct ath_radar_info *radar_info;
983 int len = rs->rs_datalen;
984 int dc_pos;
985 u16 fft_len, length, freq = ah->curchan->chan->center_freq;
986 enum nl80211_channel_type chan_type;
987
988 /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
989 * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
990 * yet, but this is supposed to be possible as well.
991 */
992 if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
993 rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
994 rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
995 return 0;
996
997 /* check if spectral scan bit is set. This does not have to be checked
998 * if received through a SPECTRAL phy error, but shouldn't hurt.
999 */
1000 radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
1001 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
1002 return 0;
1003
1004 chan_type = cfg80211_get_chandef_type(&sc->hw->conf.chandef);
1005 if ((chan_type == NL80211_CHAN_HT40MINUS) ||
1006 (chan_type == NL80211_CHAN_HT40PLUS)) {
1007 fft_len = SPECTRAL_HT20_40_TOTAL_DATA_LEN;
1008 num_bins = SPECTRAL_HT20_40_NUM_BINS;
1009 bins = (u8 *)fft_sample_40.data;
1010 } else {
1011 fft_len = SPECTRAL_HT20_TOTAL_DATA_LEN;
1012 num_bins = SPECTRAL_HT20_NUM_BINS;
1013 bins = (u8 *)fft_sample_20.data;
1014 }
1015
1016 /* Variation in the data length is possible and will be fixed later */
1017 if ((len > fft_len + 2) || (len < fft_len - 1))
1018 return 1;
1019
1020 switch (len - fft_len) {
1021 case 0:
1022 /* length correct, nothing to do. */
1023 memcpy(bins, vdata, num_bins);
1024 break;
1025 case -1:
1026 /* first byte missing, duplicate it. */
1027 memcpy(&bins[1], vdata, num_bins - 1);
1028 bins[0] = vdata[0];
1029 break;
1030 case 2:
1031 /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
1032 memcpy(bins, vdata, 30);
1033 bins[30] = vdata[31];
1034 memcpy(&bins[31], &vdata[33], num_bins - 31);
1035 break;
1036 case 1:
1037 /* MAC added 2 extra bytes AND first byte is missing. */
1038 bins[0] = vdata[0];
1039 memcpy(&bins[1], vdata, 30);
1040 bins[31] = vdata[31];
1041 memcpy(&bins[32], &vdata[33], num_bins - 32);
1042 break;
1043 default:
1044 return 1;
1045 }
1046
1047 /* DC value (value in the middle) is the blind spot of the spectral
1048 * sample and invalid, interpolate it.
1049 */
1050 dc_pos = num_bins / 2;
1051 bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
1052
1053 if ((chan_type == NL80211_CHAN_HT40MINUS) ||
1054 (chan_type == NL80211_CHAN_HT40PLUS)) {
1055 s8 lower_rssi, upper_rssi;
1056 s16 ext_nf;
1057 u8 lower_max_index, upper_max_index;
1058 u8 lower_bitmap_w, upper_bitmap_w;
1059 u16 lower_mag, upper_mag;
1060 struct ath9k_hw_cal_data *caldata = ah->caldata;
1061 struct ath_ht20_40_mag_info *mag_info;
1062
1063 if (caldata)
1064 ext_nf = ath9k_hw_getchan_noise(ah, ah->curchan,
1065 caldata->nfCalHist[3].privNF);
1066 else
1067 ext_nf = ATH_DEFAULT_NOISE_FLOOR;
1068
1069 length = sizeof(fft_sample_40) - sizeof(struct fft_sample_tlv);
1070 fft_sample_40.tlv.type = ATH_FFT_SAMPLE_HT20_40;
1071 fft_sample_40.tlv.length = __cpu_to_be16(length);
1072 fft_sample_40.freq = __cpu_to_be16(freq);
1073 fft_sample_40.channel_type = chan_type;
1074
1075 if (chan_type == NL80211_CHAN_HT40PLUS) {
1076 lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
1077 upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0);
1078
1079 fft_sample_40.lower_noise = ah->noise;
1080 fft_sample_40.upper_noise = ext_nf;
1081 } else {
1082 lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0);
1083 upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
1084
1085 fft_sample_40.lower_noise = ext_nf;
1086 fft_sample_40.upper_noise = ah->noise;
1087 }
1088 fft_sample_40.lower_rssi = lower_rssi;
1089 fft_sample_40.upper_rssi = upper_rssi;
1090
1091 mag_info = ((struct ath_ht20_40_mag_info *)radar_info) - 1;
1092 lower_mag = spectral_max_magnitude(mag_info->lower_bins);
1093 upper_mag = spectral_max_magnitude(mag_info->upper_bins);
1094 fft_sample_40.lower_max_magnitude = __cpu_to_be16(lower_mag);
1095 fft_sample_40.upper_max_magnitude = __cpu_to_be16(upper_mag);
1096 lower_max_index = spectral_max_index(mag_info->lower_bins);
1097 upper_max_index = spectral_max_index(mag_info->upper_bins);
1098 fft_sample_40.lower_max_index = lower_max_index;
1099 fft_sample_40.upper_max_index = upper_max_index;
1100 lower_bitmap_w = spectral_bitmap_weight(mag_info->lower_bins);
1101 upper_bitmap_w = spectral_bitmap_weight(mag_info->upper_bins);
1102 fft_sample_40.lower_bitmap_weight = lower_bitmap_w;
1103 fft_sample_40.upper_bitmap_weight = upper_bitmap_w;
1104 fft_sample_40.max_exp = mag_info->max_exp & 0xf;
1105
1106 fft_sample_40.tsf = __cpu_to_be64(tsf);
1107
1108 tlv = (struct fft_sample_tlv *)&fft_sample_40;
1109 } else {
1110 u8 max_index, bitmap_w;
1111 u16 magnitude;
1112 struct ath_ht20_mag_info *mag_info;
1113
1114 length = sizeof(fft_sample_20) - sizeof(struct fft_sample_tlv);
1115 fft_sample_20.tlv.type = ATH_FFT_SAMPLE_HT20;
1116 fft_sample_20.tlv.length = __cpu_to_be16(length);
1117 fft_sample_20.freq = __cpu_to_be16(freq);
1118
1119 fft_sample_20.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
1120 fft_sample_20.noise = ah->noise;
1121
1122 mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
1123 magnitude = spectral_max_magnitude(mag_info->all_bins);
1124 fft_sample_20.max_magnitude = __cpu_to_be16(magnitude);
1125 max_index = spectral_max_index(mag_info->all_bins);
1126 fft_sample_20.max_index = max_index;
1127 bitmap_w = spectral_bitmap_weight(mag_info->all_bins);
1128 fft_sample_20.bitmap_weight = bitmap_w;
1129 fft_sample_20.max_exp = mag_info->max_exp & 0xf;
1130
1131 fft_sample_20.tsf = __cpu_to_be64(tsf);
1132
1133 tlv = (struct fft_sample_tlv *)&fft_sample_20;
1134 }
1135
1136 ath_debug_send_fft_sample(sc, tlv);
1137 return 1;
1138#else
1139 return 0;
1140#endif
1141}
1142
1143static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr)
1144{
1145 struct ath_hw *ah = sc->sc_ah;
1146 struct ath_common *common = ath9k_hw_common(ah);
1147
1148 if (ieee80211_is_beacon(hdr->frame_control)) {
1149 RX_STAT_INC(rx_beacons);
1150 if (!is_zero_ether_addr(common->curbssid) &&
1151 ether_addr_equal(hdr->addr3, common->curbssid))
1152 return true;
1153 }
1154
1155 return false;
1156}
1157
1158/* 972/*
1159 * For Decrypt or Demic errors, we only mark packet status here and always push 973 * For Decrypt or Demic errors, we only mark packet status here and always push
1160 * up the frame up to let mac80211 handle the actual error case, be it no 974 * up the frame up to let mac80211 handle the actual error case, be it no
@@ -1242,10 +1056,17 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1242 goto exit; 1056 goto exit;
1243 } 1057 }
1244 1058
1245 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); 1059 if (ath_is_mybeacon(common, hdr)) {
1246 if (rx_stats->is_mybeacon) { 1060 RX_STAT_INC(rx_beacons);
1247 sc->hw_busy_count = 0; 1061 rx_stats->is_mybeacon = true;
1248 ath_start_rx_poll(sc, 3); 1062 }
1063
1064 /*
1065 * This shouldn't happen, but have a safety check anyway.
1066 */
1067 if (WARN_ON(!ah->curchan)) {
1068 ret = -EINVAL;
1069 goto exit;
1249 } 1070 }
1250 1071
1251 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { 1072 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
@@ -1255,8 +1076,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1255 1076
1256 ath9k_process_rssi(common, hw, rx_stats, rx_status); 1077 ath9k_process_rssi(common, hw, rx_stats, rx_status);
1257 1078
1258 rx_status->band = hw->conf.chandef.chan->band; 1079 rx_status->band = ah->curchan->chan->band;
1259 rx_status->freq = hw->conf.chandef.chan->center_freq; 1080 rx_status->freq = ah->curchan->chan->center_freq;
1260 rx_status->antenna = rx_stats->rs_antenna; 1081 rx_status->antenna = rx_stats->rs_antenna;
1261 rx_status->flag |= RX_FLAG_MACTIME_END; 1082 rx_status->flag |= RX_FLAG_MACTIME_END;
1262 1083
@@ -1521,8 +1342,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1521 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 1342 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1522 1343
1523 ath9k_antenna_check(sc, &rs); 1344 ath9k_antenna_check(sc, &rs);
1524
1525 ath9k_apply_ampdu_details(sc, &rs, rxs); 1345 ath9k_apply_ampdu_details(sc, &rs, rxs);
1346 ath_debug_rate_stats(sc, &rs, skb);
1526 1347
1527 ieee80211_rx(hw, skb); 1348 ieee80211_rx(hw, skb);
1528 1349
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index a13b2d143d9e..b1fd3fa84983 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -304,6 +304,7 @@
304#define AR_IMR_S2 0x00ac 304#define AR_IMR_S2 0x00ac
305#define AR_IMR_S2_QCU_TXURN 0x000003FF 305#define AR_IMR_S2_QCU_TXURN 0x000003FF
306#define AR_IMR_S2_QCU_TXURN_S 0 306#define AR_IMR_S2_QCU_TXURN_S 0
307#define AR_IMR_S2_BB_WATCHDOG 0x00010000
307#define AR_IMR_S2_CST 0x00400000 308#define AR_IMR_S2_CST 0x00400000
308#define AR_IMR_S2_GTT 0x00800000 309#define AR_IMR_S2_GTT 0x00800000
309#define AR_IMR_S2_TIM 0x01000000 310#define AR_IMR_S2_TIM 0x01000000
@@ -809,7 +810,12 @@
809#define AR_SREV_REVISION_9462_21 3 810#define AR_SREV_REVISION_9462_21 3
810#define AR_SREV_VERSION_9565 0x2C0 811#define AR_SREV_VERSION_9565 0x2C0
811#define AR_SREV_REVISION_9565_10 0 812#define AR_SREV_REVISION_9565_10 0
813#define AR_SREV_REVISION_9565_101 1
814#define AR_SREV_REVISION_9565_11 2
812#define AR_SREV_VERSION_9550 0x400 815#define AR_SREV_VERSION_9550 0x400
816#define AR_SREV_VERSION_9531 0x500
817#define AR_SREV_REVISION_9531_10 0
818#define AR_SREV_REVISION_9531_11 1
813 819
814#define AR_SREV_5416(_ah) \ 820#define AR_SREV_5416(_ah) \
815 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 821 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -881,9 +887,6 @@
881 887
882#define AR_SREV_9330(_ah) \ 888#define AR_SREV_9330(_ah) \
883 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330)) 889 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330))
884#define AR_SREV_9330_10(_ah) \
885 (AR_SREV_9330((_ah)) && \
886 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_10))
887#define AR_SREV_9330_11(_ah) \ 890#define AR_SREV_9330_11(_ah) \
888 (AR_SREV_9330((_ah)) && \ 891 (AR_SREV_9330((_ah)) && \
889 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_11)) 892 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_11))
@@ -927,10 +930,18 @@
927 930
928#define AR_SREV_9565(_ah) \ 931#define AR_SREV_9565(_ah) \
929 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 932 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
930
931#define AR_SREV_9565_10(_ah) \ 933#define AR_SREV_9565_10(_ah) \
932 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 934 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
933 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) 935 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
936#define AR_SREV_9565_101(_ah) \
937 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
938 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
939#define AR_SREV_9565_11(_ah) \
940 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
941 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
942#define AR_SREV_9565_11_OR_LATER(_ah) \
943 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
944 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
934 945
935#define AR_SREV_9550(_ah) \ 946#define AR_SREV_9550(_ah) \
936 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550)) 947 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
@@ -938,11 +949,19 @@
938#define AR_SREV_9580(_ah) \ 949#define AR_SREV_9580(_ah) \
939 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ 950 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
940 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10)) 951 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10))
941
942#define AR_SREV_9580_10(_ah) \ 952#define AR_SREV_9580_10(_ah) \
943 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ 953 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
944 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9580_10)) 954 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9580_10))
945 955
956#define AR_SREV_9531(_ah) \
957 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531))
958#define AR_SREV_9531_10(_ah) \
959 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
960 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_10))
961#define AR_SREV_9531_11(_ah) \
962 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
963 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_11))
964
946/* NOTE: When adding chips newer than Peacock, add chip check here */ 965/* NOTE: When adding chips newer than Peacock, add chip check here */
947#define AR_SREV_9580_10_OR_LATER(_ah) \ 966#define AR_SREV_9580_10_OR_LATER(_ah) \
948 (AR_SREV_9580(_ah)) 967 (AR_SREV_9580(_ah))
diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c
new file mode 100644
index 000000000000..99f4de95c264
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/spectral.c
@@ -0,0 +1,543 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/relay.h>
18#include "ath9k.h"
19
20static s8 fix_rssi_inv_only(u8 rssi_val)
21{
22 if (rssi_val == 128)
23 rssi_val = 0;
24 return (s8) rssi_val;
25}
26
27static void ath_debug_send_fft_sample(struct ath_softc *sc,
28 struct fft_sample_tlv *fft_sample_tlv)
29{
30 int length;
31 if (!sc->rfs_chan_spec_scan)
32 return;
33
34 length = __be16_to_cpu(fft_sample_tlv->length) +
35 sizeof(*fft_sample_tlv);
36 relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv, length);
37}
38
39/* returns 1 if this was a spectral frame, even if not handled. */
40int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
41 struct ath_rx_status *rs, u64 tsf)
42{
43 struct ath_hw *ah = sc->sc_ah;
44 u8 num_bins, *bins, *vdata = (u8 *)hdr;
45 struct fft_sample_ht20 fft_sample_20;
46 struct fft_sample_ht20_40 fft_sample_40;
47 struct fft_sample_tlv *tlv;
48 struct ath_radar_info *radar_info;
49 int len = rs->rs_datalen;
50 int dc_pos;
51 u16 fft_len, length, freq = ah->curchan->chan->center_freq;
52 enum nl80211_channel_type chan_type;
53
54 /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
55 * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
56 * yet, but this is supposed to be possible as well.
57 */
58 if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
59 rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
60 rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
61 return 0;
62
63 /* check if spectral scan bit is set. This does not have to be checked
64 * if received through a SPECTRAL phy error, but shouldn't hurt.
65 */
66 radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
67 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
68 return 0;
69
70 chan_type = cfg80211_get_chandef_type(&sc->hw->conf.chandef);
71 if ((chan_type == NL80211_CHAN_HT40MINUS) ||
72 (chan_type == NL80211_CHAN_HT40PLUS)) {
73 fft_len = SPECTRAL_HT20_40_TOTAL_DATA_LEN;
74 num_bins = SPECTRAL_HT20_40_NUM_BINS;
75 bins = (u8 *)fft_sample_40.data;
76 } else {
77 fft_len = SPECTRAL_HT20_TOTAL_DATA_LEN;
78 num_bins = SPECTRAL_HT20_NUM_BINS;
79 bins = (u8 *)fft_sample_20.data;
80 }
81
82 /* Variation in the data length is possible and will be fixed later */
83 if ((len > fft_len + 2) || (len < fft_len - 1))
84 return 1;
85
86 switch (len - fft_len) {
87 case 0:
88 /* length correct, nothing to do. */
89 memcpy(bins, vdata, num_bins);
90 break;
91 case -1:
92 /* first byte missing, duplicate it. */
93 memcpy(&bins[1], vdata, num_bins - 1);
94 bins[0] = vdata[0];
95 break;
96 case 2:
97 /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
98 memcpy(bins, vdata, 30);
99 bins[30] = vdata[31];
100 memcpy(&bins[31], &vdata[33], num_bins - 31);
101 break;
102 case 1:
103 /* MAC added 2 extra bytes AND first byte is missing. */
104 bins[0] = vdata[0];
105 memcpy(&bins[1], vdata, 30);
106 bins[31] = vdata[31];
107 memcpy(&bins[32], &vdata[33], num_bins - 32);
108 break;
109 default:
110 return 1;
111 }
112
113 /* DC value (value in the middle) is the blind spot of the spectral
114 * sample and invalid, interpolate it.
115 */
116 dc_pos = num_bins / 2;
117 bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
118
119 if ((chan_type == NL80211_CHAN_HT40MINUS) ||
120 (chan_type == NL80211_CHAN_HT40PLUS)) {
121 s8 lower_rssi, upper_rssi;
122 s16 ext_nf;
123 u8 lower_max_index, upper_max_index;
124 u8 lower_bitmap_w, upper_bitmap_w;
125 u16 lower_mag, upper_mag;
126 struct ath9k_hw_cal_data *caldata = ah->caldata;
127 struct ath_ht20_40_mag_info *mag_info;
128
129 if (caldata)
130 ext_nf = ath9k_hw_getchan_noise(ah, ah->curchan,
131 caldata->nfCalHist[3].privNF);
132 else
133 ext_nf = ATH_DEFAULT_NOISE_FLOOR;
134
135 length = sizeof(fft_sample_40) - sizeof(struct fft_sample_tlv);
136 fft_sample_40.tlv.type = ATH_FFT_SAMPLE_HT20_40;
137 fft_sample_40.tlv.length = __cpu_to_be16(length);
138 fft_sample_40.freq = __cpu_to_be16(freq);
139 fft_sample_40.channel_type = chan_type;
140
141 if (chan_type == NL80211_CHAN_HT40PLUS) {
142 lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
143 upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ext[0]);
144
145 fft_sample_40.lower_noise = ah->noise;
146 fft_sample_40.upper_noise = ext_nf;
147 } else {
148 lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ext[0]);
149 upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
150
151 fft_sample_40.lower_noise = ext_nf;
152 fft_sample_40.upper_noise = ah->noise;
153 }
154 fft_sample_40.lower_rssi = lower_rssi;
155 fft_sample_40.upper_rssi = upper_rssi;
156
157 mag_info = ((struct ath_ht20_40_mag_info *)radar_info) - 1;
158 lower_mag = spectral_max_magnitude(mag_info->lower_bins);
159 upper_mag = spectral_max_magnitude(mag_info->upper_bins);
160 fft_sample_40.lower_max_magnitude = __cpu_to_be16(lower_mag);
161 fft_sample_40.upper_max_magnitude = __cpu_to_be16(upper_mag);
162 lower_max_index = spectral_max_index(mag_info->lower_bins);
163 upper_max_index = spectral_max_index(mag_info->upper_bins);
164 fft_sample_40.lower_max_index = lower_max_index;
165 fft_sample_40.upper_max_index = upper_max_index;
166 lower_bitmap_w = spectral_bitmap_weight(mag_info->lower_bins);
167 upper_bitmap_w = spectral_bitmap_weight(mag_info->upper_bins);
168 fft_sample_40.lower_bitmap_weight = lower_bitmap_w;
169 fft_sample_40.upper_bitmap_weight = upper_bitmap_w;
170 fft_sample_40.max_exp = mag_info->max_exp & 0xf;
171
172 fft_sample_40.tsf = __cpu_to_be64(tsf);
173
174 tlv = (struct fft_sample_tlv *)&fft_sample_40;
175 } else {
176 u8 max_index, bitmap_w;
177 u16 magnitude;
178 struct ath_ht20_mag_info *mag_info;
179
180 length = sizeof(fft_sample_20) - sizeof(struct fft_sample_tlv);
181 fft_sample_20.tlv.type = ATH_FFT_SAMPLE_HT20;
182 fft_sample_20.tlv.length = __cpu_to_be16(length);
183 fft_sample_20.freq = __cpu_to_be16(freq);
184
185 fft_sample_20.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
186 fft_sample_20.noise = ah->noise;
187
188 mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
189 magnitude = spectral_max_magnitude(mag_info->all_bins);
190 fft_sample_20.max_magnitude = __cpu_to_be16(magnitude);
191 max_index = spectral_max_index(mag_info->all_bins);
192 fft_sample_20.max_index = max_index;
193 bitmap_w = spectral_bitmap_weight(mag_info->all_bins);
194 fft_sample_20.bitmap_weight = bitmap_w;
195 fft_sample_20.max_exp = mag_info->max_exp & 0xf;
196
197 fft_sample_20.tsf = __cpu_to_be64(tsf);
198
199 tlv = (struct fft_sample_tlv *)&fft_sample_20;
200 }
201
202 ath_debug_send_fft_sample(sc, tlv);
203
204 return 1;
205}
206
207/*********************/
208/* spectral_scan_ctl */
209/*********************/
210
211static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf,
212 size_t count, loff_t *ppos)
213{
214 struct ath_softc *sc = file->private_data;
215 char *mode = "";
216 unsigned int len;
217
218 switch (sc->spectral_mode) {
219 case SPECTRAL_DISABLED:
220 mode = "disable";
221 break;
222 case SPECTRAL_BACKGROUND:
223 mode = "background";
224 break;
225 case SPECTRAL_CHANSCAN:
226 mode = "chanscan";
227 break;
228 case SPECTRAL_MANUAL:
229 mode = "manual";
230 break;
231 }
232 len = strlen(mode);
233 return simple_read_from_buffer(user_buf, count, ppos, mode, len);
234}
235
236static ssize_t write_file_spec_scan_ctl(struct file *file,
237 const char __user *user_buf,
238 size_t count, loff_t *ppos)
239{
240 struct ath_softc *sc = file->private_data;
241 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
242 char buf[32];
243 ssize_t len;
244
245 if (config_enabled(CONFIG_ATH9K_TX99))
246 return -EOPNOTSUPP;
247
248 len = min(count, sizeof(buf) - 1);
249 if (copy_from_user(buf, user_buf, len))
250 return -EFAULT;
251
252 buf[len] = '\0';
253
254 if (strncmp("trigger", buf, 7) == 0) {
255 ath9k_spectral_scan_trigger(sc->hw);
256 } else if (strncmp("background", buf, 9) == 0) {
257 ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND);
258 ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n");
259 } else if (strncmp("chanscan", buf, 8) == 0) {
260 ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN);
261 ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n");
262 } else if (strncmp("manual", buf, 6) == 0) {
263 ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL);
264 ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n");
265 } else if (strncmp("disable", buf, 7) == 0) {
266 ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED);
267 ath_dbg(common, CONFIG, "spectral scan: disabled\n");
268 } else {
269 return -EINVAL;
270 }
271
272 return count;
273}
274
275static const struct file_operations fops_spec_scan_ctl = {
276 .read = read_file_spec_scan_ctl,
277 .write = write_file_spec_scan_ctl,
278 .open = simple_open,
279 .owner = THIS_MODULE,
280 .llseek = default_llseek,
281};
282
283/*************************/
284/* spectral_short_repeat */
285/*************************/
286
287static ssize_t read_file_spectral_short_repeat(struct file *file,
288 char __user *user_buf,
289 size_t count, loff_t *ppos)
290{
291 struct ath_softc *sc = file->private_data;
292 char buf[32];
293 unsigned int len;
294
295 len = sprintf(buf, "%d\n", sc->spec_config.short_repeat);
296 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
297}
298
299static ssize_t write_file_spectral_short_repeat(struct file *file,
300 const char __user *user_buf,
301 size_t count, loff_t *ppos)
302{
303 struct ath_softc *sc = file->private_data;
304 unsigned long val;
305 char buf[32];
306 ssize_t len;
307
308 len = min(count, sizeof(buf) - 1);
309 if (copy_from_user(buf, user_buf, len))
310 return -EFAULT;
311
312 buf[len] = '\0';
313 if (kstrtoul(buf, 0, &val))
314 return -EINVAL;
315
316 if (val < 0 || val > 1)
317 return -EINVAL;
318
319 sc->spec_config.short_repeat = val;
320 return count;
321}
322
323static const struct file_operations fops_spectral_short_repeat = {
324 .read = read_file_spectral_short_repeat,
325 .write = write_file_spectral_short_repeat,
326 .open = simple_open,
327 .owner = THIS_MODULE,
328 .llseek = default_llseek,
329};
330
331/******************/
332/* spectral_count */
333/******************/
334
335static ssize_t read_file_spectral_count(struct file *file,
336 char __user *user_buf,
337 size_t count, loff_t *ppos)
338{
339 struct ath_softc *sc = file->private_data;
340 char buf[32];
341 unsigned int len;
342
343 len = sprintf(buf, "%d\n", sc->spec_config.count);
344 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
345}
346
347static ssize_t write_file_spectral_count(struct file *file,
348 const char __user *user_buf,
349 size_t count, loff_t *ppos)
350{
351 struct ath_softc *sc = file->private_data;
352 unsigned long val;
353 char buf[32];
354 ssize_t len;
355
356 len = min(count, sizeof(buf) - 1);
357 if (copy_from_user(buf, user_buf, len))
358 return -EFAULT;
359
360 buf[len] = '\0';
361 if (kstrtoul(buf, 0, &val))
362 return -EINVAL;
363
364 if (val < 0 || val > 255)
365 return -EINVAL;
366
367 sc->spec_config.count = val;
368 return count;
369}
370
371static const struct file_operations fops_spectral_count = {
372 .read = read_file_spectral_count,
373 .write = write_file_spectral_count,
374 .open = simple_open,
375 .owner = THIS_MODULE,
376 .llseek = default_llseek,
377};
378
379/*******************/
380/* spectral_period */
381/*******************/
382
383static ssize_t read_file_spectral_period(struct file *file,
384 char __user *user_buf,
385 size_t count, loff_t *ppos)
386{
387 struct ath_softc *sc = file->private_data;
388 char buf[32];
389 unsigned int len;
390
391 len = sprintf(buf, "%d\n", sc->spec_config.period);
392 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
393}
394
395static ssize_t write_file_spectral_period(struct file *file,
396 const char __user *user_buf,
397 size_t count, loff_t *ppos)
398{
399 struct ath_softc *sc = file->private_data;
400 unsigned long val;
401 char buf[32];
402 ssize_t len;
403
404 len = min(count, sizeof(buf) - 1);
405 if (copy_from_user(buf, user_buf, len))
406 return -EFAULT;
407
408 buf[len] = '\0';
409 if (kstrtoul(buf, 0, &val))
410 return -EINVAL;
411
412 if (val < 0 || val > 255)
413 return -EINVAL;
414
415 sc->spec_config.period = val;
416 return count;
417}
418
419static const struct file_operations fops_spectral_period = {
420 .read = read_file_spectral_period,
421 .write = write_file_spectral_period,
422 .open = simple_open,
423 .owner = THIS_MODULE,
424 .llseek = default_llseek,
425};
426
427/***********************/
428/* spectral_fft_period */
429/***********************/
430
431static ssize_t read_file_spectral_fft_period(struct file *file,
432 char __user *user_buf,
433 size_t count, loff_t *ppos)
434{
435 struct ath_softc *sc = file->private_data;
436 char buf[32];
437 unsigned int len;
438
439 len = sprintf(buf, "%d\n", sc->spec_config.fft_period);
440 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
441}
442
443static ssize_t write_file_spectral_fft_period(struct file *file,
444 const char __user *user_buf,
445 size_t count, loff_t *ppos)
446{
447 struct ath_softc *sc = file->private_data;
448 unsigned long val;
449 char buf[32];
450 ssize_t len;
451
452 len = min(count, sizeof(buf) - 1);
453 if (copy_from_user(buf, user_buf, len))
454 return -EFAULT;
455
456 buf[len] = '\0';
457 if (kstrtoul(buf, 0, &val))
458 return -EINVAL;
459
460 if (val < 0 || val > 15)
461 return -EINVAL;
462
463 sc->spec_config.fft_period = val;
464 return count;
465}
466
467static const struct file_operations fops_spectral_fft_period = {
468 .read = read_file_spectral_fft_period,
469 .write = write_file_spectral_fft_period,
470 .open = simple_open,
471 .owner = THIS_MODULE,
472 .llseek = default_llseek,
473};
474
475/*******************/
476/* Relay interface */
477/*******************/
478
479static struct dentry *create_buf_file_handler(const char *filename,
480 struct dentry *parent,
481 umode_t mode,
482 struct rchan_buf *buf,
483 int *is_global)
484{
485 struct dentry *buf_file;
486
487 buf_file = debugfs_create_file(filename, mode, parent, buf,
488 &relay_file_operations);
489 *is_global = 1;
490 return buf_file;
491}
492
493static int remove_buf_file_handler(struct dentry *dentry)
494{
495 debugfs_remove(dentry);
496
497 return 0;
498}
499
500static struct rchan_callbacks rfs_spec_scan_cb = {
501 .create_buf_file = create_buf_file_handler,
502 .remove_buf_file = remove_buf_file_handler,
503};
504
505/*********************/
506/* Debug Init/Deinit */
507/*********************/
508
509void ath9k_spectral_deinit_debug(struct ath_softc *sc)
510{
511 if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
512 relay_close(sc->rfs_chan_spec_scan);
513 sc->rfs_chan_spec_scan = NULL;
514 }
515}
516
517void ath9k_spectral_init_debug(struct ath_softc *sc)
518{
519 sc->rfs_chan_spec_scan = relay_open("spectral_scan",
520 sc->debug.debugfs_phy,
521 1024, 256, &rfs_spec_scan_cb,
522 NULL);
523 debugfs_create_file("spectral_scan_ctl",
524 S_IRUSR | S_IWUSR,
525 sc->debug.debugfs_phy, sc,
526 &fops_spec_scan_ctl);
527 debugfs_create_file("spectral_short_repeat",
528 S_IRUSR | S_IWUSR,
529 sc->debug.debugfs_phy, sc,
530 &fops_spectral_short_repeat);
531 debugfs_create_file("spectral_count",
532 S_IRUSR | S_IWUSR,
533 sc->debug.debugfs_phy, sc,
534 &fops_spectral_count);
535 debugfs_create_file("spectral_period",
536 S_IRUSR | S_IWUSR,
537 sc->debug.debugfs_phy, sc,
538 &fops_spectral_period);
539 debugfs_create_file("spectral_fft_period",
540 S_IRUSR | S_IWUSR,
541 sc->debug.debugfs_phy, sc,
542 &fops_spectral_fft_period);
543}
diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h
new file mode 100644
index 000000000000..ead63412ee1a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/spectral.h
@@ -0,0 +1,212 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef SPECTRAL_H
18#define SPECTRAL_H
19
20/* enum spectral_mode:
21 *
22 * @SPECTRAL_DISABLED: spectral mode is disabled
23 * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
24 * something else.
25 * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
26 * is performed manually.
27 * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
28 * during a channel scan.
29 */
30enum spectral_mode {
31 SPECTRAL_DISABLED = 0,
32 SPECTRAL_BACKGROUND,
33 SPECTRAL_MANUAL,
34 SPECTRAL_CHANSCAN,
35};
36
37#define SPECTRAL_SCAN_BITMASK 0x10
38/* Radar info packet format, used for DFS and spectral formats. */
39struct ath_radar_info {
40 u8 pulse_length_pri;
41 u8 pulse_length_ext;
42 u8 pulse_bw_info;
43} __packed;
44
45/* The HT20 spectral data has 4 bytes of additional information at it's end.
46 *
47 * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
48 * [7:0]: all bins max_magnitude[9:2]
49 * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
50 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
51 */
52struct ath_ht20_mag_info {
53 u8 all_bins[3];
54 u8 max_exp;
55} __packed;
56
57#define SPECTRAL_HT20_NUM_BINS 56
58
59/* WARNING: don't actually use this struct! MAC may vary the amount of
60 * data by -1/+2. This struct is for reference only.
61 */
62struct ath_ht20_fft_packet {
63 u8 data[SPECTRAL_HT20_NUM_BINS];
64 struct ath_ht20_mag_info mag_info;
65 struct ath_radar_info radar_info;
66} __packed;
67
68#define SPECTRAL_HT20_TOTAL_DATA_LEN (sizeof(struct ath_ht20_fft_packet))
69
70/* Dynamic 20/40 mode:
71 *
72 * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
73 * [7:0]: lower bins max_magnitude[9:2]
74 * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
75 * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
76 * [7:0]: upper bins max_magnitude[9:2]
77 * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
78 * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
79 */
80struct ath_ht20_40_mag_info {
81 u8 lower_bins[3];
82 u8 upper_bins[3];
83 u8 max_exp;
84} __packed;
85
86#define SPECTRAL_HT20_40_NUM_BINS 128
87
88/* WARNING: don't actually use this struct! MAC may vary the amount of
89 * data. This struct is for reference only.
90 */
91struct ath_ht20_40_fft_packet {
92 u8 data[SPECTRAL_HT20_40_NUM_BINS];
93 struct ath_ht20_40_mag_info mag_info;
94 struct ath_radar_info radar_info;
95} __packed;
96
97
98#define SPECTRAL_HT20_40_TOTAL_DATA_LEN (sizeof(struct ath_ht20_40_fft_packet))
99
100/* grabs the max magnitude from the all/upper/lower bins */
101static inline u16 spectral_max_magnitude(u8 *bins)
102{
103 return (bins[0] & 0xc0) >> 6 |
104 (bins[1] & 0xff) << 2 |
105 (bins[2] & 0x03) << 10;
106}
107
108/* return the max magnitude from the all/upper/lower bins */
109static inline u8 spectral_max_index(u8 *bins)
110{
111 s8 m = (bins[2] & 0xfc) >> 2;
112
113 /* TODO: this still doesn't always report the right values ... */
114 if (m > 32)
115 m |= 0xe0;
116 else
117 m &= ~0xe0;
118
119 return m + 29;
120}
121
122/* return the bitmap weight from the all/upper/lower bins */
123static inline u8 spectral_bitmap_weight(u8 *bins)
124{
125 return bins[0] & 0x3f;
126}
127
128/* FFT sample format given to userspace via debugfs.
129 *
130 * Please keep the type/length at the front position and change
131 * other fields after adding another sample type
132 *
133 * TODO: this might need rework when switching to nl80211-based
134 * interface.
135 */
136enum ath_fft_sample_type {
137 ATH_FFT_SAMPLE_HT20 = 1,
138 ATH_FFT_SAMPLE_HT20_40,
139};
140
141struct fft_sample_tlv {
142 u8 type; /* see ath_fft_sample */
143 __be16 length;
144 /* type dependent data follows */
145} __packed;
146
147struct fft_sample_ht20 {
148 struct fft_sample_tlv tlv;
149
150 u8 max_exp;
151
152 __be16 freq;
153 s8 rssi;
154 s8 noise;
155
156 __be16 max_magnitude;
157 u8 max_index;
158 u8 bitmap_weight;
159
160 __be64 tsf;
161
162 u8 data[SPECTRAL_HT20_NUM_BINS];
163} __packed;
164
165struct fft_sample_ht20_40 {
166 struct fft_sample_tlv tlv;
167
168 u8 channel_type;
169 __be16 freq;
170
171 s8 lower_rssi;
172 s8 upper_rssi;
173
174 __be64 tsf;
175
176 s8 lower_noise;
177 s8 upper_noise;
178
179 __be16 lower_max_magnitude;
180 __be16 upper_max_magnitude;
181
182 u8 lower_max_index;
183 u8 upper_max_index;
184
185 u8 lower_bitmap_weight;
186 u8 upper_bitmap_weight;
187
188 u8 max_exp;
189
190 u8 data[SPECTRAL_HT20_40_NUM_BINS];
191} __packed;
192
193void ath9k_spectral_init_debug(struct ath_softc *sc);
194void ath9k_spectral_deinit_debug(struct ath_softc *sc);
195
196void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw);
197int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
198 enum spectral_mode spectral_mode);
199
200#ifdef CONFIG_ATH9K_DEBUGFS
201int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
202 struct ath_rx_status *rs, u64 tsf);
203#else
204static inline int ath_process_fft(struct ath_softc *sc,
205 struct ieee80211_hdr *hdr,
206 struct ath_rx_status *rs, u64 tsf)
207{
208 return 0;
209}
210#endif /* CONFIG_ATH9K_DEBUGFS */
211
212#endif /* SPECTRAL_H */
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
new file mode 100644
index 000000000000..b686a7498450
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -0,0 +1,272 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static void ath9k_tx99_stop(struct ath_softc *sc)
20{
21 struct ath_hw *ah = sc->sc_ah;
22 struct ath_common *common = ath9k_hw_common(ah);
23
24 ath_drain_all_txq(sc);
25 ath_startrecv(sc);
26
27 ath9k_hw_set_interrupts(ah);
28 ath9k_hw_enable_interrupts(ah);
29
30 ieee80211_wake_queues(sc->hw);
31
32 kfree_skb(sc->tx99_skb);
33 sc->tx99_skb = NULL;
34 sc->tx99_state = false;
35
36 ath9k_hw_tx99_stop(sc->sc_ah);
37 ath_dbg(common, XMIT, "TX99 stopped\n");
38}
39
40static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
41{
42 static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
43 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
44 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
45 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
46 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
47 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
48 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
49 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
50 u32 len = 1200;
51 struct ieee80211_tx_rate *rate;
52 struct ieee80211_hw *hw = sc->hw;
53 struct ath_hw *ah = sc->sc_ah;
54 struct ieee80211_hdr *hdr;
55 struct ieee80211_tx_info *tx_info;
56 struct sk_buff *skb;
57
58 skb = alloc_skb(len, GFP_KERNEL);
59 if (!skb)
60 return NULL;
61
62 skb_put(skb, len);
63
64 memset(skb->data, 0, len);
65
66 hdr = (struct ieee80211_hdr *)skb->data;
67 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
68 hdr->duration_id = 0;
69
70 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
71 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
72 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
73
74 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
75
76 tx_info = IEEE80211_SKB_CB(skb);
77 memset(tx_info, 0, sizeof(*tx_info));
78 rate = &tx_info->control.rates[0];
79 tx_info->band = hw->conf.chandef.chan->band;
80 tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
81 tx_info->control.vif = sc->tx99_vif;
82 rate->count = 1;
83 if (ah->curchan && IS_CHAN_HT(ah->curchan)) {
84 rate->flags |= IEEE80211_TX_RC_MCS;
85 if (IS_CHAN_HT40(ah->curchan))
86 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
87 }
88
89 memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
90
91 return skb;
92}
93
94static void ath9k_tx99_deinit(struct ath_softc *sc)
95{
96 ath_reset(sc);
97
98 ath9k_ps_wakeup(sc);
99 ath9k_tx99_stop(sc);
100 ath9k_ps_restore(sc);
101}
102
103static int ath9k_tx99_init(struct ath_softc *sc)
104{
105 struct ieee80211_hw *hw = sc->hw;
106 struct ath_hw *ah = sc->sc_ah;
107 struct ath_common *common = ath9k_hw_common(ah);
108 struct ath_tx_control txctl;
109 int r;
110
111 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
112 ath_err(common,
113 "driver is in invalid state unable to use TX99");
114 return -EINVAL;
115 }
116
117 sc->tx99_skb = ath9k_build_tx99_skb(sc);
118 if (!sc->tx99_skb)
119 return -ENOMEM;
120
121 memset(&txctl, 0, sizeof(txctl));
122 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
123
124 ath_reset(sc);
125
126 ath9k_ps_wakeup(sc);
127
128 ath9k_hw_disable_interrupts(ah);
129 atomic_set(&ah->intr_ref_cnt, -1);
130 ath_drain_all_txq(sc);
131 ath_stoprecv(sc);
132
133 sc->tx99_state = true;
134
135 ieee80211_stop_queues(hw);
136
137 if (sc->tx99_power == MAX_RATE_POWER + 1)
138 sc->tx99_power = MAX_RATE_POWER;
139
140 ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
141 r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
142 if (r) {
143 ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
144 return r;
145 }
146
147 ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
148 sc->tx99_power,
149 sc->tx99_power / 2);
150
151 /* We leave the harware awake as it will be chugging on */
152
153 return 0;
154}
155
156static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
157 size_t count, loff_t *ppos)
158{
159 struct ath_softc *sc = file->private_data;
160 char buf[3];
161 unsigned int len;
162
163 len = sprintf(buf, "%d\n", sc->tx99_state);
164 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
165}
166
167static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
168 size_t count, loff_t *ppos)
169{
170 struct ath_softc *sc = file->private_data;
171 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
172 char buf[32];
173 bool start;
174 ssize_t len;
175 int r;
176
177 if (sc->nvifs > 1)
178 return -EOPNOTSUPP;
179
180 len = min(count, sizeof(buf) - 1);
181 if (copy_from_user(buf, user_buf, len))
182 return -EFAULT;
183
184 if (strtobool(buf, &start))
185 return -EINVAL;
186
187 if (start == sc->tx99_state) {
188 if (!start)
189 return count;
190 ath_dbg(common, XMIT, "Resetting TX99\n");
191 ath9k_tx99_deinit(sc);
192 }
193
194 if (!start) {
195 ath9k_tx99_deinit(sc);
196 return count;
197 }
198
199 r = ath9k_tx99_init(sc);
200 if (r)
201 return r;
202
203 return count;
204}
205
206static const struct file_operations fops_tx99 = {
207 .read = read_file_tx99,
208 .write = write_file_tx99,
209 .open = simple_open,
210 .owner = THIS_MODULE,
211 .llseek = default_llseek,
212};
213
214static ssize_t read_file_tx99_power(struct file *file,
215 char __user *user_buf,
216 size_t count, loff_t *ppos)
217{
218 struct ath_softc *sc = file->private_data;
219 char buf[32];
220 unsigned int len;
221
222 len = sprintf(buf, "%d (%d dBm)\n",
223 sc->tx99_power,
224 sc->tx99_power / 2);
225
226 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
227}
228
229static ssize_t write_file_tx99_power(struct file *file,
230 const char __user *user_buf,
231 size_t count, loff_t *ppos)
232{
233 struct ath_softc *sc = file->private_data;
234 int r;
235 u8 tx_power;
236
237 r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
238 if (r)
239 return r;
240
241 if (tx_power > MAX_RATE_POWER)
242 return -EINVAL;
243
244 sc->tx99_power = tx_power;
245
246 ath9k_ps_wakeup(sc);
247 ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
248 ath9k_ps_restore(sc);
249
250 return count;
251}
252
253static const struct file_operations fops_tx99_power = {
254 .read = read_file_tx99_power,
255 .write = write_file_tx99_power,
256 .open = simple_open,
257 .owner = THIS_MODULE,
258 .llseek = default_llseek,
259};
260
261void ath9k_tx99_init_debug(struct ath_softc *sc)
262{
263 if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah))
264 return;
265
266 debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
267 sc->debug.debugfs_phy, sc,
268 &fops_tx99);
269 debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
270 sc->debug.debugfs_phy, sc,
271 &fops_tx99_power);
272}
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 81c88dd606dc..1b3230fa3651 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012 Qualcomm Atheros, Inc. 2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -14,409 +14,347 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/export.h>
18#include "ath9k.h" 17#include "ath9k.h"
19#include "reg.h"
20#include "hw-ops.h"
21 18
22const char *ath9k_hw_wow_event_to_string(u32 wow_event) 19static const struct wiphy_wowlan_support ath9k_wowlan_support = {
23{ 20 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
24 if (wow_event & AH_WOW_MAGIC_PATTERN_EN) 21 .n_patterns = MAX_NUM_USER_PATTERN,
25 return "Magic pattern"; 22 .pattern_min_len = 1,
26 if (wow_event & AH_WOW_USER_PATTERN_EN) 23 .pattern_max_len = MAX_PATTERN_SIZE,
27 return "User pattern"; 24};
28 if (wow_event & AH_WOW_LINK_CHANGE)
29 return "Link change";
30 if (wow_event & AH_WOW_BEACON_MISS)
31 return "Beacon miss";
32
33 return "unknown reason";
34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36 25
37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 26static void ath9k_wow_map_triggers(struct ath_softc *sc,
27 struct cfg80211_wowlan *wowlan,
28 u32 *wow_triggers)
38{ 29{
39 struct ath_common *common = ath9k_hw_common(ah); 30 if (wowlan->disconnect)
31 *wow_triggers |= AH_WOW_LINK_CHANGE |
32 AH_WOW_BEACON_MISS;
33 if (wowlan->magic_pkt)
34 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
40 35
41 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 36 if (wowlan->n_patterns)
37 *wow_triggers |= AH_WOW_USER_PATTERN_EN;
42 38
43 /* set rx disable bit */ 39 sc->wow_enabled = *wow_triggers;
44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
45
46 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
49 return;
50 }
51 40
52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
53} 41}
54 42
55static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) 43static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
56{ 44{
45 struct ath_hw *ah = sc->sc_ah;
57 struct ath_common *common = ath9k_hw_common(ah); 46 struct ath_common *common = ath9k_hw_common(ah);
58 u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN]; 47 int pattern_count = 0;
59 u32 ctl[13] = {0}; 48 int i, byte_cnt;
60 u32 data_word[KAL_NUM_DATA_WORDS]; 49 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
61 u8 i; 50 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
62 u32 wow_ka_data_word0;
63
64 memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
65 memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
66
67 /* set the transmit buffer */
68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
69 ctl[1] = 0;
70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
71 ctl[4] = 0;
72 ctl[7] = (ah->txchainmask) << 2;
73 ctl[2] = 0xf << 16; /* tx_tries 0 */
74
75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
77
78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
79
80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
82 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
83 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
84 data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
85 (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
86 data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
87 (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
88 data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
89 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
90 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
91
92 if (AR_SREV_9462_20(ah)) {
93 /* AR9462 2.0 has an extra descriptor word (time based
94 * discard) compared to other chips */
95 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
96 wow_ka_data_word0 = AR_WOW_TXBUF(13);
97 } else {
98 wow_ka_data_word0 = AR_WOW_TXBUF(12);
99 }
100
101 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
102 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
103
104}
105
106void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
107 u8 *user_mask, int pattern_count,
108 int pattern_len)
109{
110 int i;
111 u32 pattern_val, mask_val;
112 u32 set, clr;
113 51
114 /* FIXME: should check count by querying the hardware capability */ 52 memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
115 if (pattern_count >= MAX_NUM_PATTERN) 53 memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
116 return;
117
118 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
119
120 /* set the registers for pattern */
121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
122 memcpy(&pattern_val, user_pattern, 4);
123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
124 pattern_val);
125 user_pattern += 4;
126 }
127
128 /* set the registers for mask */
129 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
130 memcpy(&mask_val, user_mask, 4);
131 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
132 user_mask += 4;
133 }
134 54
135 /* set the pattern length to be matched 55 /*
56 * Create Dissassociate / Deauthenticate packet filter
57 *
58 * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
59 * +--------------+----------+---------+--------+--------+----
60 * + Frame Control+ Duration + DA + SA + BSSID +
61 * +--------------+----------+---------+--------+--------+----
136 * 62 *
137 * AR_WOW_LENGTH1_REG1 63 * The above is the management frame format for disassociate/
138 * bit 31:24 pattern 0 length 64 * deauthenticate pattern, from this we need to match the first byte
139 * bit 23:16 pattern 1 length 65 * of 'Frame Control' and DA, SA, and BSSID fields
140 * bit 15:8 pattern 2 length 66 * (skipping 2nd byte of FC and Duration feild.
141 * bit 7:0 pattern 3 length
142 * 67 *
143 * AR_WOW_LENGTH1_REG2 68 * Disassociate pattern
144 * bit 31:24 pattern 4 length 69 * --------------------
145 * bit 23:16 pattern 5 length 70 * Frame control = 00 00 1010
146 * bit 15:8 pattern 6 length 71 * DA, SA, BSSID = x:x:x:x:x:x
147 * bit 7:0 pattern 7 length 72 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
73 * | x:x:x:x:x:x -- 22 bytes
148 * 74 *
149 * the below logic writes out the new 75 * Deauthenticate pattern
150 * pattern length for the corresponding 76 * ----------------------
151 * pattern_count, while masking out the 77 * Frame control = 00 00 1100
152 * other fields 78 * DA, SA, BSSID = x:x:x:x:x:x
79 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
80 * | x:x:x:x:x:x -- 22 bytes
153 */ 81 */
154 82
155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 83 /* Create Disassociate Pattern first */
156
157 if (pattern_count < 4) {
158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
160 AR_WOW_LEN1_SHIFT(pattern_count);
161 clr = AR_WOW_LENGTH1_MASK(pattern_count);
162 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
163 } else {
164 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
165 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
166 AR_WOW_LEN2_SHIFT(pattern_count);
167 clr = AR_WOW_LENGTH2_MASK(pattern_count);
168 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
169 }
170 84
171} 85 byte_cnt = 0;
172EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
173 86
174u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) 87 /* Fill out the mask with all FF's */
175{
176 u32 wow_status = 0;
177 u32 val = 0, rval;
178 88
179 /* 89 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
180 * read the WoW status register to know 90 dis_deauth_mask[i] = 0xff;
181 * the wakeup reason
182 */
183 rval = REG_READ(ah, AR_WOW_PATTERN);
184 val = AR_WOW_STATUS(rval);
185 91
186 /* 92 /* copy the first byte of frame control field */
187 * mask only the WoW events that we have enabled. Sometimes 93 dis_deauth_pattern[byte_cnt] = 0xa0;
188 * we have spurious WoW events from the AR_WOW_PATTERN 94 byte_cnt++;
189 * register. This mask will clean it up.
190 */
191 95
192 val &= ah->wow_event_mask; 96 /* skip 2nd byte of frame control and Duration field */
193 97 byte_cnt += 3;
194 if (val) {
195 if (val & AR_WOW_MAGIC_PAT_FOUND)
196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
197 if (AR_WOW_PATTERN_FOUND(val))
198 wow_status |= AH_WOW_USER_PATTERN_EN;
199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
200 wow_status |= AH_WOW_LINK_CHANGE;
201 if (val & AR_WOW_BEACON_FAIL)
202 wow_status |= AH_WOW_BEACON_MISS;
203 }
204 98
205 /* 99 /*
206 * set and clear WOW_PME_CLEAR registers for the chip to 100 * need not match the destination mac address, it can be a broadcast
207 * generate next wow signal. 101 * mac address or an unicast to this station
208 * disable D3 before accessing other registers ?
209 */ 102 */
103 byte_cnt += 6;
210 104
211 /* do we need to check the bit value 0x01000000 (7-10) ?? */ 105 /* copy the source mac address */
212 REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR, 106 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
213 AR_PMCTRL_PWR_STATE_D1D3);
214 107
215 /* 108 byte_cnt += 6;
216 * clear all events
217 */
218 REG_WRITE(ah, AR_WOW_PATTERN,
219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
220 109
221 /* 110 /* copy the bssid, its same as the source mac address */
222 * restore the beacon threshold to init value 111
223 */ 112 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 113
114 /* Create Disassociate pattern mask */
115
116 dis_deauth_mask[0] = 0xfe;
117 dis_deauth_mask[1] = 0x03;
118 dis_deauth_mask[2] = 0xc0;
119
120 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
225 121
122 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
123 pattern_count, byte_cnt);
124
125 pattern_count++;
226 /* 126 /*
227 * Restore the way the PCI-E reset, Power-On-Reset, external 127 * for de-authenticate pattern, only the first byte of the frame
228 * PCIE_POR_SHORT pins are tied to its original value. 128 * control field gets changed from 0xA0 to 0xC0
229 * Previously just before WoW sleep, we untie the PCI-E
230 * reset to our Chip's Power On Reset so that any PCI-E
231 * reset from the bus will not reset our chip
232 */ 129 */
233 if (ah->is_pciexpress) 130 dis_deauth_pattern[0] = 0xC0;
234 ath9k_hw_configpcipowersave(ah, false);
235 131
236 ah->wow_event_mask = 0; 132 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
133 pattern_count, byte_cnt);
237 134
238 return wow_status;
239} 135}
240EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
241 136
242void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) 137static void ath9k_wow_add_pattern(struct ath_softc *sc,
138 struct cfg80211_wowlan *wowlan)
243{ 139{
244 u32 wow_event_mask; 140 struct ath_hw *ah = sc->sc_ah;
245 u32 set, clr; 141 struct ath9k_wow_pattern *wow_pattern = NULL;
142 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
143 int mask_len;
144 s8 i = 0;
246 145
247 /* 146 if (!wowlan->n_patterns)
248 * wow_event_mask is a mask to the AR_WOW_PATTERN register to 147 return;
249 * indicate which WoW events we have enabled. The WoW events
250 * are from the 'pattern_enable' in this function and
251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
252 */
253 wow_event_mask = ah->wow_event_mask;
254 148
255 /* 149 /*
256 * Untie Power-on-Reset from the PCI-E-Reset. When we are in 150 * Add the new user configured patterns
257 * WOW sleep, we do want the Reset from the PCI-E to disturb
258 * our hw state
259 */ 151 */
260 if (ah->is_pciexpress) { 152 for (i = 0; i < wowlan->n_patterns; i++) {
153
154 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
155
156 if (!wow_pattern)
157 return;
158
159 /*
160 * TODO: convert the generic user space pattern to
161 * appropriate chip specific/802.11 pattern.
162 */
163
164 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
165 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
166 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
167 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
168 patterns[i].pattern_len);
169 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
170 wow_pattern->pattern_len = patterns[i].pattern_len;
171
261 /* 172 /*
262 * we need to untie the internal POR (power-on-reset) 173 * just need to take care of deauth and disssoc pattern,
263 * to the external PCI-E reset. We also need to tie 174 * make sure we don't overwrite them.
264 * the PCI-E Phy reset to the PCI-E reset.
265 */ 175 */
266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 176
267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE; 177 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
268 REG_RMW(ah, AR_WA, set, clr); 178 wow_pattern->mask_bytes,
179 i + 2,
180 wow_pattern->pattern_len);
181 kfree(wow_pattern);
182
269 } 183 }
270 184
271 /* 185}
272 * set the power states appropriately and enable PME
273 */
274 set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
275 AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
276 186
277 /* 187int ath9k_suspend(struct ieee80211_hw *hw,
278 * set and clear WOW_PME_CLEAR registers for the chip 188 struct cfg80211_wowlan *wowlan)
279 * to generate next wow signal. 189{
280 */ 190 struct ath_softc *sc = hw->priv;
281 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 191 struct ath_hw *ah = sc->sc_ah;
282 clr = AR_PMCTRL_WOW_PME_CLR; 192 struct ath_common *common = ath9k_hw_common(ah);
283 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 193 u32 wow_triggers_enabled = 0;
194 int ret = 0;
284 195
285 /* 196 mutex_lock(&sc->mutex);
286 * Setup for:
287 * - beacon misses
288 * - magic pattern
289 * - keep alive timeout
290 * - pattern matching
291 */
292 197
293 /* 198 ath_cancel_work(sc);
294 * Program default values for pattern backoff, aifs/slot/KAL count, 199 ath_stop_ani(sc);
295 * beacon miss timeout, KAL timeout, etc.
296 */
297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
299 200
300 set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | 201 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
301 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | 202 ath_dbg(common, ANY, "Device not present\n");
302 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); 203 ret = -EINVAL;
303 REG_SET_BIT(ah, AR_WOW_COUNT, set); 204 goto fail_wow;
205 }
304 206
305 if (pattern_enable & AH_WOW_BEACON_MISS) 207 if (WARN_ON(!wowlan)) {
306 set = AR_WOW_BEACON_TIMO; 208 ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
307 /* We are not using beacon miss, program a large value */ 209 ret = -EINVAL;
308 else 210 goto fail_wow;
309 set = AR_WOW_BEACON_TIMO_MAX; 211 }
310 212
311 REG_WRITE(ah, AR_WOW_BCN_TIMO, set); 213 if (!device_can_wakeup(sc->dev)) {
214 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
215 ret = 1;
216 goto fail_wow;
217 }
312 218
313 /* 219 /*
314 * Keep alive timo in ms except AR9280 220 * none of the sta vifs are associated
221 * and we are not currently handling multivif
222 * cases, for instance we have to seperately
223 * configure 'keep alive frame' for each
224 * STA.
315 */ 225 */
316 if (!pattern_enable)
317 set = AR_WOW_KEEP_ALIVE_NEVER;
318 else
319 set = KAL_TIMEOUT * 32;
320 226
321 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); 227 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
228 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
229 ret = 1;
230 goto fail_wow;
231 }
232
233 if (sc->nvifs > 1) {
234 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
235 ret = 1;
236 goto fail_wow;
237 }
238
239 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
240
241 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
242 wow_triggers_enabled);
243
244 ath9k_ps_wakeup(sc);
245
246 ath9k_stop_btcoex(sc);
322 247
323 /* 248 /*
324 * Keep alive delay in us. based on 'power on clock', 249 * Enable wake up on recieving disassoc/deauth
325 * therefore in usec 250 * frame by default.
326 */ 251 */
327 set = KAL_DELAY * 1000; 252 ath9k_wow_add_disassoc_deauth_pattern(sc);
328 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); 253
254 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
255 ath9k_wow_add_pattern(sc, wowlan);
329 256
257 spin_lock_bh(&sc->sc_pcu_lock);
330 /* 258 /*
331 * Create keep alive pattern to respond to beacons 259 * To avoid false wake, we enable beacon miss interrupt only
260 * when we go to sleep. We save the current interrupt mask
261 * so we can restore it after the system wakes up
332 */ 262 */
333 ath9k_wow_create_keep_alive_pattern(ah); 263 sc->wow_intr_before_sleep = ah->imask;
264 ah->imask &= ~ATH9K_INT_GLOBAL;
265 ath9k_hw_disable_interrupts(ah);
266 ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
267 ath9k_hw_set_interrupts(ah);
268 ath9k_hw_enable_interrupts(ah);
269
270 spin_unlock_bh(&sc->sc_pcu_lock);
334 271
335 /* 272 /*
336 * Configure MAC WoW Registers 273 * we can now sync irq and kill any running tasklets, since we already
274 * disabled interrupts and not holding a spin lock
337 */ 275 */
338 set = 0; 276 synchronize_irq(sc->irq);
339 /* Send keep alive timeouts anyway */ 277 tasklet_kill(&sc->intr_tq);
340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
341 278
342 if (pattern_enable & AH_WOW_LINK_CHANGE) 279 ath9k_hw_wow_enable(ah, wow_triggers_enabled);
343 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
344 else
345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
346 280
347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 281 ath9k_ps_restore(sc);
348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 282 ath_dbg(common, ANY, "WoW enabled in ath9k\n");
283 atomic_inc(&sc->wow_sleep_proc_intr);
349 284
350 /* 285fail_wow:
351 * we are relying on a bmiss failure. ensure we have 286 mutex_unlock(&sc->mutex);
352 * enough threshold to prevent false positives 287 return ret;
353 */ 288}
354 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 289
355 AR_WOW_BMISSTHRESHOLD); 290int ath9k_resume(struct ieee80211_hw *hw)
291{
292 struct ath_softc *sc = hw->priv;
293 struct ath_hw *ah = sc->sc_ah;
294 struct ath_common *common = ath9k_hw_common(ah);
295 u32 wow_status;
356 296
357 set = 0; 297 mutex_lock(&sc->mutex);
358 clr = 0;
359 298
360 if (pattern_enable & AH_WOW_BEACON_MISS) { 299 ath9k_ps_wakeup(sc);
361 set = AR_WOW_BEACON_FAIL_EN; 300
362 wow_event_mask |= AR_WOW_BEACON_FAIL; 301 spin_lock_bh(&sc->sc_pcu_lock);
363 } else { 302
364 clr = AR_WOW_BEACON_FAIL_EN; 303 ath9k_hw_disable_interrupts(ah);
304 ah->imask = sc->wow_intr_before_sleep;
305 ath9k_hw_set_interrupts(ah);
306 ath9k_hw_enable_interrupts(ah);
307
308 spin_unlock_bh(&sc->sc_pcu_lock);
309
310 wow_status = ath9k_hw_wow_wakeup(ah);
311
312 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
313 /*
314 * some devices may not pick beacon miss
315 * as the reason they woke up so we add
316 * that here for that shortcoming.
317 */
318 wow_status |= AH_WOW_BEACON_MISS;
319 atomic_dec(&sc->wow_got_bmiss_intr);
320 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
365 } 321 }
366 322
367 REG_RMW(ah, AR_WOW_BCN_EN, set, clr); 323 atomic_dec(&sc->wow_sleep_proc_intr);
368 324
369 set = 0; 325 if (wow_status) {
370 clr = 0; 326 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
371 /* 327 ath9k_hw_wow_event_to_string(wow_status), wow_status);
372 * Enable the magic packet registers
373 */
374 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
375 set = AR_WOW_MAGIC_EN;
376 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
377 } else {
378 clr = AR_WOW_MAGIC_EN;
379 } 328 }
380 set |= AR_WOW_MAC_INTR_EN;
381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
382 329
383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, 330 ath_restart_work(sc);
384 AR_WOW_PATTERN_SUPPORTED); 331 ath9k_start_btcoex(sc);
385 332
386 /* 333 ath9k_ps_restore(sc);
387 * Set the power states appropriately and enable PME 334 mutex_unlock(&sc->mutex);
388 */
389 clr = 0;
390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
391 AR_PMCTRL_PWR_PM_CTRL_ENA;
392 335
393 clr = AR_PCIE_PM_CTRL_ENA; 336 return 0;
394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 337}
395 338
396 /* 339void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
397 * this is needed to prevent the chip waking up 340{
398 * the host within 3-4 seconds with certain 341 struct ath_softc *sc = hw->priv;
399 * platform/BIOS. The fix is to enable
400 * D1 & D3 to match original definition and
401 * also match the OTP value. Anyway this
402 * is more related to SW WOW.
403 */
404 clr = AR_PMCTRL_PWR_STATE_D1D3;
405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
406 342
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL; 343 mutex_lock(&sc->mutex);
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 344 device_init_wakeup(sc->dev, 1);
345 device_set_wakeup_enable(sc->dev, enabled);
346 mutex_unlock(&sc->mutex);
347}
409 348
410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 349void ath9k_init_wow(struct ieee80211_hw *hw)
350{
351 struct ath_softc *sc = hw->priv;
411 352
412 /* to bring down WOW power low margin */ 353 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
413 set = BIT(13); 354 (sc->driver_data & ATH9K_PCI_WOW) &&
414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 355 device_can_wakeup(sc->dev))
415 /* HW WoW */ 356 hw->wiphy->wowlan = &ath9k_wowlan_support;
416 clr = BIT(5);
417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
418 357
419 ath9k_hw_set_powermode_wow_sleep(ah); 358 atomic_set(&sc->wow_sleep_proc_intr, -1);
420 ah->wow_event_mask = wow_event_mask; 359 atomic_set(&sc->wow_got_bmiss_intr, -1);
421} 360}
422EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b5a19e098f2d..0a75e2f68c9d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -47,8 +47,6 @@ static u16 bits_per_symbol[][2] = {
47 { 260, 540 }, /* 7: 64-QAM 5/6 */ 47 { 260, 540 }, /* 7: 64-QAM 5/6 */
48}; 48};
49 49
50#define IS_HT_RATE(_rate) ((_rate) & 0x80)
51
52static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 50static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
53 struct ath_atx_tid *tid, struct sk_buff *skb); 51 struct ath_atx_tid *tid, struct sk_buff *skb);
54static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 52static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
@@ -174,14 +172,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
174static struct ath_atx_tid * 172static struct ath_atx_tid *
175ath_get_skb_tid(struct ath_softc *sc, struct ath_node *an, struct sk_buff *skb) 173ath_get_skb_tid(struct ath_softc *sc, struct ath_node *an, struct sk_buff *skb)
176{ 174{
177 struct ieee80211_hdr *hdr; 175 u8 tidno = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
178 u8 tidno = 0;
179
180 hdr = (struct ieee80211_hdr *) skb->data;
181 if (ieee80211_is_data_qos(hdr->frame_control))
182 tidno = ieee80211_get_qos_ctl(hdr)[0];
183
184 tidno &= IEEE80211_QOS_CTL_TID_MASK;
185 return ATH_AN_2_TID(an, tidno); 176 return ATH_AN_2_TID(an, tidno);
186} 177}
187 178
@@ -781,11 +772,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
781 if (bt_aggr_limit) 772 if (bt_aggr_limit)
782 aggr_limit = bt_aggr_limit; 773 aggr_limit = bt_aggr_limit;
783 774
784 /*
785 * h/w can accept aggregates up to 16 bit lengths (65535).
786 * The IE, however can hold up to 65536, which shows up here
787 * as zero. Ignore 65536 since we are constrained by hw.
788 */
789 if (tid->an->maxampdu) 775 if (tid->an->maxampdu)
790 aggr_limit = min(aggr_limit, tid->an->maxampdu); 776 aggr_limit = min(aggr_limit, tid->an->maxampdu);
791 777
@@ -1410,8 +1396,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
1410 * has already been added. 1396 * has already been added.
1411 */ 1397 */
1412 if (sta->ht_cap.ht_supported) { 1398 if (sta->ht_cap.ht_supported) {
1413 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 1399 an->maxampdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
1414 sta->ht_cap.ampdu_factor); 1400 sta->ht_cap.ampdu_factor)) - 1;
1415 density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); 1401 density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
1416 an->mpdudensity = density; 1402 an->mpdudensity = density;
1417 } 1403 }
@@ -1790,6 +1776,9 @@ bool ath_drain_all_txq(struct ath_softc *sc)
1790 if (!ATH_TXQ_SETUP(sc, i)) 1776 if (!ATH_TXQ_SETUP(sc, i))
1791 continue; 1777 continue;
1792 1778
1779 if (!sc->tx.txq[i].axq_depth)
1780 continue;
1781
1793 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum)) 1782 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
1794 npend |= BIT(i); 1783 npend |= BIT(i);
1795 } 1784 }
@@ -2753,6 +2742,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2753 } 2742 }
2754} 2743}
2755 2744
2745#ifdef CONFIG_ATH9K_TX99
2746
2756int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, 2747int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
2757 struct ath_tx_control *txctl) 2748 struct ath_tx_control *txctl)
2758{ 2749{
@@ -2795,3 +2786,5 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
2795 2786
2796 return 0; 2787 return 0;
2797} 2788}
2789
2790#endif /* CONFIG_ATH9K_TX99 */
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 3d70cd277fd7..1c0af9cd9a85 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -37,7 +37,6 @@
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */ 38 */
39 39
40#include <linux/init.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/seq_file.h> 42#include <linux/seq_file.h>
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 349fa22a921a..4c8cdb097b65 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -37,7 +37,6 @@
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */ 38 */
39 39
40#include <linux/init.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/etherdevice.h> 42#include <linux/etherdevice.h>
@@ -1968,18 +1967,6 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
1968 return -ENOMEM; 1967 return -ENOMEM;
1969 ar->num_channels = chans; 1968 ar->num_channels = chans;
1970 1969
1971 /*
1972 * I measured this, a bandswitch takes roughly
1973 * 135 ms and a frequency switch about 80.
1974 *
1975 * FIXME: measure these values again once EEPROM settings
1976 * are used, that will influence them!
1977 */
1978 if (bands == 2)
1979 ar->hw->channel_change_time = 135 * 1000;
1980 else
1981 ar->hw->channel_change_time = 80 * 1000;
1982
1983 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); 1970 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
1984 1971
1985 /* second part of wiphy init */ 1972 /* second part of wiphy init */
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index e935f61c7fad..536bc46a2912 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -37,7 +37,6 @@
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */ 38 */
39 39
40#include <linux/init.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/etherdevice.h> 42#include <linux/etherdevice.h>
@@ -520,6 +519,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
520{ 519{
521 struct ieee80211_hdr *hdr = data; 520 struct ieee80211_hdr *hdr = data;
522 struct ieee80211_tim_ie *tim_ie; 521 struct ieee80211_tim_ie *tim_ie;
522 struct ath_common *common = &ar->common;
523 u8 *tim; 523 u8 *tim;
524 u8 tim_len; 524 u8 tim_len;
525 bool cam; 525 bool cam;
@@ -527,17 +527,13 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
527 if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) 527 if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS)))
528 return; 528 return;
529 529
530 /* check if this really is a beacon */
531 if (!ieee80211_is_beacon(hdr->frame_control))
532 return;
533
534 /* min. beacon length + FCS_LEN */ 530 /* min. beacon length + FCS_LEN */
535 if (len <= 40 + FCS_LEN) 531 if (len <= 40 + FCS_LEN)
536 return; 532 return;
537 533
534 /* check if this really is a beacon */
538 /* and only beacons from the associated BSSID, please */ 535 /* and only beacons from the associated BSSID, please */
539 if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) || 536 if (!ath_is_mybeacon(common, hdr) || !common->curaid)
540 !ar->common.curaid)
541 return; 537 return;
542 538
543 ar->ps.last_beacon = jiffies; 539 ar->ps.last_beacon = jiffies;
@@ -602,8 +598,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len)
602 598
603 if (bar->start_seq_num == entry_bar->start_seq_num && 599 if (bar->start_seq_num == entry_bar->start_seq_num &&
604 TID_CHECK(bar->control, entry_bar->control) && 600 TID_CHECK(bar->control, entry_bar->control) &&
605 ether_addr_equal(bar->ra, entry_bar->ta) && 601 ether_addr_equal_64bits(bar->ra, entry_bar->ta) &&
606 ether_addr_equal(bar->ta, entry_bar->ra)) { 602 ether_addr_equal_64bits(bar->ta, entry_bar->ra)) {
607 struct ieee80211_tx_info *tx_info; 603 struct ieee80211_tx_info *tx_info;
608 604
609 tx_info = IEEE80211_SKB_CB(entry_skb); 605 tx_info = IEEE80211_SKB_CB(entry_skb);
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index e3f696ee4d23..4cadfd48ffdf 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -37,7 +37,6 @@
37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 37 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */ 38 */
39 39
40#include <linux/init.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/etherdevice.h> 42#include <linux/etherdevice.h>
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 8e99540cd90e..8b0ac14d5c32 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -59,6 +59,14 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
59} 59}
60EXPORT_SYMBOL(ath_rxbuf_alloc); 60EXPORT_SYMBOL(ath_rxbuf_alloc);
61 61
62bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr)
63{
64 return ieee80211_is_beacon(hdr->frame_control) &&
65 !is_zero_ether_addr(common->curbssid) &&
66 ether_addr_equal_64bits(hdr->addr3, common->curbssid);
67}
68EXPORT_SYMBOL(ath_is_mybeacon);
69
62void ath_printk(const char *level, const struct ath_common* common, 70void ath_printk(const char *level, const struct ath_common* common,
63 const char *fmt, ...) 71 const char *fmt, ...)
64{ 72{
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 1217c52ab28e..e5e905910db4 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -37,17 +37,18 @@ static int __ath_regd_init(struct ath_regulatory *reg);
37 37
38/* We enable active scan on these a case by case basis by regulatory domain */ 38/* We enable active scan on these a case by case basis by regulatory domain */
39#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 39#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
40 NL80211_RRF_PASSIVE_SCAN) 40 NL80211_RRF_NO_IR)
41#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ 41#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
42 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) 42 NL80211_RRF_NO_IR | \
43 NL80211_RRF_NO_OFDM)
43 44
44/* We allow IBSS on these on a case by case basis by regulatory domain */ 45/* We allow IBSS on these on a case by case basis by regulatory domain */
45#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ 46#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
46 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 47 NL80211_RRF_NO_IR)
47#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ 48#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
48 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 49 NL80211_RRF_NO_IR)
49#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\ 50#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\
50 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 51 NL80211_RRF_NO_IR)
51 52
52#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ 53#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
53 ATH9K_2GHZ_CH12_13, \ 54 ATH9K_2GHZ_CH12_13, \
@@ -113,6 +114,87 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
113 } 114 }
114}; 115};
115 116
117static bool dynamic_country_user_possible(struct ath_regulatory *reg)
118{
119 if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
120 return true;
121
122 switch (reg->country_code) {
123 case CTRY_UNITED_STATES:
124 case CTRY_JAPAN1:
125 case CTRY_JAPAN2:
126 case CTRY_JAPAN3:
127 case CTRY_JAPAN4:
128 case CTRY_JAPAN5:
129 case CTRY_JAPAN6:
130 case CTRY_JAPAN7:
131 case CTRY_JAPAN8:
132 case CTRY_JAPAN9:
133 case CTRY_JAPAN10:
134 case CTRY_JAPAN11:
135 case CTRY_JAPAN12:
136 case CTRY_JAPAN13:
137 case CTRY_JAPAN14:
138 case CTRY_JAPAN15:
139 case CTRY_JAPAN16:
140 case CTRY_JAPAN17:
141 case CTRY_JAPAN18:
142 case CTRY_JAPAN19:
143 case CTRY_JAPAN20:
144 case CTRY_JAPAN21:
145 case CTRY_JAPAN22:
146 case CTRY_JAPAN23:
147 case CTRY_JAPAN24:
148 case CTRY_JAPAN25:
149 case CTRY_JAPAN26:
150 case CTRY_JAPAN27:
151 case CTRY_JAPAN28:
152 case CTRY_JAPAN29:
153 case CTRY_JAPAN30:
154 case CTRY_JAPAN31:
155 case CTRY_JAPAN32:
156 case CTRY_JAPAN33:
157 case CTRY_JAPAN34:
158 case CTRY_JAPAN35:
159 case CTRY_JAPAN36:
160 case CTRY_JAPAN37:
161 case CTRY_JAPAN38:
162 case CTRY_JAPAN39:
163 case CTRY_JAPAN40:
164 case CTRY_JAPAN41:
165 case CTRY_JAPAN42:
166 case CTRY_JAPAN43:
167 case CTRY_JAPAN44:
168 case CTRY_JAPAN45:
169 case CTRY_JAPAN46:
170 case CTRY_JAPAN47:
171 case CTRY_JAPAN48:
172 case CTRY_JAPAN49:
173 case CTRY_JAPAN50:
174 case CTRY_JAPAN51:
175 case CTRY_JAPAN52:
176 case CTRY_JAPAN53:
177 case CTRY_JAPAN54:
178 case CTRY_JAPAN55:
179 case CTRY_JAPAN56:
180 case CTRY_JAPAN57:
181 case CTRY_JAPAN58:
182 case CTRY_JAPAN59:
183 return false;
184 }
185
186 return true;
187}
188
189static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
190{
191 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
192 return false;
193 if (!dynamic_country_user_possible(reg))
194 return false;
195 return true;
196}
197
116static inline bool is_wwr_sku(u16 regd) 198static inline bool is_wwr_sku(u16 regd)
117{ 199{
118 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 200 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
@@ -177,118 +259,139 @@ static bool ath_is_radar_freq(u16 center_freq)
177 return (center_freq >= 5260 && center_freq <= 5700); 259 return (center_freq >= 5260 && center_freq <= 5700);
178} 260}
179 261
262static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
263 struct ieee80211_channel *ch)
264{
265 const struct ieee80211_reg_rule *reg_rule;
266
267 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
268 if (IS_ERR(reg_rule))
269 return;
270
271 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
272 if (ch->flags & IEEE80211_CHAN_NO_IR)
273 ch->flags &= ~IEEE80211_CHAN_NO_IR;
274}
275
276static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
277{
278 struct ieee80211_channel *ch;
279
280 ch = ieee80211_get_channel(wiphy, center_freq);
281 if (!ch)
282 return;
283
284 ath_force_clear_no_ir_chan(wiphy, ch);
285}
286
287static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
288{
289 ch->flags |= IEEE80211_CHAN_NO_IR;
290}
291
292static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
293{
294 struct ieee80211_channel *ch;
295
296 ch = ieee80211_get_channel(wiphy, center_freq);
297 if (!ch)
298 return;
299
300 ath_force_no_ir_chan(ch);
301}
302
303static void
304__ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
305 struct ath_regulatory *reg,
306 enum nl80211_reg_initiator initiator,
307 struct ieee80211_channel *ch)
308{
309 if (ath_is_radar_freq(ch->center_freq) ||
310 (ch->flags & IEEE80211_CHAN_RADAR))
311 return;
312
313 switch (initiator) {
314 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
315 ath_force_clear_no_ir_chan(wiphy, ch);
316 break;
317 case NL80211_REGDOM_SET_BY_USER:
318 if (ath_reg_dyn_country_user_allow(reg))
319 ath_force_clear_no_ir_chan(wiphy, ch);
320 break;
321 default:
322 if (ch->beacon_found)
323 ch->flags &= ~IEEE80211_CHAN_NO_IR;
324 }
325}
326
180/* 327/*
181 * N.B: These exception rules do not apply radar freqs. 328 * These exception rules do not apply radar frequencies.
182 * 329 *
183 * - We enable adhoc (or beaconing) if allowed by 11d 330 * - We enable initiating radiation if the country IE says its fine:
184 * - We enable active scan if the channel is allowed by 11d
185 * - If no country IE has been processed and a we determine we have 331 * - If no country IE has been processed and a we determine we have
186 * received a beacon on a channel we can enable active scan and 332 * received a beacon on a channel we can enable initiating radiation.
187 * adhoc (or beaconing).
188 */ 333 */
189static void 334static void
190ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 335ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
336 struct ath_regulatory *reg,
191 enum nl80211_reg_initiator initiator) 337 enum nl80211_reg_initiator initiator)
192{ 338{
193 enum ieee80211_band band; 339 enum ieee80211_band band;
194 struct ieee80211_supported_band *sband; 340 struct ieee80211_supported_band *sband;
195 const struct ieee80211_reg_rule *reg_rule;
196 struct ieee80211_channel *ch; 341 struct ieee80211_channel *ch;
197 unsigned int i; 342 unsigned int i;
198 343
199 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 344 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
200
201 if (!wiphy->bands[band]) 345 if (!wiphy->bands[band])
202 continue; 346 continue;
203
204 sband = wiphy->bands[band]; 347 sband = wiphy->bands[band];
205
206 for (i = 0; i < sband->n_channels; i++) { 348 for (i = 0; i < sband->n_channels; i++) {
207
208 ch = &sband->channels[i]; 349 ch = &sband->channels[i];
209 350 __ath_reg_apply_beaconing_flags(wiphy, reg,
210 if (ath_is_radar_freq(ch->center_freq) || 351 initiator, ch);
211 (ch->flags & IEEE80211_CHAN_RADAR))
212 continue;
213
214 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
215 reg_rule = freq_reg_info(wiphy, ch->center_freq);
216 if (IS_ERR(reg_rule))
217 continue;
218 /*
219 * If 11d had a rule for this channel ensure
220 * we enable adhoc/beaconing if it allows us to
221 * use it. Note that we would have disabled it
222 * by applying our static world regdomain by
223 * default during init, prior to calling our
224 * regulatory_hint().
225 */
226 if (!(reg_rule->flags &
227 NL80211_RRF_NO_IBSS))
228 ch->flags &=
229 ~IEEE80211_CHAN_NO_IBSS;
230 if (!(reg_rule->flags &
231 NL80211_RRF_PASSIVE_SCAN))
232 ch->flags &=
233 ~IEEE80211_CHAN_PASSIVE_SCAN;
234 } else {
235 if (ch->beacon_found)
236 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
237 IEEE80211_CHAN_PASSIVE_SCAN);
238 }
239 } 352 }
240 } 353 }
241
242} 354}
243 355
244/* Allows active scan scan on Ch 12 and 13 */ 356/**
357 * ath_reg_apply_ir_flags()
358 * @wiphy: the wiphy to use
359 * @initiator: the regulatory hint initiator
360 *
361 * If no country IE has been received always enable passive scan
362 * and no-ibss on these channels. This is only done for specific
363 * regulatory SKUs.
364 *
365 * If a country IE has been received check its rule for this
366 * channel first before enabling active scan. The passive scan
367 * would have been enforced by the initial processing of our
368 * custom regulatory domain.
369 */
245static void 370static void
246ath_reg_apply_active_scan_flags(struct wiphy *wiphy, 371ath_reg_apply_ir_flags(struct wiphy *wiphy,
247 enum nl80211_reg_initiator initiator) 372 struct ath_regulatory *reg,
373 enum nl80211_reg_initiator initiator)
248{ 374{
249 struct ieee80211_supported_band *sband; 375 struct ieee80211_supported_band *sband;
250 struct ieee80211_channel *ch;
251 const struct ieee80211_reg_rule *reg_rule;
252 376
253 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 377 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
254 if (!sband) 378 if (!sband)
255 return; 379 return;
256 380
257 /* 381 switch(initiator) {
258 * If no country IE has been received always enable active scan 382 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
259 * on these channels. This is only done for specific regulatory SKUs 383 ath_force_clear_no_ir_freq(wiphy, 2467);
260 */ 384 ath_force_clear_no_ir_freq(wiphy, 2472);
261 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 385 break;
262 ch = &sband->channels[11]; /* CH 12 */ 386 case NL80211_REGDOM_SET_BY_USER:
263 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 387 if (!ath_reg_dyn_country_user_allow(reg))
264 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 388 break;
265 ch = &sband->channels[12]; /* CH 13 */ 389 ath_force_clear_no_ir_freq(wiphy, 2467);
266 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 390 ath_force_clear_no_ir_freq(wiphy, 2472);
267 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 391 break;
268 return; 392 default:
269 } 393 ath_force_no_ir_freq(wiphy, 2467);
270 394 ath_force_no_ir_freq(wiphy, 2472);
271 /*
272 * If a country IE has been received check its rule for this
273 * channel first before enabling active scan. The passive scan
274 * would have been enforced by the initial processing of our
275 * custom regulatory domain.
276 */
277
278 ch = &sband->channels[11]; /* CH 12 */
279 reg_rule = freq_reg_info(wiphy, ch->center_freq);
280 if (!IS_ERR(reg_rule)) {
281 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
282 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
283 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
284 }
285
286 ch = &sband->channels[12]; /* CH 13 */
287 reg_rule = freq_reg_info(wiphy, ch->center_freq);
288 if (!IS_ERR(reg_rule)) {
289 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
290 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
291 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
292 } 395 }
293} 396}
294 397
@@ -320,8 +423,7 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
320 */ 423 */
321 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 424 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
322 ch->flags |= IEEE80211_CHAN_RADAR | 425 ch->flags |= IEEE80211_CHAN_RADAR |
323 IEEE80211_CHAN_NO_IBSS | 426 IEEE80211_CHAN_NO_IR;
324 IEEE80211_CHAN_PASSIVE_SCAN;
325 } 427 }
326} 428}
327 429
@@ -335,12 +437,15 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
335 case 0x66: 437 case 0x66:
336 case 0x67: 438 case 0x67:
337 case 0x6C: 439 case 0x6C:
338 ath_reg_apply_beaconing_flags(wiphy, initiator); 440 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
339 break; 441 break;
340 case 0x68: 442 case 0x68:
341 ath_reg_apply_beaconing_flags(wiphy, initiator); 443 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
342 ath_reg_apply_active_scan_flags(wiphy, initiator); 444 ath_reg_apply_ir_flags(wiphy, reg, initiator);
343 break; 445 break;
446 default:
447 if (ath_reg_dyn_country_user_allow(reg))
448 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
344 } 449 }
345} 450}
346 451
@@ -393,89 +498,6 @@ static void ath_reg_dyn_country(struct wiphy *wiphy,
393 reg_initiator_name(request->initiator)); 498 reg_initiator_name(request->initiator));
394} 499}
395 500
396static bool dynamic_country_user_possible(struct ath_regulatory *reg)
397{
398 if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
399 return true;
400
401 switch (reg->country_code) {
402 case CTRY_UNITED_STATES:
403 case CTRY_JAPAN1:
404 case CTRY_JAPAN2:
405 case CTRY_JAPAN3:
406 case CTRY_JAPAN4:
407 case CTRY_JAPAN5:
408 case CTRY_JAPAN6:
409 case CTRY_JAPAN7:
410 case CTRY_JAPAN8:
411 case CTRY_JAPAN9:
412 case CTRY_JAPAN10:
413 case CTRY_JAPAN11:
414 case CTRY_JAPAN12:
415 case CTRY_JAPAN13:
416 case CTRY_JAPAN14:
417 case CTRY_JAPAN15:
418 case CTRY_JAPAN16:
419 case CTRY_JAPAN17:
420 case CTRY_JAPAN18:
421 case CTRY_JAPAN19:
422 case CTRY_JAPAN20:
423 case CTRY_JAPAN21:
424 case CTRY_JAPAN22:
425 case CTRY_JAPAN23:
426 case CTRY_JAPAN24:
427 case CTRY_JAPAN25:
428 case CTRY_JAPAN26:
429 case CTRY_JAPAN27:
430 case CTRY_JAPAN28:
431 case CTRY_JAPAN29:
432 case CTRY_JAPAN30:
433 case CTRY_JAPAN31:
434 case CTRY_JAPAN32:
435 case CTRY_JAPAN33:
436 case CTRY_JAPAN34:
437 case CTRY_JAPAN35:
438 case CTRY_JAPAN36:
439 case CTRY_JAPAN37:
440 case CTRY_JAPAN38:
441 case CTRY_JAPAN39:
442 case CTRY_JAPAN40:
443 case CTRY_JAPAN41:
444 case CTRY_JAPAN42:
445 case CTRY_JAPAN43:
446 case CTRY_JAPAN44:
447 case CTRY_JAPAN45:
448 case CTRY_JAPAN46:
449 case CTRY_JAPAN47:
450 case CTRY_JAPAN48:
451 case CTRY_JAPAN49:
452 case CTRY_JAPAN50:
453 case CTRY_JAPAN51:
454 case CTRY_JAPAN52:
455 case CTRY_JAPAN53:
456 case CTRY_JAPAN54:
457 case CTRY_JAPAN55:
458 case CTRY_JAPAN56:
459 case CTRY_JAPAN57:
460 case CTRY_JAPAN58:
461 case CTRY_JAPAN59:
462 return false;
463 }
464
465 return true;
466}
467
468static void ath_reg_dyn_country_user(struct wiphy *wiphy,
469 struct ath_regulatory *reg,
470 struct regulatory_request *request)
471{
472 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
473 return;
474 if (!dynamic_country_user_possible(reg))
475 return;
476 ath_reg_dyn_country(wiphy, reg, request);
477}
478
479void ath_reg_notifier_apply(struct wiphy *wiphy, 501void ath_reg_notifier_apply(struct wiphy *wiphy,
480 struct regulatory_request *request, 502 struct regulatory_request *request,
481 struct ath_regulatory *reg) 503 struct ath_regulatory *reg)
@@ -508,7 +530,8 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
508 case NL80211_REGDOM_SET_BY_DRIVER: 530 case NL80211_REGDOM_SET_BY_DRIVER:
509 break; 531 break;
510 case NL80211_REGDOM_SET_BY_USER: 532 case NL80211_REGDOM_SET_BY_USER:
511 ath_reg_dyn_country_user(wiphy, reg, request); 533 if (ath_reg_dyn_country_user_allow(reg))
534 ath_reg_dyn_country(wiphy, reg, request);
512 break; 535 break;
513 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 536 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
514 ath_reg_dyn_country(wiphy, reg, request); 537 ath_reg_dyn_country(wiphy, reg, request);
@@ -609,7 +632,8 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
609 const struct ieee80211_regdomain *regd; 632 const struct ieee80211_regdomain *regd;
610 633
611 wiphy->reg_notifier = reg_notifier; 634 wiphy->reg_notifier = reg_notifier;
612 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 635 wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
636 REGULATORY_CUSTOM_REG;
613 637
614 if (ath_is_world_regd(reg)) { 638 if (ath_is_world_regd(reg)) {
615 /* 639 /*
@@ -617,7 +641,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
617 * saved on the wiphy orig_* parameters 641 * saved on the wiphy orig_* parameters
618 */ 642 */
619 regd = ath_world_regdomain(reg); 643 regd = ath_world_regdomain(reg);
620 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 644 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_FOLLOW_POWER;
621 } else { 645 } else {
622 /* 646 /*
623 * This gets applied in the case of the absence of CRDA, 647 * This gets applied in the case of the absence of CRDA,
@@ -626,6 +650,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
626 */ 650 */
627 regd = ath_default_world_regdomain(); 651 regd = ath_default_world_regdomain();
628 } 652 }
653
629 wiphy_apply_custom_regulatory(wiphy, regd); 654 wiphy_apply_custom_regulatory(wiphy, regd);
630 ath_reg_apply_radar_flags(wiphy); 655 ath_reg_apply_radar_flags(wiphy);
631 ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); 656 ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index c02dbc618724..3c2ef0c32f72 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2644,7 +2644,7 @@ struct wcn36xx_hal_trigger_ba_rsp_candidate {
2644 struct add_ba_info ba_info[STACFG_MAX_TC]; 2644 struct add_ba_info ba_info[STACFG_MAX_TC];
2645} __packed; 2645} __packed;
2646 2646
2647struct wcn36xx_hal_trigget_ba_req_candidate { 2647struct wcn36xx_hal_trigger_ba_req_candidate {
2648 u8 sta_index; 2648 u8 sta_index;
2649 u8 tid_bitmap; 2649 u8 tid_bitmap;
2650} __packed; 2650} __packed;
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 7839b31e4826..e64a6784079e 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -641,7 +641,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
641 dev_kfree_skb(skb); 641 dev_kfree_skb(skb);
642 } 642 }
643 643
644 if (changed & BSS_CHANGED_BEACON_ENABLED) { 644 if (changed & BSS_CHANGED_BEACON_ENABLED ||
645 changed & BSS_CHANGED_BEACON) {
645 wcn36xx_dbg(WCN36XX_DBG_MAC, 646 wcn36xx_dbg(WCN36XX_DBG_MAC,
646 "mac bss changed beacon enabled %d\n", 647 "mac bss changed beacon enabled %d\n",
647 bss_conf->enable_beacon); 648 bss_conf->enable_beacon);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 366339421d4f..750626b0e22d 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -115,6 +115,22 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta,
115 } 115 }
116} 116}
117 117
118static void wcn36xx_smd_set_sta_default_ht_params(
119 struct wcn36xx_hal_config_sta_params *sta_params)
120{
121 sta_params->ht_capable = 1;
122 sta_params->tx_channel_width_set = 1;
123 sta_params->lsig_txop_protection = 1;
124 sta_params->max_ampdu_size = 3;
125 sta_params->max_ampdu_density = 5;
126 sta_params->max_amsdu_size = 0;
127 sta_params->sgi_20Mhz = 1;
128 sta_params->sgi_40mhz = 1;
129 sta_params->green_field_capable = 1;
130 sta_params->delayed_ba_support = 0;
131 sta_params->dsss_cck_mode_40mhz = 1;
132}
133
118static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, 134static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
119 struct ieee80211_vif *vif, 135 struct ieee80211_vif *vif,
120 struct ieee80211_sta *sta, 136 struct ieee80211_sta *sta,
@@ -172,6 +188,7 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
172 sizeof(priv_sta->supported_rates)); 188 sizeof(priv_sta->supported_rates));
173 } else { 189 } else {
174 wcn36xx_set_default_rates(&sta_params->supported_rates); 190 wcn36xx_set_default_rates(&sta_params->supported_rates);
191 wcn36xx_smd_set_sta_default_ht_params(sta_params);
175 } 192 }
176} 193}
177 194
@@ -1134,14 +1151,14 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
1134 /* STA */ 1151 /* STA */
1135 bss->oper_mode = 1; 1152 bss->oper_mode = 1;
1136 bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_MODE; 1153 bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_MODE;
1137 } else if (vif->type == NL80211_IFTYPE_AP) { 1154 } else if (vif->type == NL80211_IFTYPE_AP ||
1155 vif->type == NL80211_IFTYPE_MESH_POINT) {
1138 bss->bss_type = WCN36XX_HAL_INFRA_AP_MODE; 1156 bss->bss_type = WCN36XX_HAL_INFRA_AP_MODE;
1139 1157
1140 /* AP */ 1158 /* AP */
1141 bss->oper_mode = 0; 1159 bss->oper_mode = 0;
1142 bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_SAP_MODE; 1160 bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_SAP_MODE;
1143 } else if (vif->type == NL80211_IFTYPE_ADHOC || 1161 } else if (vif->type == NL80211_IFTYPE_ADHOC) {
1144 vif->type == NL80211_IFTYPE_MESH_POINT) {
1145 bss->bss_type = WCN36XX_HAL_IBSS_MODE; 1162 bss->bss_type = WCN36XX_HAL_IBSS_MODE;
1146 1163
1147 /* STA */ 1164 /* STA */
@@ -1292,7 +1309,11 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif,
1292 memcpy(msg_body.bssid, vif->addr, ETH_ALEN); 1309 memcpy(msg_body.bssid, vif->addr, ETH_ALEN);
1293 1310
1294 /* TODO need to find out why this is needed? */ 1311 /* TODO need to find out why this is needed? */
1295 msg_body.tim_ie_offset = tim_off+4; 1312 if (vif->type == NL80211_IFTYPE_MESH_POINT)
1313 /* mesh beacon don't need this, so push further down */
1314 msg_body.tim_ie_offset = 256;
1315 else
1316 msg_body.tim_ie_offset = tim_off+4;
1296 msg_body.p2p_ie_offset = p2p_off; 1317 msg_body.p2p_ie_offset = p2p_off;
1297 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 1318 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
1298 1319
@@ -1838,7 +1859,7 @@ out:
1838int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) 1859int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
1839{ 1860{
1840 struct wcn36xx_hal_trigger_ba_req_msg msg_body; 1861 struct wcn36xx_hal_trigger_ba_req_msg msg_body;
1841 struct wcn36xx_hal_trigget_ba_req_candidate *candidate; 1862 struct wcn36xx_hal_trigger_ba_req_candidate *candidate;
1842 int ret = 0; 1863 int ret = 0;
1843 1864
1844 mutex_lock(&wcn->hal_mutex); 1865 mutex_lock(&wcn->hal_mutex);
@@ -1849,7 +1870,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
1849 msg_body.header.len += sizeof(*candidate); 1870 msg_body.header.len += sizeof(*candidate);
1850 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 1871 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
1851 1872
1852 candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *) 1873 candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *)
1853 (wcn->hal_buf + sizeof(msg_body)); 1874 (wcn->hal_buf + sizeof(msg_body));
1854 candidate->sta_index = sta_index; 1875 candidate->sta_index = sta_index;
1855 candidate->tid_bitmap = 1; 1876 candidate->tid_bitmap = 1;
@@ -2039,22 +2060,28 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
2039 case WCN36XX_HAL_OTA_TX_COMPL_IND: 2060 case WCN36XX_HAL_OTA_TX_COMPL_IND:
2040 case WCN36XX_HAL_MISSED_BEACON_IND: 2061 case WCN36XX_HAL_MISSED_BEACON_IND:
2041 case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: 2062 case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
2042 mutex_lock(&wcn->hal_ind_mutex);
2043 msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); 2063 msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL);
2044 if (msg_ind) { 2064 if (!msg_ind)
2045 msg_ind->msg_len = len; 2065 goto nomem;
2046 msg_ind->msg = kmalloc(len, GFP_KERNEL); 2066 msg_ind->msg_len = len;
2047 memcpy(msg_ind->msg, buf, len); 2067 msg_ind->msg = kmalloc(len, GFP_KERNEL);
2048 list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); 2068 if (!msg_ind->msg) {
2049 queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); 2069 kfree(msg_ind);
2050 wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); 2070nomem:
2071 /*
2072 * FIXME: Do something smarter then just
2073 * printing an error.
2074 */
2075 wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
2076 msg_header->msg_type);
2077 break;
2051 } 2078 }
2079 memcpy(msg_ind->msg, buf, len);
2080 mutex_lock(&wcn->hal_ind_mutex);
2081 list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
2082 queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
2052 mutex_unlock(&wcn->hal_ind_mutex); 2083 mutex_unlock(&wcn->hal_ind_mutex);
2053 if (msg_ind) 2084 wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
2054 break;
2055 /* FIXME: Do something smarter then just printing an error. */
2056 wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
2057 msg_header->msg_type);
2058 break; 2085 break;
2059 default: 2086 default:
2060 wcn36xx_err("SMD_EVENT (%d) not supported\n", 2087 wcn36xx_err("SMD_EVENT (%d) not supported\n",
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 58b63833e8e7..8fa5cbace5ab 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -54,7 +54,7 @@ enum wcn36xx_debug_mask {
54}; 54};
55 55
56#define wcn36xx_err(fmt, arg...) \ 56#define wcn36xx_err(fmt, arg...) \
57 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg); 57 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg)
58 58
59#define wcn36xx_warn(fmt, arg...) \ 59#define wcn36xx_warn(fmt, arg...) \
60 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) 60 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 8205d3e4ab66..10919f95a83c 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -156,6 +156,19 @@ void wil6210_enable_irq(struct wil6210_priv *wil)
156 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 156 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
157 offsetof(struct RGF_ICR, ICC)); 157 offsetof(struct RGF_ICR, ICC));
158 158
159 /* interrupt moderation parameters */
160 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
161 /* disable interrupt moderation for monitor
162 * to get better timestamp precision
163 */
164 iowrite32(0, wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
165 } else {
166 iowrite32(WIL6210_ITR_TRSH,
167 wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
168 iowrite32(BIT_DMA_ITR_CNT_CRL_EN,
169 wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
170 }
171
159 wil6210_unmask_irq_pseudo(wil); 172 wil6210_unmask_irq_pseudo(wil);
160 wil6210_unmask_irq_tx(wil); 173 wil6210_unmask_irq_tx(wil);
161 wil6210_unmask_irq_rx(wil); 174 wil6210_unmask_irq_rx(wil);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index d505b2676a73..0b0975d88b43 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -21,6 +21,7 @@
21#include <linux/ip.h> 21#include <linux/ip.h>
22#include <linux/ipv6.h> 22#include <linux/ipv6.h>
23#include <net/ipv6.h> 23#include <net/ipv6.h>
24#include <linux/prefetch.h>
24 25
25#include "wil6210.h" 26#include "wil6210.h"
26#include "wmi.h" 27#include "wmi.h"
@@ -377,6 +378,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
377 } 378 }
378 skb_trim(skb, dmalen); 379 skb_trim(skb, dmalen);
379 380
381 prefetch(skb->data);
382
380 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, 383 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
381 skb->data, skb_headlen(skb), false); 384 skb->data, skb_headlen(skb), false);
382 385
@@ -673,9 +676,12 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
673 if (skb->ip_summed != CHECKSUM_PARTIAL) 676 if (skb->ip_summed != CHECKSUM_PARTIAL)
674 return 0; 677 return 0;
675 678
679 d->dma.b11 = ETH_HLEN; /* MAC header length */
680
676 switch (skb->protocol) { 681 switch (skb->protocol) {
677 case cpu_to_be16(ETH_P_IP): 682 case cpu_to_be16(ETH_P_IP):
678 protocol = ip_hdr(skb)->protocol; 683 protocol = ip_hdr(skb)->protocol;
684 d->dma.b11 |= BIT(DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS);
679 break; 685 break;
680 case cpu_to_be16(ETH_P_IPV6): 686 case cpu_to_be16(ETH_P_IPV6):
681 protocol = ipv6_hdr(skb)->nexthdr; 687 protocol = ipv6_hdr(skb)->nexthdr;
@@ -701,8 +707,6 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
701 } 707 }
702 708
703 d->dma.ip_length = skb_network_header_len(skb); 709 d->dma.ip_length = skb_network_header_len(skb);
704 d->dma.b11 = ETH_HLEN; /* MAC header length */
705 d->dma.b11 |= BIT(DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_POS);
706 /* Enable TCP/UDP checksum */ 710 /* Enable TCP/UDP checksum */
707 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS); 711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_TCP_UDP_CHECKSUM_EN_POS);
708 /* Calculate pseudo-header */ 712 /* Calculate pseudo-header */
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index c4a51638736a..1f91eaf95bbe 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -39,6 +39,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
39#define WIL6210_MAX_TX_RINGS (24) /* HW limit */ 39#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
40#define WIL6210_MAX_CID (8) /* HW limit */ 40#define WIL6210_MAX_CID (8) /* HW limit */
41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ 41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
42#define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */
42 43
43/* Hardware definitions begin */ 44/* Hardware definitions begin */
44 45
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 0d950f209dae..bf93ea859f2d 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -28,8 +28,8 @@
28 GNU General Public License for more details. 28 GNU General Public License for more details.
29 29
30 You should have received a copy of the GNU General Public License 30 You should have received a copy of the GNU General Public License
31 along with Atmel wireless lan drivers; if not, write to the Free Software 31 along with Atmel wireless lan drivers; if not, see
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32 <http://www.gnu.org/licenses/>.
33 33
34 For all queries about this code, please contact the current author, 34 For all queries about this code, please contact the current author,
35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation. 35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
@@ -39,7 +39,6 @@
39 39
40******************************************************************************/ 40******************************************************************************/
41 41
42#include <linux/init.h>
43#include <linux/interrupt.h> 42#include <linux/interrupt.h>
44 43
45#include <linux/kernel.h> 44#include <linux/kernel.h>
@@ -4278,8 +4277,7 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4278 GNU General Public License for more details. 4277 GNU General Public License for more details.
4279 4278
4280 You should have received a copy of the GNU General Public License 4279 You should have received a copy of the GNU General Public License
4281 along with AtmelMACFW; if not, write to the Free Software 4280 along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4282 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4283 4281
4284****************************************************************************/ 4282****************************************************************************/
4285/* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */ 4283/* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
diff --git a/drivers/net/wireless/atmel.h b/drivers/net/wireless/atmel.h
index b9b3e5b76544..96f7318cbb04 100644
--- a/drivers/net/wireless/atmel.h
+++ b/drivers/net/wireless/atmel.h
@@ -15,8 +15,8 @@
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with Atmel wireless lan drivers; if not, write to the Free Software 18 along with Atmel wireless lan drivers; if not, see
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 <http://www.gnu.org/licenses/>.
20 20
21******************************************************************************/ 21******************************************************************************/
22 22
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 522572219217..4cfb4d99ced0 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -24,15 +24,14 @@
24 GNU General Public License for more details. 24 GNU General Public License for more details.
25 25
26 You should have received a copy of the GNU General Public License 26 You should have received a copy of the GNU General Public License
27 along with Atmel wireless lan drivers; if not, write to the Free Software 27 along with Atmel wireless lan drivers; if not, see
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 <http://www.gnu.org/licenses/>.
29 29
30******************************************************************************/ 30******************************************************************************/
31 31
32#ifdef __IN_PCMCIA_PACKAGE__ 32#ifdef __IN_PCMCIA_PACKAGE__
33#include <pcmcia/k_compat.h> 33#include <pcmcia/k_compat.h>
34#endif 34#endif
35#include <linux/init.h>
36#include <linux/kernel.h> 35#include <linux/kernel.h>
37#include <linux/module.h> 36#include <linux/module.h>
38#include <linux/ptrace.h> 37#include <linux/ptrace.h>
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index c1b159ebcffe..5cd97e3cbee3 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -15,14 +15,13 @@
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with Atmel wireless lan drivers; if not, write to the Free Software 18 along with Atmel wireless lan drivers; if not, see
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 <http://www.gnu.org/licenses/>.
20 20
21******************************************************************************/ 21******************************************************************************/
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/netdevice.h> 25#include <linux/netdevice.h>
27#include "atmel.h" 26#include "atmel.h"
28 27
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 7f3d461f7e8d..54376fddfaf9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -731,8 +731,6 @@ enum b43_firmware_file_type {
731struct b43_request_fw_context { 731struct b43_request_fw_context {
732 /* The device we are requesting the fw for. */ 732 /* The device we are requesting the fw for. */
733 struct b43_wldev *dev; 733 struct b43_wldev *dev;
734 /* a completion event structure needed if this call is asynchronous */
735 struct completion fw_load_complete;
736 /* a pointer to the firmware object */ 734 /* a pointer to the firmware object */
737 const struct firmware *blob; 735 const struct firmware *blob;
738 /* The type of firmware to request. */ 736 /* The type of firmware to request. */
@@ -809,6 +807,8 @@ enum {
809struct b43_wldev { 807struct b43_wldev {
810 struct b43_bus_dev *dev; 808 struct b43_bus_dev *dev;
811 struct b43_wl *wl; 809 struct b43_wl *wl;
810 /* a completion event structure needed if this call is asynchronous */
811 struct completion fw_load_complete;
812 812
813 /* The device initialization status. 813 /* The device initialization status.
814 * Use b43_status() to query. */ 814 * Use b43_status() to query. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ccd24f0acb8d..c75237eb55a1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2070,6 +2070,7 @@ void b43_do_release_fw(struct b43_firmware_file *fw)
2070 2070
2071static void b43_release_firmware(struct b43_wldev *dev) 2071static void b43_release_firmware(struct b43_wldev *dev)
2072{ 2072{
2073 complete(&dev->fw_load_complete);
2073 b43_do_release_fw(&dev->fw.ucode); 2074 b43_do_release_fw(&dev->fw.ucode);
2074 b43_do_release_fw(&dev->fw.pcm); 2075 b43_do_release_fw(&dev->fw.pcm);
2075 b43_do_release_fw(&dev->fw.initvals); 2076 b43_do_release_fw(&dev->fw.initvals);
@@ -2095,7 +2096,7 @@ static void b43_fw_cb(const struct firmware *firmware, void *context)
2095 struct b43_request_fw_context *ctx = context; 2096 struct b43_request_fw_context *ctx = context;
2096 2097
2097 ctx->blob = firmware; 2098 ctx->blob = firmware;
2098 complete(&ctx->fw_load_complete); 2099 complete(&ctx->dev->fw_load_complete);
2099} 2100}
2100 2101
2101int b43_do_request_fw(struct b43_request_fw_context *ctx, 2102int b43_do_request_fw(struct b43_request_fw_context *ctx,
@@ -2142,7 +2143,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
2142 } 2143 }
2143 if (async) { 2144 if (async) {
2144 /* do this part asynchronously */ 2145 /* do this part asynchronously */
2145 init_completion(&ctx->fw_load_complete); 2146 init_completion(&ctx->dev->fw_load_complete);
2146 err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname, 2147 err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,
2147 ctx->dev->dev->dev, GFP_KERNEL, 2148 ctx->dev->dev->dev, GFP_KERNEL,
2148 ctx, b43_fw_cb); 2149 ctx, b43_fw_cb);
@@ -2150,12 +2151,11 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
2150 pr_err("Unable to load firmware\n"); 2151 pr_err("Unable to load firmware\n");
2151 return err; 2152 return err;
2152 } 2153 }
2153 /* stall here until fw ready */ 2154 wait_for_completion(&ctx->dev->fw_load_complete);
2154 wait_for_completion(&ctx->fw_load_complete);
2155 if (ctx->blob) 2155 if (ctx->blob)
2156 goto fw_ready; 2156 goto fw_ready;
2157 /* On some ARM systems, the async request will fail, but the next sync 2157 /* On some ARM systems, the async request will fail, but the next sync
2158 * request works. For this reason, we dall through here 2158 * request works. For this reason, we fall through here
2159 */ 2159 */
2160 } 2160 }
2161 err = request_firmware(&ctx->blob, ctx->fwname, 2161 err = request_firmware(&ctx->blob, ctx->fwname,
@@ -2424,6 +2424,7 @@ error:
2424 2424
2425static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); 2425static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);
2426static void b43_one_core_detach(struct b43_bus_dev *dev); 2426static void b43_one_core_detach(struct b43_bus_dev *dev);
2427static int b43_rng_init(struct b43_wl *wl);
2427 2428
2428static void b43_request_firmware(struct work_struct *work) 2429static void b43_request_firmware(struct work_struct *work)
2429{ 2430{
@@ -2475,6 +2476,10 @@ start_ieee80211:
2475 goto err_one_core_detach; 2476 goto err_one_core_detach;
2476 wl->hw_registred = true; 2477 wl->hw_registred = true;
2477 b43_leds_register(wl->current_dev); 2478 b43_leds_register(wl->current_dev);
2479
2480 /* Register HW RNG driver */
2481 b43_rng_init(wl);
2482
2478 goto out; 2483 goto out;
2479 2484
2480err_one_core_detach: 2485err_one_core_detach:
@@ -4636,9 +4641,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4636 if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) 4641 if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
4637 return; 4642 return;
4638 4643
4639 /* Unregister HW RNG driver */
4640 b43_rng_exit(dev->wl);
4641
4642 b43_set_status(dev, B43_STAT_UNINIT); 4644 b43_set_status(dev, B43_STAT_UNINIT);
4643 4645
4644 /* Stop the microcode PSM. */ 4646 /* Stop the microcode PSM. */
@@ -4795,9 +4797,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4795 4797
4796 b43_set_status(dev, B43_STAT_INITIALIZED); 4798 b43_set_status(dev, B43_STAT_INITIALIZED);
4797 4799
4798 /* Register HW RNG driver */
4799 b43_rng_init(dev->wl);
4800
4801out: 4800out:
4802 return err; 4801 return err;
4803 4802
@@ -5464,6 +5463,9 @@ static void b43_bcma_remove(struct bcma_device *core)
5464 5463
5465 b43_one_core_detach(wldev->dev); 5464 b43_one_core_detach(wldev->dev);
5466 5465
5466 /* Unregister HW RNG driver */
5467 b43_rng_exit(wl);
5468
5467 b43_leds_unregister(wl); 5469 b43_leds_unregister(wl);
5468 5470
5469 ieee80211_free_hw(wl->hw); 5471 ieee80211_free_hw(wl->hw);
@@ -5541,6 +5543,9 @@ static void b43_ssb_remove(struct ssb_device *sdev)
5541 5543
5542 b43_one_core_detach(dev); 5544 b43_one_core_detach(dev);
5543 5545
5546 /* Unregister HW RNG driver */
5547 b43_rng_exit(wl);
5548
5544 if (list_empty(&wl->devlist)) { 5549 if (list_empty(&wl->devlist)) {
5545 b43_leds_unregister(wl); 5550 b43_leds_unregister(wl);
5546 /* Last core on the chip unregistered. 5551 /* Last core on the chip unregistered.
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 4ae63f4ddfb2..50e5ddb12fb3 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -821,10 +821,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
821 * channel number in b43. */ 821 * channel number in b43. */
822 if (chanstat & B43_RX_CHAN_5GHZ) { 822 if (chanstat & B43_RX_CHAN_5GHZ) {
823 status.band = IEEE80211_BAND_5GHZ; 823 status.band = IEEE80211_BAND_5GHZ;
824 status.freq = b43_freq_to_channel_5ghz(chanid); 824 status.freq = b43_channel_to_freq_5ghz(chanid);
825 } else { 825 } else {
826 status.band = IEEE80211_BAND_2GHZ; 826 status.band = IEEE80211_BAND_2GHZ;
827 status.freq = b43_freq_to_channel_2ghz(chanid); 827 status.freq = b43_channel_to_freq_2ghz(chanid);
828 } 828 }
829 break; 829 break;
830 default: 830 default:
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 572668821862..349c77605231 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3919,6 +3919,7 @@ static void b43legacy_remove(struct ssb_device *dev)
3919 * as the ieee80211 unreg will destroy the workqueue. */ 3919 * as the ieee80211 unreg will destroy the workqueue. */
3920 cancel_work_sync(&wldev->restart_work); 3920 cancel_work_sync(&wldev->restart_work);
3921 cancel_work_sync(&wl->firmware_load); 3921 cancel_work_sync(&wl->firmware_load);
3922 complete(&wldev->fw_load_complete);
3922 3923
3923 B43legacy_WARN_ON(!wl); 3924 B43legacy_WARN_ON(!wl);
3924 if (!wldev->fw.ucode) 3925 if (!wldev->fw.ucode)
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index 54e36fcb3954..fcfed6b99a62 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -4,13 +4,12 @@ config BRCMUTIL
4config BRCMSMAC 4config BRCMSMAC
5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" 5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
6 depends on MAC80211 6 depends on MAC80211
7 depends on BCMA 7 depends on BCMA_POSSIBLE
8 select BCMA
8 select NEW_LEDS if BCMA_DRIVER_GPIO 9 select NEW_LEDS if BCMA_DRIVER_GPIO
9 select LEDS_CLASS if BCMA_DRIVER_GPIO 10 select LEDS_CLASS if BCMA_DRIVER_GPIO
10 select BRCMUTIL 11 select BRCMUTIL
11 select FW_LOADER 12 select FW_LOADER
12 select CRC_CCITT
13 select CRC8
14 select CORDIC 13 select CORDIC
15 ---help--- 14 ---help---
16 This module adds support for PCIe wireless adapters based on Broadcom 15 This module adds support for PCIe wireless adapters based on Broadcom
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 8e9b1221b32c..57cddee03252 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -28,14 +28,15 @@ brcmfmac-objs += \
28 fweh.o \ 28 fweh.o \
29 fwsignal.o \ 29 fwsignal.o \
30 p2p.o \ 30 p2p.o \
31 dhd_cdc.o \ 31 proto.o \
32 bcdc.o \
32 dhd_common.o \ 33 dhd_common.o \
33 dhd_linux.o \ 34 dhd_linux.o \
35 nvram.o \
34 btcoex.o 36 btcoex.o
35brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 37brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
36 dhd_sdio.o \ 38 dhd_sdio.o \
37 bcmsdh.o \ 39 bcmsdh.o \
38 bcmsdh_sdmmc.o \
39 sdio_chip.o 40 sdio_chip.o
40brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 41brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
41 usb.o 42 usb.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
new file mode 100644
index 000000000000..c229210d50ba
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*******************************************************************************
18 * Communicates with the dongle by using dcmd codes.
19 * For certain dcmd codes, the dongle interprets string data from the host.
20 ******************************************************************************/
21
22#include <linux/types.h>
23#include <linux/netdevice.h>
24
25#include <brcmu_utils.h>
26#include <brcmu_wifi.h>
27
28#include "dhd.h"
29#include "dhd_bus.h"
30#include "fwsignal.h"
31#include "dhd_dbg.h"
32#include "tracepoint.h"
33#include "proto.h"
34#include "bcdc.h"
35
36struct brcmf_proto_bcdc_dcmd {
37 __le32 cmd; /* dongle command value */
38 __le32 len; /* lower 16: output buflen;
39 * upper 16: input buflen (excludes header) */
40 __le32 flags; /* flag defns given below */
41 __le32 status; /* status code returned from the device */
42};
43
44/* BCDC flag definitions */
45#define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */
46#define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
47#define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */
48#define BCDC_DCMD_IF_SHIFT 12
49#define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
50#define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
51#define BCDC_DCMD_ID(flags) \
52 (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT)
53
54/*
55 * BCDC header - Broadcom specific extension of CDC.
56 * Used on data packets to convey priority across USB.
57 */
58#define BCDC_HEADER_LEN 4
59#define BCDC_PROTO_VER 2 /* Protocol version */
60#define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
61#define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
62#define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
63#define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
64#define BCDC_PRIORITY_MASK 0x7
65#define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
66#define BCDC_FLAG2_IF_SHIFT 0
67
68#define BCDC_GET_IF_IDX(hdr) \
69 ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT))
70#define BCDC_SET_IF_IDX(hdr, idx) \
71 ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \
72 ((idx) << BCDC_FLAG2_IF_SHIFT)))
73
74/**
75 * struct brcmf_proto_bcdc_header - BCDC header format
76 *
77 * @flags: flags contain protocol and checksum info.
78 * @priority: 802.1d priority and USB flow control info (bit 4:7).
79 * @flags2: additional flags containing dongle interface index.
80 * @data_offset: start of packet data. header is following by firmware signals.
81 */
82struct brcmf_proto_bcdc_header {
83 u8 flags;
84 u8 priority;
85 u8 flags2;
86 u8 data_offset;
87};
88
89/*
90 * maximum length of firmware signal data between
91 * the BCDC header and packet data in the tx path.
92 */
93#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
94
95#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
96#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
97 * (amount of header tha might be added)
98 * plus any space that might be needed
99 * for bus alignment padding.
100 */
101struct brcmf_bcdc {
102 u16 reqid;
103 u8 bus_header[BUS_HEADER_LEN];
104 struct brcmf_proto_bcdc_dcmd msg;
105 unsigned char buf[BRCMF_DCMD_MAXLEN];
106};
107
108
109static int
110brcmf_proto_bcdc_msg(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
111 uint len, bool set)
112{
113 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
114 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
115 u32 flags;
116
117 brcmf_dbg(BCDC, "Enter\n");
118
119 memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
120
121 msg->cmd = cpu_to_le32(cmd);
122 msg->len = cpu_to_le32(len);
123 flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT);
124 if (set)
125 flags |= BCDC_DCMD_SET;
126 flags = (flags & ~BCDC_DCMD_IF_MASK) |
127 (ifidx << BCDC_DCMD_IF_SHIFT);
128 msg->flags = cpu_to_le32(flags);
129
130 if (buf)
131 memcpy(bcdc->buf, buf, len);
132
133 len += sizeof(*msg);
134 if (len > BRCMF_TX_IOCTL_MAX_MSG_SIZE)
135 len = BRCMF_TX_IOCTL_MAX_MSG_SIZE;
136
137 /* Send request */
138 return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len);
139}
140
141static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
142{
143 int ret;
144 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
145
146 brcmf_dbg(BCDC, "Enter\n");
147 len += sizeof(struct brcmf_proto_bcdc_dcmd);
148 do {
149 ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg,
150 len);
151 if (ret < 0)
152 break;
153 } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id);
154
155 return ret;
156}
157
158static int
159brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
160 void *buf, uint len)
161{
162 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
163 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
164 void *info;
165 int ret = 0, retries = 0;
166 u32 id, flags;
167
168 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
169
170 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
171 if (ret < 0) {
172 brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
173 ret);
174 goto done;
175 }
176
177retry:
178 /* wait for interrupt and get first fragment */
179 ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
180 if (ret < 0)
181 goto done;
182
183 flags = le32_to_cpu(msg->flags);
184 id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
185
186 if ((id < bcdc->reqid) && (++retries < RETRIES))
187 goto retry;
188 if (id != bcdc->reqid) {
189 brcmf_err("%s: unexpected request id %d (expected %d)\n",
190 brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
191 ret = -EINVAL;
192 goto done;
193 }
194
195 /* Check info buffer */
196 info = (void *)&msg[1];
197
198 /* Copy info buffer */
199 if (buf) {
200 if (ret < (int)len)
201 len = ret;
202 memcpy(buf, info, len);
203 }
204
205 /* Check the ERROR flag */
206 if (flags & BCDC_DCMD_ERROR)
207 ret = le32_to_cpu(msg->status);
208
209done:
210 return ret;
211}
212
213static int
214brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
215 void *buf, uint len)
216{
217 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
218 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
219 int ret = 0;
220 u32 flags, id;
221
222 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
223
224 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
225 if (ret < 0)
226 goto done;
227
228 ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
229 if (ret < 0)
230 goto done;
231
232 flags = le32_to_cpu(msg->flags);
233 id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
234
235 if (id != bcdc->reqid) {
236 brcmf_err("%s: unexpected request id %d (expected %d)\n",
237 brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
238 ret = -EINVAL;
239 goto done;
240 }
241
242 /* Check the ERROR flag */
243 if (flags & BCDC_DCMD_ERROR)
244 ret = le32_to_cpu(msg->status);
245
246done:
247 return ret;
248}
249
250static void
251brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
252 struct sk_buff *pktbuf)
253{
254 struct brcmf_proto_bcdc_header *h;
255
256 brcmf_dbg(BCDC, "Enter\n");
257
258 /* Push BDC header used to convey priority for buses that don't */
259 skb_push(pktbuf, BCDC_HEADER_LEN);
260
261 h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
262
263 h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT);
264 if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
265 h->flags |= BCDC_FLAG_SUM_NEEDED;
266
267 h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
268 h->flags2 = 0;
269 h->data_offset = offset;
270 BCDC_SET_IF_IDX(h, ifidx);
271 trace_brcmf_bcdchdr(pktbuf->data);
272}
273
274static int
275brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
276 struct sk_buff *pktbuf)
277{
278 struct brcmf_proto_bcdc_header *h;
279
280 brcmf_dbg(BCDC, "Enter\n");
281
282 /* Pop BCDC header used to convey priority for buses that don't */
283 if (pktbuf->len <= BCDC_HEADER_LEN) {
284 brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
285 pktbuf->len, BCDC_HEADER_LEN);
286 return -EBADE;
287 }
288
289 trace_brcmf_bcdchdr(pktbuf->data);
290 h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
291
292 *ifidx = BCDC_GET_IF_IDX(h);
293 if (*ifidx >= BRCMF_MAX_IFS) {
294 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
295 return -EBADE;
296 }
297 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
298 * events this is easy because it contains the bssidx which maps
299 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
300 * bssidx 1 is used for p2p0 and no data can be received or
301 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
302 */
303 if (*ifidx)
304 (*ifidx)++;
305
306 if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
307 BCDC_PROTO_VER) {
308 brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
309 brcmf_ifname(drvr, *ifidx), h->flags);
310 return -EBADE;
311 }
312
313 if (h->flags & BCDC_FLAG_SUM_GOOD) {
314 brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
315 brcmf_ifname(drvr, *ifidx), h->flags);
316 pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
317 }
318
319 pktbuf->priority = h->priority & BCDC_PRIORITY_MASK;
320
321 skb_pull(pktbuf, BCDC_HEADER_LEN);
322 if (do_fws)
323 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
324 else
325 skb_pull(pktbuf, h->data_offset << 2);
326
327 if (pktbuf->len == 0)
328 return -ENODATA;
329 return 0;
330}
331
332static int
333brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
334 struct sk_buff *pktbuf)
335{
336 brcmf_proto_bcdc_hdrpush(drvr, ifidx, offset, pktbuf);
337 return brcmf_bus_txdata(drvr->bus_if, pktbuf);
338}
339
340
341int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
342{
343 struct brcmf_bcdc *bcdc;
344
345 bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC);
346 if (!bcdc)
347 goto fail;
348
349 /* ensure that the msg buf directly follows the cdc msg struct */
350 if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
351 brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n");
352 goto fail;
353 }
354
355 drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
356 drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
357 drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
358 drvr->proto->txdata = brcmf_proto_bcdc_txdata;
359 drvr->proto->pd = bcdc;
360
361 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
362 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
363 sizeof(struct brcmf_proto_bcdc_dcmd);
364 return 0;
365
366fail:
367 kfree(bcdc);
368 return -ENOMEM;
369}
370
371void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
372{
373 kfree(drvr->proto->pd);
374 drvr->proto->pd = NULL;
375}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
new file mode 100644
index 000000000000..17e8c039ff32
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef BRCMFMAC_BCDC_H
17#define BRCMFMAC_BCDC_H
18
19
20int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
21void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
22
23
24#endif /* BRCMFMAC_BCDC_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3e10b801eee8..fa35b23bbaa7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -17,16 +17,23 @@
17 17
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/export.h>
21#include <linux/pci.h> 20#include <linux/pci.h>
22#include <linux/pci_ids.h> 21#include <linux/pci_ids.h>
23#include <linux/sched.h> 22#include <linux/sched.h>
24#include <linux/completion.h> 23#include <linux/completion.h>
25#include <linux/scatterlist.h> 24#include <linux/scatterlist.h>
26#include <linux/mmc/sdio.h> 25#include <linux/mmc/sdio.h>
26#include <linux/mmc/core.h>
27#include <linux/mmc/sdio_func.h> 27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/sdio_ids.h>
28#include <linux/mmc/card.h> 29#include <linux/mmc/card.h>
30#include <linux/mmc/host.h>
31#include <linux/platform_device.h>
29#include <linux/platform_data/brcmfmac-sdio.h> 32#include <linux/platform_data/brcmfmac-sdio.h>
33#include <linux/suspend.h>
34#include <linux/errno.h>
35#include <linux/module.h>
36#include <net/cfg80211.h>
30 37
31#include <defs.h> 38#include <defs.h>
32#include <brcm_hw_ids.h> 39#include <brcm_hw_ids.h>
@@ -36,11 +43,19 @@
36#include "dhd_bus.h" 43#include "dhd_bus.h"
37#include "dhd_dbg.h" 44#include "dhd_dbg.h"
38#include "sdio_host.h" 45#include "sdio_host.h"
46#include "sdio_chip.h"
39 47
40#define SDIOH_API_ACCESS_RETRY_LIMIT 2 48#define SDIOH_API_ACCESS_RETRY_LIMIT 2
41 49
50#define DMA_ALIGN_MASK 0x03
42 51
43static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) 52#define SDIO_FUNC1_BLOCKSIZE 64
53#define SDIO_FUNC2_BLOCKSIZE 512
54/* Maximum milliseconds to wait for F2 to come up */
55#define SDIO_WAIT_F2RDY 3000
56
57
58static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
44{ 59{
45 struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); 60 struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
46 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 61 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
@@ -55,27 +70,46 @@ static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id)
55 sdiodev->irq_en = false; 70 sdiodev->irq_en = false;
56 } 71 }
57 72
58 brcmf_sdbrcm_isr(sdiodev->bus); 73 brcmf_sdio_isr(sdiodev->bus);
59 74
60 return IRQ_HANDLED; 75 return IRQ_HANDLED;
61} 76}
62 77
63static void brcmf_sdio_ib_irqhandler(struct sdio_func *func) 78static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func)
64{ 79{
65 struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); 80 struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev);
66 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 81 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
67 82
68 brcmf_dbg(INTR, "IB intr triggered\n"); 83 brcmf_dbg(INTR, "IB intr triggered\n");
69 84
70 brcmf_sdbrcm_isr(sdiodev->bus); 85 brcmf_sdio_isr(sdiodev->bus);
71} 86}
72 87
73/* dummy handler for SDIO function 2 interrupt */ 88/* dummy handler for SDIO function 2 interrupt */
74static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) 89static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)
75{ 90{
76} 91}
77 92
78int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) 93static bool brcmf_sdiod_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
94{
95 bool is_err = false;
96#ifdef CONFIG_PM_SLEEP
97 is_err = atomic_read(&sdiodev->suspend);
98#endif
99 return is_err;
100}
101
102static void brcmf_sdiod_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
103 wait_queue_head_t *wq)
104{
105#ifdef CONFIG_PM_SLEEP
106 int retry = 0;
107 while (atomic_read(&sdiodev->suspend) && retry++ != 30)
108 wait_event_timeout(*wq, false, HZ/100);
109#endif
110}
111
112int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
79{ 113{
80 int ret = 0; 114 int ret = 0;
81 u8 data; 115 u8 data;
@@ -85,7 +119,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
85 brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", 119 brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
86 sdiodev->pdata->oob_irq_nr); 120 sdiodev->pdata->oob_irq_nr);
87 ret = request_irq(sdiodev->pdata->oob_irq_nr, 121 ret = request_irq(sdiodev->pdata->oob_irq_nr,
88 brcmf_sdio_oob_irqhandler, 122 brcmf_sdiod_oob_irqhandler,
89 sdiodev->pdata->oob_irq_flags, 123 sdiodev->pdata->oob_irq_flags,
90 "brcmf_oob_intr", 124 "brcmf_oob_intr",
91 &sdiodev->func[1]->dev); 125 &sdiodev->func[1]->dev);
@@ -109,36 +143,36 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
109 sdio_claim_host(sdiodev->func[1]); 143 sdio_claim_host(sdiodev->func[1]);
110 144
111 /* must configure SDIO_CCCR_IENx to enable irq */ 145 /* must configure SDIO_CCCR_IENx to enable irq */
112 data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); 146 data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
113 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; 147 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
114 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); 148 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
115 149
116 /* redirect, configure and enable io for interrupt signal */ 150 /* redirect, configure and enable io for interrupt signal */
117 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; 151 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
118 if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) 152 if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
119 data |= SDIO_SEPINT_ACT_HI; 153 data |= SDIO_SEPINT_ACT_HI;
120 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); 154 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
121 155
122 sdio_release_host(sdiodev->func[1]); 156 sdio_release_host(sdiodev->func[1]);
123 } else { 157 } else {
124 brcmf_dbg(SDIO, "Entering\n"); 158 brcmf_dbg(SDIO, "Entering\n");
125 sdio_claim_host(sdiodev->func[1]); 159 sdio_claim_host(sdiodev->func[1]);
126 sdio_claim_irq(sdiodev->func[1], brcmf_sdio_ib_irqhandler); 160 sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
127 sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); 161 sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
128 sdio_release_host(sdiodev->func[1]); 162 sdio_release_host(sdiodev->func[1]);
129 } 163 }
130 164
131 return 0; 165 return 0;
132} 166}
133 167
134int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) 168int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
135{ 169{
136 brcmf_dbg(SDIO, "Entering\n"); 170 brcmf_dbg(SDIO, "Entering\n");
137 171
138 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { 172 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
139 sdio_claim_host(sdiodev->func[1]); 173 sdio_claim_host(sdiodev->func[1]);
140 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); 174 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
141 brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); 175 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
142 sdio_release_host(sdiodev->func[1]); 176 sdio_release_host(sdiodev->func[1]);
143 177
144 if (sdiodev->oob_irq_requested) { 178 if (sdiodev->oob_irq_requested) {
@@ -161,29 +195,150 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
161 return 0; 195 return 0;
162} 196}
163 197
198static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
199 uint regaddr, u8 byte)
200{
201 int err_ret;
202
203 /*
204 * Can only directly write to some F0 registers.
205 * Handle CCCR_IENx and CCCR_ABORT command
206 * as a special case.
207 */
208 if ((regaddr == SDIO_CCCR_ABORT) ||
209 (regaddr == SDIO_CCCR_IENx))
210 sdio_writeb(func, byte, regaddr, &err_ret);
211 else
212 sdio_f0_writeb(func, byte, regaddr, &err_ret);
213
214 return err_ret;
215}
216
217static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
218 u32 addr, u8 regsz, void *data, bool write)
219{
220 struct sdio_func *func;
221 int ret;
222
223 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
224 write, fn, addr, regsz);
225
226 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
227 if (brcmf_sdiod_pm_resume_error(sdiodev))
228 return -EIO;
229
230 /* only allow byte access on F0 */
231 if (WARN_ON(regsz > 1 && !fn))
232 return -EINVAL;
233 func = sdiodev->func[fn];
234
235 switch (regsz) {
236 case sizeof(u8):
237 if (write) {
238 if (fn)
239 sdio_writeb(func, *(u8 *)data, addr, &ret);
240 else
241 ret = brcmf_sdiod_f0_writeb(func, addr,
242 *(u8 *)data);
243 } else {
244 if (fn)
245 *(u8 *)data = sdio_readb(func, addr, &ret);
246 else
247 *(u8 *)data = sdio_f0_readb(func, addr, &ret);
248 }
249 break;
250 case sizeof(u16):
251 if (write)
252 sdio_writew(func, *(u16 *)data, addr, &ret);
253 else
254 *(u16 *)data = sdio_readw(func, addr, &ret);
255 break;
256 case sizeof(u32):
257 if (write)
258 sdio_writel(func, *(u32 *)data, addr, &ret);
259 else
260 *(u32 *)data = sdio_readl(func, addr, &ret);
261 break;
262 default:
263 brcmf_err("invalid size: %d\n", regsz);
264 break;
265 }
266
267 if (ret) {
268 /*
269 * SleepCSR register access can fail when
270 * waking up the device so reduce this noise
271 * in the logs.
272 */
273 if (addr != SBSDIO_FUNC1_SLEEPCSR)
274 brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
275 write ? "write" : "read", fn, addr, ret);
276 else
277 brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
278 write ? "write" : "read", fn, addr, ret);
279 }
280 return ret;
281}
282
283static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
284 u8 regsz, void *data, bool write)
285{
286 u8 func_num;
287 s32 retry = 0;
288 int ret;
289
290 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
291 return -ENOMEDIUM;
292
293 /*
294 * figure out how to read the register based on address range
295 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
296 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
297 * The rest: function 1 silicon backplane core registers
298 */
299 if ((addr & ~REG_F0_REG_MASK) == 0)
300 func_num = SDIO_FUNC_0;
301 else
302 func_num = SDIO_FUNC_1;
303
304 do {
305 if (!write)
306 memset(data, 0, regsz);
307 /* for retry wait for 1 ms till bus get settled down */
308 if (retry)
309 usleep_range(1000, 2000);
310 ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz,
311 data, write);
312 } while (ret != 0 && ret != -ENOMEDIUM &&
313 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
314
315 if (ret == -ENOMEDIUM)
316 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
317 else if (ret != 0)
318 brcmf_err("failed with %d\n", ret);
319
320 return ret;
321}
322
164static int 323static int
165brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) 324brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
166{ 325{
167 int err = 0, i; 326 int err = 0, i;
168 u8 addr[3]; 327 u8 addr[3];
169 s32 retry; 328
329 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM)
330 return -ENOMEDIUM;
170 331
171 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 332 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
172 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; 333 addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
173 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; 334 addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
174 335
175 for (i = 0; i < 3; i++) { 336 for (i = 0; i < 3; i++) {
176 retry = 0; 337 err = brcmf_sdiod_regrw_helper(sdiodev,
177 do { 338 SBSDIO_FUNC1_SBADDRLOW + i,
178 if (retry) 339 sizeof(u8), &addr[i], true);
179 usleep_range(1000, 2000);
180 err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
181 SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
182 &addr[i]);
183 } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
184
185 if (err) { 340 if (err) {
186 brcmf_err("failed at addr:0x%0x\n", 341 brcmf_err("failed at addr: 0x%0x\n",
187 SBSDIO_FUNC1_SBADDRLOW + i); 342 SBSDIO_FUNC1_SBADDRLOW + i);
188 break; 343 break;
189 } 344 }
@@ -193,13 +348,13 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
193} 348}
194 349
195static int 350static int
196brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) 351brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
197{ 352{
198 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; 353 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
199 int err = 0; 354 int err = 0;
200 355
201 if (bar0 != sdiodev->sbwad) { 356 if (bar0 != sdiodev->sbwad) {
202 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 357 err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
203 if (err) 358 if (err)
204 return err; 359 return err;
205 360
@@ -214,62 +369,14 @@ brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
214 return 0; 369 return 0;
215} 370}
216 371
217int 372u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
218brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
219 void *data, bool write)
220{
221 u8 func_num, reg_size;
222 s32 retry = 0;
223 int ret;
224
225 /*
226 * figure out how to read the register based on address range
227 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
228 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
229 * The rest: function 1 silicon backplane core registers
230 */
231 if ((addr & ~REG_F0_REG_MASK) == 0) {
232 func_num = SDIO_FUNC_0;
233 reg_size = 1;
234 } else if ((addr & ~REG_F1_MISC_MASK) == 0) {
235 func_num = SDIO_FUNC_1;
236 reg_size = 1;
237 } else {
238 func_num = SDIO_FUNC_1;
239 reg_size = 4;
240
241 ret = brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
242 if (ret)
243 goto done;
244 }
245
246 do {
247 if (!write)
248 memset(data, 0, reg_size);
249 if (retry) /* wait for 1 ms till bus get settled down */
250 usleep_range(1000, 2000);
251 if (reg_size == 1)
252 ret = brcmf_sdioh_request_byte(sdiodev, write,
253 func_num, addr, data);
254 else
255 ret = brcmf_sdioh_request_word(sdiodev, write,
256 func_num, addr, data, 4);
257 } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
258
259done:
260 if (ret != 0)
261 brcmf_err("failed with %d\n", ret);
262
263 return ret;
264}
265
266u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
267{ 373{
268 u8 data; 374 u8 data;
269 int retval; 375 int retval;
270 376
271 brcmf_dbg(SDIO, "addr:0x%08x\n", addr); 377 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
272 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 378 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
379 false);
273 brcmf_dbg(SDIO, "data:0x%02x\n", data); 380 brcmf_dbg(SDIO, "data:0x%02x\n", data);
274 381
275 if (ret) 382 if (ret)
@@ -278,52 +385,63 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
278 return data; 385 return data;
279} 386}
280 387
281u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) 388u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
282{ 389{
283 u32 data; 390 u32 data;
284 int retval; 391 int retval;
285 392
286 brcmf_dbg(SDIO, "addr:0x%08x\n", addr); 393 brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 394 retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
395 if (retval)
396 goto done;
397 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
398 false);
288 brcmf_dbg(SDIO, "data:0x%08x\n", data); 399 brcmf_dbg(SDIO, "data:0x%08x\n", data);
289 400
401done:
290 if (ret) 402 if (ret)
291 *ret = retval; 403 *ret = retval;
292 404
293 return data; 405 return data;
294} 406}
295 407
296void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, 408void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
297 u8 data, int *ret) 409 u8 data, int *ret)
298{ 410{
299 int retval; 411 int retval;
300 412
301 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); 413 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
302 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 414 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
303 415 true);
304 if (ret) 416 if (ret)
305 *ret = retval; 417 *ret = retval;
306} 418}
307 419
308void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, 420void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
309 u32 data, int *ret) 421 u32 data, int *ret)
310{ 422{
311 int retval; 423 int retval;
312 424
313 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); 425 brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
314 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 426 retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr);
427 if (retval)
428 goto done;
429 retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
430 true);
315 431
432done:
316 if (ret) 433 if (ret)
317 *ret = retval; 434 *ret = retval;
318} 435}
319 436
320static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, 437static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
321 bool write, u32 addr, struct sk_buff *pkt) 438 bool write, u32 addr, struct sk_buff *pkt)
322{ 439{
323 unsigned int req_sz; 440 unsigned int req_sz;
441 int err;
324 442
325 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); 443 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
326 if (brcmf_pm_resume_error(sdiodev)) 444 if (brcmf_sdiod_pm_resume_error(sdiodev))
327 return -EIO; 445 return -EIO;
328 446
329 /* Single skb use the standard mmc interface */ 447 /* Single skb use the standard mmc interface */
@@ -331,22 +449,22 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
331 req_sz &= (uint)~3; 449 req_sz &= (uint)~3;
332 450
333 if (write) 451 if (write)
334 return sdio_memcpy_toio(sdiodev->func[fn], addr, 452 err = sdio_memcpy_toio(sdiodev->func[fn], addr,
335 ((u8 *)(pkt->data)), 453 ((u8 *)(pkt->data)), req_sz);
336 req_sz);
337 else if (fn == 1) 454 else if (fn == 1)
338 return sdio_memcpy_fromio(sdiodev->func[fn], 455 err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
339 ((u8 *)(pkt->data)), 456 addr, req_sz);
340 addr, req_sz);
341 else 457 else
342 /* function 2 read is FIFO operation */ 458 /* function 2 read is FIFO operation */
343 return sdio_readsb(sdiodev->func[fn], 459 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
344 ((u8 *)(pkt->data)), addr, 460 req_sz);
345 req_sz); 461 if (err == -ENOMEDIUM)
462 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
463 return err;
346} 464}
347 465
348/** 466/**
349 * brcmf_sdio_sglist_rw - SDIO interface function for block data access 467 * brcmf_sdiod_sglist_rw - SDIO interface function for block data access
350 * @sdiodev: brcmfmac sdio device 468 * @sdiodev: brcmfmac sdio device
351 * @fn: SDIO function number 469 * @fn: SDIO function number
352 * @write: direction flag 470 * @write: direction flag
@@ -357,9 +475,9 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
357 * stack for block data access. It assumes that the skb passed down by the 475 * stack for block data access. It assumes that the skb passed down by the
358 * caller has already been padded and aligned. 476 * caller has already been padded and aligned.
359 */ 477 */
360static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, 478static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
361 bool write, u32 addr, 479 bool write, u32 addr,
362 struct sk_buff_head *pktlist) 480 struct sk_buff_head *pktlist)
363{ 481{
364 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; 482 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
365 unsigned int max_req_sz, orig_offset, dst_offset; 483 unsigned int max_req_sz, orig_offset, dst_offset;
@@ -377,8 +495,8 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
377 if (!pktlist->qlen) 495 if (!pktlist->qlen)
378 return -EINVAL; 496 return -EINVAL;
379 497
380 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); 498 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
381 if (brcmf_pm_resume_error(sdiodev)) 499 if (brcmf_sdiod_pm_resume_error(sdiodev))
382 return -EIO; 500 return -EIO;
383 501
384 target_list = pktlist; 502 target_list = pktlist;
@@ -485,7 +603,11 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
485 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); 603 mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
486 604
487 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 605 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
488 if (ret != 0) { 606 if (ret == -ENOMEDIUM) {
607 brcmf_bus_change_state(sdiodev->bus_if,
608 BRCMF_BUS_NOMEDIUM);
609 break;
610 } else if (ret != 0) {
489 brcmf_err("CMD53 sg block %s failed %d\n", 611 brcmf_err("CMD53 sg block %s failed %d\n",
490 write ? "write" : "read", ret); 612 write ? "write" : "read", ret);
491 ret = -EIO; 613 ret = -EIO;
@@ -525,9 +647,7 @@ exit:
525 return ret; 647 return ret;
526} 648}
527 649
528int 650int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
529brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
530 uint flags, u8 *buf, uint nbytes)
531{ 651{
532 struct sk_buff *mypkt; 652 struct sk_buff *mypkt;
533 int err; 653 int err;
@@ -539,7 +659,7 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
539 return -EIO; 659 return -EIO;
540 } 660 }
541 661
542 err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt); 662 err = brcmf_sdiod_recv_pkt(sdiodev, mypkt);
543 if (!err) 663 if (!err)
544 memcpy(buf, mypkt->data, nbytes); 664 memcpy(buf, mypkt->data, nbytes);
545 665
@@ -547,50 +667,47 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
547 return err; 667 return err;
548} 668}
549 669
550int 670int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
551brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
552 uint flags, struct sk_buff *pkt)
553{ 671{
554 uint width; 672 u32 addr = sdiodev->sbwad;
555 int err = 0; 673 int err = 0;
556 674
557 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", 675 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
558 fn, addr, pkt->len);
559 676
560 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 677 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
561 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
562 if (err) 678 if (err)
563 goto done; 679 goto done;
564 680
565 err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt); 681 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt);
566 682
567done: 683done:
568 return err; 684 return err;
569} 685}
570 686
571int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 687int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
572 uint flags, struct sk_buff_head *pktq, uint totlen) 688 struct sk_buff_head *pktq, uint totlen)
573{ 689{
574 struct sk_buff *glom_skb; 690 struct sk_buff *glom_skb;
575 struct sk_buff *skb; 691 struct sk_buff *skb;
576 uint width; 692 u32 addr = sdiodev->sbwad;
577 int err = 0; 693 int err = 0;
578 694
579 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", 695 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
580 fn, addr, pktq->qlen); 696 addr, pktq->qlen);
581 697
582 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 698 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
583 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
584 if (err) 699 if (err)
585 goto done; 700 goto done;
586 701
587 if (pktq->qlen == 1) 702 if (pktq->qlen == 1)
588 err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq->next); 703 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
704 pktq->next);
589 else if (!sdiodev->sg_support) { 705 else if (!sdiodev->sg_support) {
590 glom_skb = brcmu_pkt_buf_get_skb(totlen); 706 glom_skb = brcmu_pkt_buf_get_skb(totlen);
591 if (!glom_skb) 707 if (!glom_skb)
592 return -ENOMEM; 708 return -ENOMEM;
593 err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, glom_skb); 709 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
710 glom_skb);
594 if (err) 711 if (err)
595 goto done; 712 goto done;
596 713
@@ -599,18 +716,17 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
599 skb_pull(glom_skb, skb->len); 716 skb_pull(glom_skb, skb->len);
600 } 717 }
601 } else 718 } else
602 err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, pktq); 719 err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,
720 pktq);
603 721
604done: 722done:
605 return err; 723 return err;
606} 724}
607 725
608int 726int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
609brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
610 uint flags, u8 *buf, uint nbytes)
611{ 727{
612 struct sk_buff *mypkt; 728 struct sk_buff *mypkt;
613 uint width; 729 u32 addr = sdiodev->sbwad;
614 int err; 730 int err;
615 731
616 mypkt = brcmu_pkt_buf_get_skb(nbytes); 732 mypkt = brcmu_pkt_buf_get_skb(nbytes);
@@ -622,48 +738,47 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
622 738
623 memcpy(mypkt->data, buf, nbytes); 739 memcpy(mypkt->data, buf, nbytes);
624 740
625 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 741 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
626 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
627 742
628 if (!err) 743 if (!err)
629 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt); 744 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
745 mypkt);
630 746
631 brcmu_pkt_buf_free_skb(mypkt); 747 brcmu_pkt_buf_free_skb(mypkt);
632 return err; 748 return err;
633 749
634} 750}
635 751
636int 752int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
637brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 753 struct sk_buff_head *pktq)
638 uint flags, struct sk_buff_head *pktq)
639{ 754{
640 struct sk_buff *skb; 755 struct sk_buff *skb;
641 uint width; 756 u32 addr = sdiodev->sbwad;
642 int err; 757 int err;
643 758
644 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", 759 brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
645 fn, addr, pktq->qlen);
646 760
647 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 761 err = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
648 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
649 if (err) 762 if (err)
650 return err; 763 return err;
651 764
652 if (pktq->qlen == 1 || !sdiodev->sg_support) 765 if (pktq->qlen == 1 || !sdiodev->sg_support)
653 skb_queue_walk(pktq, skb) { 766 skb_queue_walk(pktq, skb) {
654 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, skb); 767 err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true,
768 addr, skb);
655 if (err) 769 if (err)
656 break; 770 break;
657 } 771 }
658 else 772 else
659 err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq); 773 err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
774 pktq);
660 775
661 return err; 776 return err;
662} 777}
663 778
664int 779int
665brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, 780brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
666 u8 *data, uint size) 781 u8 *data, uint size)
667{ 782{
668 int bcmerror = 0; 783 int bcmerror = 0;
669 struct sk_buff *pkt; 784 struct sk_buff *pkt;
@@ -690,7 +805,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
690 /* Do the transfer(s) */ 805 /* Do the transfer(s) */
691 while (size) { 806 while (size) {
692 /* Set the backplane window to include the start address */ 807 /* Set the backplane window to include the start address */
693 bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address); 808 bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
694 if (bcmerror) 809 if (bcmerror)
695 break; 810 break;
696 811
@@ -704,8 +819,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
704 skb_put(pkt, dsize); 819 skb_put(pkt, dsize);
705 if (write) 820 if (write)
706 memcpy(pkt->data, data, dsize); 821 memcpy(pkt->data, data, dsize);
707 bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write, 822 bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
708 sdaddr, pkt); 823 sdaddr, pkt);
709 if (bcmerror) { 824 if (bcmerror) {
710 brcmf_err("membytes transfer failed\n"); 825 brcmf_err("membytes transfer failed\n");
711 break; 826 break;
@@ -727,7 +842,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
727 dev_kfree_skb(pkt); 842 dev_kfree_skb(pkt);
728 843
729 /* Return the window to backplane enumeration space for core access */ 844 /* Return the window to backplane enumeration space for core access */
730 if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad)) 845 if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad))
731 brcmf_err("FAILED to set window back to 0x%x\n", 846 brcmf_err("FAILED to set window back to 0x%x\n",
732 sdiodev->sbwad); 847 sdiodev->sbwad);
733 848
@@ -736,67 +851,335 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
736 return bcmerror; 851 return bcmerror;
737} 852}
738 853
739int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) 854int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
740{ 855{
741 char t_func = (char)fn; 856 char t_func = (char)fn;
742 brcmf_dbg(SDIO, "Enter\n"); 857 brcmf_dbg(SDIO, "Enter\n");
743 858
744 /* issue abort cmd52 command through F0 */ 859 /* issue abort cmd52 command through F0 */
745 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, 860 brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
746 SDIO_CCCR_ABORT, &t_func); 861 sizeof(t_func), &t_func, true);
747 862
748 brcmf_dbg(SDIO, "Exit\n"); 863 brcmf_dbg(SDIO, "Exit\n");
749 return 0; 864 return 0;
750} 865}
751 866
752int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) 867static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
753{ 868{
754 u32 regs = 0; 869 if (sdiodev->bus) {
870 brcmf_sdio_remove(sdiodev->bus);
871 sdiodev->bus = NULL;
872 }
873
874 /* Disable Function 2 */
875 sdio_claim_host(sdiodev->func[2]);
876 sdio_disable_func(sdiodev->func[2]);
877 sdio_release_host(sdiodev->func[2]);
878
879 /* Disable Function 1 */
880 sdio_claim_host(sdiodev->func[1]);
881 sdio_disable_func(sdiodev->func[1]);
882 sdio_release_host(sdiodev->func[1]);
883
884 sdiodev->sbwad = 0;
885
886 return 0;
887}
888
889static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
890{
891 struct sdio_func *func;
892 struct mmc_host *host;
893 uint max_blocks;
755 int ret = 0; 894 int ret = 0;
756 895
757 ret = brcmf_sdioh_attach(sdiodev); 896 sdiodev->num_funcs = 2;
758 if (ret) 897
898 sdio_claim_host(sdiodev->func[1]);
899
900 ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
901 if (ret) {
902 brcmf_err("Failed to set F1 blocksize\n");
903 sdio_release_host(sdiodev->func[1]);
904 goto out;
905 }
906 ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
907 if (ret) {
908 brcmf_err("Failed to set F2 blocksize\n");
909 sdio_release_host(sdiodev->func[1]);
910 goto out;
911 }
912
913 /* increase F2 timeout */
914 sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY;
915
916 /* Enable Function 1 */
917 ret = sdio_enable_func(sdiodev->func[1]);
918 sdio_release_host(sdiodev->func[1]);
919 if (ret) {
920 brcmf_err("Failed to enable F1: err=%d\n", ret);
759 goto out; 921 goto out;
922 }
760 923
761 regs = SI_ENUM_BASE; 924 /*
925 * determine host related variables after brcmf_sdiod_probe()
926 * as func->cur_blksize is properly set and F2 init has been
927 * completed successfully.
928 */
929 func = sdiodev->func[2];
930 host = func->card->host;
931 sdiodev->sg_support = host->max_segs > 1;
932 max_blocks = min_t(uint, host->max_blk_count, 511u);
933 sdiodev->max_request_size = min_t(uint, host->max_req_size,
934 max_blocks * func->cur_blksize);
935 sdiodev->max_segment_count = min_t(uint, host->max_segs,
936 SG_MAX_SINGLE_ALLOC);
937 sdiodev->max_segment_size = host->max_seg_size;
762 938
763 /* try to attach to the target device */ 939 /* try to attach to the target device */
764 sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); 940 sdiodev->bus = brcmf_sdio_probe(sdiodev);
765 if (!sdiodev->bus) { 941 if (!sdiodev->bus) {
766 brcmf_err("device attach failed\n");
767 ret = -ENODEV; 942 ret = -ENODEV;
768 goto out; 943 goto out;
769 } 944 }
770 945
771out: 946out:
772 if (ret) 947 if (ret)
773 brcmf_sdio_remove(sdiodev); 948 brcmf_sdiod_remove(sdiodev);
774 949
775 return ret; 950 return ret;
776} 951}
777EXPORT_SYMBOL(brcmf_sdio_probe);
778 952
779int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) 953/* devices we support, null terminated */
954static const struct sdio_device_id brcmf_sdmmc_ids[] = {
955 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)},
956 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
957 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
958 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
959 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
960 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
961 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
962 SDIO_DEVICE_ID_BROADCOM_4335_4339)},
963 { /* end: all zeroes */ },
964};
965MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
966
967static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
968
969
970static int brcmf_ops_sdio_probe(struct sdio_func *func,
971 const struct sdio_device_id *id)
780{ 972{
781 sdiodev->bus_if->state = BRCMF_BUS_DOWN; 973 int err;
974 struct brcmf_sdio_dev *sdiodev;
975 struct brcmf_bus *bus_if;
782 976
783 if (sdiodev->bus) { 977 brcmf_dbg(SDIO, "Enter\n");
784 brcmf_sdbrcm_disconnect(sdiodev->bus); 978 brcmf_dbg(SDIO, "Class=%x\n", func->class);
785 sdiodev->bus = NULL; 979 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
980 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
981 brcmf_dbg(SDIO, "Function#: %d\n", func->num);
982
983 /* Consume func num 1 but dont do anything with it. */
984 if (func->num == 1)
985 return 0;
986
987 /* Ignore anything but func 2 */
988 if (func->num != 2)
989 return -ENODEV;
990
991 bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
992 if (!bus_if)
993 return -ENOMEM;
994 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
995 if (!sdiodev) {
996 kfree(bus_if);
997 return -ENOMEM;
786 } 998 }
787 999
788 brcmf_sdioh_detach(sdiodev); 1000 /* store refs to functions used. mmc_card does
1001 * not hold the F0 function pointer.
1002 */
1003 sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
1004 sdiodev->func[0]->num = 0;
1005 sdiodev->func[1] = func->card->sdio_func[0];
1006 sdiodev->func[2] = func;
1007
1008 sdiodev->bus_if = bus_if;
1009 bus_if->bus_priv.sdio = sdiodev;
1010 bus_if->proto_type = BRCMF_PROTO_BCDC;
1011 dev_set_drvdata(&func->dev, bus_if);
1012 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
1013 sdiodev->dev = &sdiodev->func[1]->dev;
1014 sdiodev->pdata = brcmfmac_sdio_pdata;
1015
1016 atomic_set(&sdiodev->suspend, false);
1017 init_waitqueue_head(&sdiodev->request_word_wait);
1018 init_waitqueue_head(&sdiodev->request_buffer_wait);
1019
1020 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1021 err = brcmf_sdiod_probe(sdiodev);
1022 if (err) {
1023 brcmf_err("F2 error, probe failed %d...\n", err);
1024 goto fail;
1025 }
789 1026
790 sdiodev->sbwad = 0; 1027 brcmf_dbg(SDIO, "F2 init completed...\n");
1028 return 0;
1029
1030fail:
1031 dev_set_drvdata(&func->dev, NULL);
1032 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
1033 kfree(sdiodev->func[0]);
1034 kfree(sdiodev);
1035 kfree(bus_if);
1036 return err;
1037}
1038
1039static void brcmf_ops_sdio_remove(struct sdio_func *func)
1040{
1041 struct brcmf_bus *bus_if;
1042 struct brcmf_sdio_dev *sdiodev;
1043
1044 brcmf_dbg(SDIO, "Enter\n");
1045 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
1046 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1047 brcmf_dbg(SDIO, "Function: %d\n", func->num);
1048
1049 if (func->num != 1 && func->num != 2)
1050 return;
1051
1052 bus_if = dev_get_drvdata(&func->dev);
1053 if (bus_if) {
1054 sdiodev = bus_if->bus_priv.sdio;
1055 brcmf_sdiod_remove(sdiodev);
1056
1057 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
1058 dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
1059
1060 kfree(bus_if);
1061 kfree(sdiodev->func[0]);
1062 kfree(sdiodev);
1063 }
1064
1065 brcmf_dbg(SDIO, "Exit\n");
1066}
1067
1068#ifdef CONFIG_PM_SLEEP
1069static int brcmf_ops_sdio_suspend(struct device *dev)
1070{
1071 mmc_pm_flag_t sdio_flags;
1072 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1073 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1074 int ret = 0;
1075
1076 brcmf_dbg(SDIO, "\n");
1077
1078 atomic_set(&sdiodev->suspend, true);
1079
1080 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
1081 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
1082 brcmf_err("Host can't keep power while suspended\n");
1083 return -EINVAL;
1084 }
1085
1086 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
1087 if (ret) {
1088 brcmf_err("Failed to set pm_flags\n");
1089 return ret;
1090 }
1091
1092 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1093
1094 return ret;
1095}
1096
1097static int brcmf_ops_sdio_resume(struct device *dev)
1098{
1099 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1100 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1101
1102 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
1103 atomic_set(&sdiodev->suspend, false);
1104 return 0;
1105}
1106
1107static const struct dev_pm_ops brcmf_sdio_pm_ops = {
1108 .suspend = brcmf_ops_sdio_suspend,
1109 .resume = brcmf_ops_sdio_resume,
1110};
1111#endif /* CONFIG_PM_SLEEP */
1112
1113static struct sdio_driver brcmf_sdmmc_driver = {
1114 .probe = brcmf_ops_sdio_probe,
1115 .remove = brcmf_ops_sdio_remove,
1116 .name = BRCMFMAC_SDIO_PDATA_NAME,
1117 .id_table = brcmf_sdmmc_ids,
1118#ifdef CONFIG_PM_SLEEP
1119 .drv = {
1120 .pm = &brcmf_sdio_pm_ops,
1121 },
1122#endif /* CONFIG_PM_SLEEP */
1123};
1124
1125static int brcmf_sdio_pd_probe(struct platform_device *pdev)
1126{
1127 brcmf_dbg(SDIO, "Enter\n");
1128
1129 brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
1130
1131 if (brcmfmac_sdio_pdata->power_on)
1132 brcmfmac_sdio_pdata->power_on();
791 1133
792 return 0; 1134 return 0;
793} 1135}
794EXPORT_SYMBOL(brcmf_sdio_remove);
795 1136
796void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) 1137static int brcmf_sdio_pd_remove(struct platform_device *pdev)
797{ 1138{
798 if (enable) 1139 brcmf_dbg(SDIO, "Enter\n");
799 brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1140
1141 if (brcmfmac_sdio_pdata->power_off)
1142 brcmfmac_sdio_pdata->power_off();
1143
1144 sdio_unregister_driver(&brcmf_sdmmc_driver);
1145
1146 return 0;
1147}
1148
1149static struct platform_driver brcmf_sdio_pd = {
1150 .remove = brcmf_sdio_pd_remove,
1151 .driver = {
1152 .name = BRCMFMAC_SDIO_PDATA_NAME,
1153 .owner = THIS_MODULE,
1154 }
1155};
1156
1157void brcmf_sdio_register(void)
1158{
1159 int ret;
1160
1161 ret = sdio_register_driver(&brcmf_sdmmc_driver);
1162 if (ret)
1163 brcmf_err("sdio_register_driver failed: %d\n", ret);
1164}
1165
1166void brcmf_sdio_exit(void)
1167{
1168 brcmf_dbg(SDIO, "Enter\n");
1169
1170 if (brcmfmac_sdio_pdata)
1171 platform_driver_unregister(&brcmf_sdio_pd);
800 else 1172 else
801 brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); 1173 sdio_unregister_driver(&brcmf_sdmmc_driver);
1174}
1175
1176void __init brcmf_sdio_init(void)
1177{
1178 int ret;
1179
1180 brcmf_dbg(SDIO, "Enter\n");
1181
1182 ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
1183 if (ret == -ENODEV)
1184 brcmf_dbg(SDIO, "No platform data available.\n");
802} 1185}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
deleted file mode 100644
index abc9ceca70f3..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ /dev/null
@@ -1,539 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <linux/netdevice.h>
19#include <linux/mmc/sdio.h>
20#include <linux/mmc/core.h>
21#include <linux/mmc/sdio_func.h>
22#include <linux/mmc/sdio_ids.h>
23#include <linux/mmc/card.h>
24#include <linux/mmc/host.h>
25#include <linux/suspend.h>
26#include <linux/errno.h>
27#include <linux/sched.h> /* request_irq() */
28#include <linux/module.h>
29#include <linux/platform_device.h>
30#include <linux/platform_data/brcmfmac-sdio.h>
31#include <net/cfg80211.h>
32
33#include <defs.h>
34#include <brcm_hw_ids.h>
35#include <brcmu_utils.h>
36#include <brcmu_wifi.h>
37#include "sdio_host.h"
38#include "sdio_chip.h"
39#include "dhd_dbg.h"
40#include "dhd_bus.h"
41
42#define SDIO_VENDOR_ID_BROADCOM 0x02d0
43
44#define DMA_ALIGN_MASK 0x03
45
46#define SDIO_FUNC1_BLOCKSIZE 64
47#define SDIO_FUNC2_BLOCKSIZE 512
48
49/* devices we support, null terminated */
50static const struct sdio_device_id brcmf_sdmmc_ids[] = {
51 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)},
52 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
53 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
54 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
55 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
56 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
57 SDIO_DEVICE_ID_BROADCOM_4335_4339)},
58 { /* end: all zeroes */ },
59};
60MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
61
62static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
63
64
65bool
66brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
67{
68 bool is_err = false;
69#ifdef CONFIG_PM_SLEEP
70 is_err = atomic_read(&sdiodev->suspend);
71#endif
72 return is_err;
73}
74
75void
76brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
77{
78#ifdef CONFIG_PM_SLEEP
79 int retry = 0;
80 while (atomic_read(&sdiodev->suspend) && retry++ != 30)
81 wait_event_timeout(*wq, false, HZ/100);
82#endif
83}
84
85static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
86 uint regaddr, u8 *byte)
87{
88 struct sdio_func *sdfunc = sdiodev->func[0];
89 int err_ret;
90
91 /*
92 * Can only directly write to some F0 registers.
93 * Handle F2 enable/disable and Abort command
94 * as a special case.
95 */
96 if (regaddr == SDIO_CCCR_IOEx) {
97 sdfunc = sdiodev->func[2];
98 if (sdfunc) {
99 if (*byte & SDIO_FUNC_ENABLE_2) {
100 /* Enable Function 2 */
101 err_ret = sdio_enable_func(sdfunc);
102 if (err_ret)
103 brcmf_err("enable F2 failed:%d\n",
104 err_ret);
105 } else {
106 /* Disable Function 2 */
107 err_ret = sdio_disable_func(sdfunc);
108 if (err_ret)
109 brcmf_err("Disable F2 failed:%d\n",
110 err_ret);
111 }
112 } else {
113 err_ret = -ENOENT;
114 }
115 } else if ((regaddr == SDIO_CCCR_ABORT) ||
116 (regaddr == SDIO_CCCR_IENx)) {
117 sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
118 GFP_KERNEL);
119 if (!sdfunc)
120 return -ENOMEM;
121 sdfunc->num = 0;
122 sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
123 kfree(sdfunc);
124 } else if (regaddr < 0xF0) {
125 brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr);
126 err_ret = -EPERM;
127 } else {
128 sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
129 }
130
131 return err_ret;
132}
133
134int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
135 uint regaddr, u8 *byte)
136{
137 int err_ret;
138
139 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
140
141 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
142 if (brcmf_pm_resume_error(sdiodev))
143 return -EIO;
144
145 if (rw && func == 0) {
146 /* handle F0 separately */
147 err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
148 } else {
149 if (rw) /* CMD52 Write */
150 sdio_writeb(sdiodev->func[func], *byte, regaddr,
151 &err_ret);
152 else if (func == 0) {
153 *byte = sdio_f0_readb(sdiodev->func[func], regaddr,
154 &err_ret);
155 } else {
156 *byte = sdio_readb(sdiodev->func[func], regaddr,
157 &err_ret);
158 }
159 }
160
161 if (err_ret)
162 brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
163 rw ? "write" : "read", func, regaddr, *byte, err_ret);
164
165 return err_ret;
166}
167
168int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
169 uint rw, uint func, uint addr, u32 *word,
170 uint nbytes)
171{
172 int err_ret = -EIO;
173
174 if (func == 0) {
175 brcmf_err("Only CMD52 allowed to F0\n");
176 return -EINVAL;
177 }
178
179 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
180 rw, func, addr, nbytes);
181
182 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
183 if (brcmf_pm_resume_error(sdiodev))
184 return -EIO;
185
186 if (rw) { /* CMD52 Write */
187 if (nbytes == 4)
188 sdio_writel(sdiodev->func[func], *word, addr,
189 &err_ret);
190 else if (nbytes == 2)
191 sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
192 addr, &err_ret);
193 else
194 brcmf_err("Invalid nbytes: %d\n", nbytes);
195 } else { /* CMD52 Read */
196 if (nbytes == 4)
197 *word = sdio_readl(sdiodev->func[func], addr, &err_ret);
198 else if (nbytes == 2)
199 *word = sdio_readw(sdiodev->func[func], addr,
200 &err_ret) & 0xFFFF;
201 else
202 brcmf_err("Invalid nbytes: %d\n", nbytes);
203 }
204
205 if (err_ret)
206 brcmf_err("Failed to %s word, Err: 0x%08x\n",
207 rw ? "write" : "read", err_ret);
208
209 return err_ret;
210}
211
212static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
213{
214 /* read 24 bits and return valid 17 bit addr */
215 int i, ret;
216 u32 scratch, regdata;
217 __le32 scratch_le;
218 u8 *ptr = (u8 *)&scratch_le;
219
220 for (i = 0; i < 3; i++) {
221 regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
222 if (ret != 0)
223 brcmf_err("Can't read!\n");
224
225 *ptr++ = (u8) regdata;
226 regaddr++;
227 }
228
229 /* Only the lower 17-bits are valid */
230 scratch = le32_to_cpu(scratch_le);
231 scratch &= 0x0001FFFF;
232 return scratch;
233}
234
235static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
236{
237 int err_ret;
238 u32 fbraddr;
239 u8 func;
240
241 brcmf_dbg(SDIO, "\n");
242
243 /* Get the Card's common CIS address */
244 sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
245 SDIO_CCCR_CIS);
246 brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n",
247 sdiodev->func_cis_ptr[0]);
248
249 /* Get the Card's function CIS (for each function) */
250 for (fbraddr = SDIO_FBR_BASE(1), func = 1;
251 func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
252 sdiodev->func_cis_ptr[func] =
253 brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
254 brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n",
255 func, sdiodev->func_cis_ptr[func]);
256 }
257
258 /* Enable Function 1 */
259 err_ret = sdio_enable_func(sdiodev->func[1]);
260 if (err_ret)
261 brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret);
262
263 return false;
264}
265
266/*
267 * Public entry points & extern's
268 */
269int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
270{
271 int err_ret = 0;
272
273 brcmf_dbg(SDIO, "\n");
274
275 sdiodev->num_funcs = 2;
276
277 sdio_claim_host(sdiodev->func[1]);
278
279 err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
280 if (err_ret) {
281 brcmf_err("Failed to set F1 blocksize\n");
282 goto out;
283 }
284
285 err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
286 if (err_ret) {
287 brcmf_err("Failed to set F2 blocksize\n");
288 goto out;
289 }
290
291 brcmf_sdioh_enablefuncs(sdiodev);
292
293out:
294 sdio_release_host(sdiodev->func[1]);
295 brcmf_dbg(SDIO, "Done\n");
296 return err_ret;
297}
298
299void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
300{
301 brcmf_dbg(SDIO, "\n");
302
303 /* Disable Function 2 */
304 sdio_claim_host(sdiodev->func[2]);
305 sdio_disable_func(sdiodev->func[2]);
306 sdio_release_host(sdiodev->func[2]);
307
308 /* Disable Function 1 */
309 sdio_claim_host(sdiodev->func[1]);
310 sdio_disable_func(sdiodev->func[1]);
311 sdio_release_host(sdiodev->func[1]);
312
313}
314
315static int brcmf_ops_sdio_probe(struct sdio_func *func,
316 const struct sdio_device_id *id)
317{
318 int err;
319 struct brcmf_sdio_dev *sdiodev;
320 struct brcmf_bus *bus_if;
321 struct mmc_host *host;
322 uint max_blocks;
323
324 brcmf_dbg(SDIO, "Enter\n");
325 brcmf_dbg(SDIO, "Class=%x\n", func->class);
326 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
327 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
328 brcmf_dbg(SDIO, "Function#: %d\n", func->num);
329
330 /* Consume func num 1 but dont do anything with it. */
331 if (func->num == 1)
332 return 0;
333
334 /* Ignore anything but func 2 */
335 if (func->num != 2)
336 return -ENODEV;
337
338 bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
339 if (!bus_if)
340 return -ENOMEM;
341 sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
342 if (!sdiodev) {
343 kfree(bus_if);
344 return -ENOMEM;
345 }
346
347 sdiodev->func[0] = func->card->sdio_func[0];
348 sdiodev->func[1] = func->card->sdio_func[0];
349 sdiodev->func[2] = func;
350
351 sdiodev->bus_if = bus_if;
352 bus_if->bus_priv.sdio = sdiodev;
353 dev_set_drvdata(&func->dev, bus_if);
354 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
355 sdiodev->dev = &sdiodev->func[1]->dev;
356 sdiodev->pdata = brcmfmac_sdio_pdata;
357
358 atomic_set(&sdiodev->suspend, false);
359 init_waitqueue_head(&sdiodev->request_byte_wait);
360 init_waitqueue_head(&sdiodev->request_word_wait);
361 init_waitqueue_head(&sdiodev->request_buffer_wait);
362
363 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
364 err = brcmf_sdio_probe(sdiodev);
365 if (err) {
366 brcmf_err("F2 error, probe failed %d...\n", err);
367 goto fail;
368 }
369
370 /*
371 * determine host related variables after brcmf_sdio_probe()
372 * as func->cur_blksize is properly set and F2 init has been
373 * completed successfully.
374 */
375 host = func->card->host;
376 sdiodev->sg_support = host->max_segs > 1;
377 max_blocks = min_t(uint, host->max_blk_count, 511u);
378 sdiodev->max_request_size = min_t(uint, host->max_req_size,
379 max_blocks * func->cur_blksize);
380 sdiodev->max_segment_count = min_t(uint, host->max_segs,
381 SG_MAX_SINGLE_ALLOC);
382 sdiodev->max_segment_size = host->max_seg_size;
383 brcmf_dbg(SDIO, "F2 init completed...\n");
384 return 0;
385
386fail:
387 dev_set_drvdata(&func->dev, NULL);
388 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
389 kfree(sdiodev);
390 kfree(bus_if);
391 return err;
392}
393
394static void brcmf_ops_sdio_remove(struct sdio_func *func)
395{
396 struct brcmf_bus *bus_if;
397 struct brcmf_sdio_dev *sdiodev;
398
399 brcmf_dbg(SDIO, "Enter\n");
400 brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
401 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
402 brcmf_dbg(SDIO, "Function: %d\n", func->num);
403
404 if (func->num != 1 && func->num != 2)
405 return;
406
407 bus_if = dev_get_drvdata(&func->dev);
408 if (bus_if) {
409 sdiodev = bus_if->bus_priv.sdio;
410 brcmf_sdio_remove(sdiodev);
411
412 dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
413 dev_set_drvdata(&sdiodev->func[2]->dev, NULL);
414
415 kfree(bus_if);
416 kfree(sdiodev);
417 }
418
419 brcmf_dbg(SDIO, "Exit\n");
420}
421
422#ifdef CONFIG_PM_SLEEP
423static int brcmf_sdio_suspend(struct device *dev)
424{
425 mmc_pm_flag_t sdio_flags;
426 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
427 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
428 int ret = 0;
429
430 brcmf_dbg(SDIO, "\n");
431
432 atomic_set(&sdiodev->suspend, true);
433
434 sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
435 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
436 brcmf_err("Host can't keep power while suspended\n");
437 return -EINVAL;
438 }
439
440 ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
441 if (ret) {
442 brcmf_err("Failed to set pm_flags\n");
443 return ret;
444 }
445
446 brcmf_sdio_wdtmr_enable(sdiodev, false);
447
448 return ret;
449}
450
451static int brcmf_sdio_resume(struct device *dev)
452{
453 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
454 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
455
456 brcmf_sdio_wdtmr_enable(sdiodev, true);
457 atomic_set(&sdiodev->suspend, false);
458 return 0;
459}
460
461static const struct dev_pm_ops brcmf_sdio_pm_ops = {
462 .suspend = brcmf_sdio_suspend,
463 .resume = brcmf_sdio_resume,
464};
465#endif /* CONFIG_PM_SLEEP */
466
467static struct sdio_driver brcmf_sdmmc_driver = {
468 .probe = brcmf_ops_sdio_probe,
469 .remove = brcmf_ops_sdio_remove,
470 .name = BRCMFMAC_SDIO_PDATA_NAME,
471 .id_table = brcmf_sdmmc_ids,
472#ifdef CONFIG_PM_SLEEP
473 .drv = {
474 .pm = &brcmf_sdio_pm_ops,
475 },
476#endif /* CONFIG_PM_SLEEP */
477};
478
479static int brcmf_sdio_pd_probe(struct platform_device *pdev)
480{
481 brcmf_dbg(SDIO, "Enter\n");
482
483 brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
484
485 if (brcmfmac_sdio_pdata->power_on)
486 brcmfmac_sdio_pdata->power_on();
487
488 return 0;
489}
490
491static int brcmf_sdio_pd_remove(struct platform_device *pdev)
492{
493 brcmf_dbg(SDIO, "Enter\n");
494
495 if (brcmfmac_sdio_pdata->power_off)
496 brcmfmac_sdio_pdata->power_off();
497
498 sdio_unregister_driver(&brcmf_sdmmc_driver);
499
500 return 0;
501}
502
503static struct platform_driver brcmf_sdio_pd = {
504 .remove = brcmf_sdio_pd_remove,
505 .driver = {
506 .name = BRCMFMAC_SDIO_PDATA_NAME,
507 .owner = THIS_MODULE,
508 }
509};
510
511void brcmf_sdio_register(void)
512{
513 int ret;
514
515 ret = sdio_register_driver(&brcmf_sdmmc_driver);
516 if (ret)
517 brcmf_err("sdio_register_driver failed: %d\n", ret);
518}
519
520void brcmf_sdio_exit(void)
521{
522 brcmf_dbg(SDIO, "Enter\n");
523
524 if (brcmfmac_sdio_pdata)
525 platform_driver_unregister(&brcmf_sdio_pd);
526 else
527 sdio_unregister_driver(&brcmf_sdmmc_driver);
528}
529
530void __init brcmf_sdio_init(void)
531{
532 int ret;
533
534 brcmf_dbg(SDIO, "Enter\n");
535
536 ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
537 if (ret == -ENODEV)
538 brcmf_dbg(SDIO, "No platform data available.\n");
539}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 899a2ada5b82..939d6b132922 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -21,481 +21,33 @@
21#ifndef _BRCMF_H_ 21#ifndef _BRCMF_H_
22#define _BRCMF_H_ 22#define _BRCMF_H_
23 23
24#define BRCMF_VERSION_STR "4.218.248.5"
25
26#include "fweh.h" 24#include "fweh.h"
27 25
28/*******************************************************************************
29 * IO codes that are interpreted by dongle firmware
30 ******************************************************************************/
31#define BRCMF_C_GET_VERSION 1
32#define BRCMF_C_UP 2
33#define BRCMF_C_DOWN 3
34#define BRCMF_C_SET_PROMISC 10
35#define BRCMF_C_GET_RATE 12
36#define BRCMF_C_GET_INFRA 19
37#define BRCMF_C_SET_INFRA 20
38#define BRCMF_C_GET_AUTH 21
39#define BRCMF_C_SET_AUTH 22
40#define BRCMF_C_GET_BSSID 23
41#define BRCMF_C_GET_SSID 25
42#define BRCMF_C_SET_SSID 26
43#define BRCMF_C_TERMINATED 28
44#define BRCMF_C_GET_CHANNEL 29
45#define BRCMF_C_SET_CHANNEL 30
46#define BRCMF_C_GET_SRL 31
47#define BRCMF_C_SET_SRL 32
48#define BRCMF_C_GET_LRL 33
49#define BRCMF_C_SET_LRL 34
50#define BRCMF_C_GET_RADIO 37
51#define BRCMF_C_SET_RADIO 38
52#define BRCMF_C_GET_PHYTYPE 39
53#define BRCMF_C_SET_KEY 45
54#define BRCMF_C_SET_PASSIVE_SCAN 49
55#define BRCMF_C_SCAN 50
56#define BRCMF_C_SCAN_RESULTS 51
57#define BRCMF_C_DISASSOC 52
58#define BRCMF_C_REASSOC 53
59#define BRCMF_C_SET_ROAM_TRIGGER 55
60#define BRCMF_C_SET_ROAM_DELTA 57
61#define BRCMF_C_GET_BCNPRD 75
62#define BRCMF_C_SET_BCNPRD 76
63#define BRCMF_C_GET_DTIMPRD 77
64#define BRCMF_C_SET_DTIMPRD 78
65#define BRCMF_C_SET_COUNTRY 84
66#define BRCMF_C_GET_PM 85
67#define BRCMF_C_SET_PM 86
68#define BRCMF_C_GET_CURR_RATESET 114
69#define BRCMF_C_GET_AP 117
70#define BRCMF_C_SET_AP 118
71#define BRCMF_C_GET_RSSI 127
72#define BRCMF_C_GET_WSEC 133
73#define BRCMF_C_SET_WSEC 134
74#define BRCMF_C_GET_PHY_NOISE 135
75#define BRCMF_C_GET_BSS_INFO 136
76#define BRCMF_C_GET_BANDLIST 140
77#define BRCMF_C_SET_SCB_TIMEOUT 158
78#define BRCMF_C_GET_PHYLIST 180
79#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
80#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
81#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
82#define BRCMF_C_GET_VALID_CHANNELS 217
83#define BRCMF_C_GET_KEY_PRIMARY 235
84#define BRCMF_C_SET_KEY_PRIMARY 236
85#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
86#define BRCMF_C_GET_VAR 262
87#define BRCMF_C_SET_VAR 263
88
89/* phy types (returned by WLC_GET_PHYTPE) */
90#define WLC_PHY_TYPE_A 0
91#define WLC_PHY_TYPE_B 1
92#define WLC_PHY_TYPE_G 2
93#define WLC_PHY_TYPE_N 4
94#define WLC_PHY_TYPE_LP 5
95#define WLC_PHY_TYPE_SSN 6
96#define WLC_PHY_TYPE_HT 7
97#define WLC_PHY_TYPE_LCN 8
98#define WLC_PHY_TYPE_NULL 0xf
99
100#define TOE_TX_CSUM_OL 0x00000001 26#define TOE_TX_CSUM_OL 0x00000001
101#define TOE_RX_CSUM_OL 0x00000002 27#define TOE_RX_CSUM_OL 0x00000002
102 28
103#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
104
105/* size of brcmf_scan_params not including variable length array */
106#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
107
108/* masks for channel and ssid count */
109#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
110#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
111
112/* primary (ie tx) key */
113#define BRCMF_PRIMARY_KEY (1 << 1)
114
115/* For supporting multiple interfaces */ 29/* For supporting multiple interfaces */
116#define BRCMF_MAX_IFS 16 30#define BRCMF_MAX_IFS 16
117 31
118#define DOT11_BSSTYPE_ANY 2
119#define DOT11_MAX_DEFAULT_KEYS 4 32#define DOT11_MAX_DEFAULT_KEYS 4
120 33
121#define BRCMF_ESCAN_REQ_VERSION 1
122
123#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
124
125#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
126#define BRCMF_STA_ASSOC 0x10 /* Associated */
127
128#define BRCMF_E_STATUS_SUCCESS 0
129#define BRCMF_E_STATUS_FAIL 1
130#define BRCMF_E_STATUS_TIMEOUT 2
131#define BRCMF_E_STATUS_NO_NETWORKS 3
132#define BRCMF_E_STATUS_ABORT 4
133#define BRCMF_E_STATUS_NO_ACK 5
134#define BRCMF_E_STATUS_UNSOLICITED 6
135#define BRCMF_E_STATUS_ATTEMPT 7
136#define BRCMF_E_STATUS_PARTIAL 8
137#define BRCMF_E_STATUS_NEWSCAN 9
138#define BRCMF_E_STATUS_NEWASSOC 10
139#define BRCMF_E_STATUS_11HQUIET 11
140#define BRCMF_E_STATUS_SUPPRESS 12
141#define BRCMF_E_STATUS_NOCHANS 13
142#define BRCMF_E_STATUS_CS_ABORT 15
143#define BRCMF_E_STATUS_ERROR 16
144
145#define BRCMF_E_REASON_INITIAL_ASSOC 0
146#define BRCMF_E_REASON_LOW_RSSI 1
147#define BRCMF_E_REASON_DEAUTH 2
148#define BRCMF_E_REASON_DISASSOC 3
149#define BRCMF_E_REASON_BCNS_LOST 4
150#define BRCMF_E_REASON_MINTXRATE 9
151#define BRCMF_E_REASON_TXFAIL 10
152
153#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
154#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
155#define BRCMF_E_REASON_DIRECTED_ROAM 6
156#define BRCMF_E_REASON_TSPEC_REJECTED 7
157#define BRCMF_E_REASON_BETTER_AP 8
158
159#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
160#define BRCMF_E_PRUNE_BCAST_BSSID 2
161#define BRCMF_E_PRUNE_MAC_DENY 3
162#define BRCMF_E_PRUNE_MAC_NA 4
163#define BRCMF_E_PRUNE_REG_PASSV 5
164#define BRCMF_E_PRUNE_SPCT_MGMT 6
165#define BRCMF_E_PRUNE_RADAR 7
166#define BRCMF_E_RSN_MISMATCH 8
167#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
168#define BRCMF_E_PRUNE_BASIC_RATES 10
169#define BRCMF_E_PRUNE_CIPHER_NA 12
170#define BRCMF_E_PRUNE_KNOWN_STA 13
171#define BRCMF_E_PRUNE_WDS_PEER 15
172#define BRCMF_E_PRUNE_QBSS_LOAD 16
173#define BRCMF_E_PRUNE_HOME_AP 17
174
175#define BRCMF_E_SUP_OTHER 0
176#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
177#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
178#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
179#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
180#define BRCMF_E_SUP_PW_KEY_CIPHER 5
181#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
182#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
183#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
184#define BRCMF_E_SUP_MSG3_NO_GTK 9
185#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
186#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
187#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
188#define BRCMF_E_SUP_SEND_FAIL 13
189#define BRCMF_E_SUP_DEAUTH 14
190
191#define BRCMF_E_IF_ADD 1
192#define BRCMF_E_IF_DEL 2
193#define BRCMF_E_IF_CHANGE 3
194
195#define BRCMF_E_IF_FLAG_NOIF 1
196
197#define BRCMF_E_IF_ROLE_STA 0
198#define BRCMF_E_IF_ROLE_AP 1
199#define BRCMF_E_IF_ROLE_WDS 2
200
201#define BRCMF_E_LINK_BCN_LOSS 1
202#define BRCMF_E_LINK_DISASSOC 2
203#define BRCMF_E_LINK_ASSOC_REC 3
204#define BRCMF_E_LINK_BSSCFG_DIS 4
205
206/* Small, medium and maximum buffer size for dcmd 34/* Small, medium and maximum buffer size for dcmd
207 */ 35 */
208#define BRCMF_DCMD_SMLEN 256 36#define BRCMF_DCMD_SMLEN 256
209#define BRCMF_DCMD_MEDLEN 1536 37#define BRCMF_DCMD_MEDLEN 1536
210#define BRCMF_DCMD_MAXLEN 8192 38#define BRCMF_DCMD_MAXLEN 8192
211 39
212#define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 40/* IOCTL from host to device are limited in lenght. A device can only handle
213 41 * ethernet frame size. This limitation is to be applied by protocol layer.
214/* Pattern matching filter. Specifies an offset within received packets to
215 * start matching, the pattern to match, the size of the pattern, and a bitmask
216 * that indicates which bits within the pattern should be matched.
217 */
218struct brcmf_pkt_filter_pattern_le {
219 /*
220 * Offset within received packet to start pattern matching.
221 * Offset '0' is the first byte of the ethernet header.
222 */
223 __le32 offset;
224 /* Size of the pattern. Bitmask must be the same size.*/
225 __le32 size_bytes;
226 /*
227 * Variable length mask and pattern data. mask starts at offset 0.
228 * Pattern immediately follows mask.
229 */
230 u8 mask_and_pattern[1];
231};
232
233/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
234struct brcmf_pkt_filter_le {
235 __le32 id; /* Unique filter id, specified by app. */
236 __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
237 __le32 negate_match; /* Negate the result of filter matches */
238 union { /* Filter definitions */
239 struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
240 } u;
241};
242
243/* IOVAR "pkt_filter_enable" parameter. */
244struct brcmf_pkt_filter_enable_le {
245 __le32 id; /* Unique filter id */
246 __le32 enable; /* Enable/disable bool */
247};
248
249/* BSS info structure
250 * Applications MUST CHECK ie_offset field and length field to access IEs and
251 * next bss_info structure in a vector (in struct brcmf_scan_results)
252 */ 42 */
253struct brcmf_bss_info_le { 43#define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
254 __le32 version; /* version field */
255 __le32 length; /* byte length of data in this record,
256 * starting at version and including IEs
257 */
258 u8 BSSID[ETH_ALEN];
259 __le16 beacon_period; /* units are Kusec */
260 __le16 capability; /* Capability information */
261 u8 SSID_len;
262 u8 SSID[32];
263 struct {
264 __le32 count; /* # rates in this set */
265 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
266 } rateset; /* supported rates */
267 __le16 chanspec; /* chanspec for bss */
268 __le16 atim_window; /* units are Kusec */
269 u8 dtim_period; /* DTIM period */
270 __le16 RSSI; /* receive signal strength (in dBm) */
271 s8 phy_noise; /* noise (in dBm) */
272
273 u8 n_cap; /* BSS is 802.11N Capable */
274 /* 802.11N BSS Capabilities (based on HT_CAP_*): */
275 __le32 nbss_cap;
276 u8 ctl_ch; /* 802.11N BSS control channel number */
277 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
278 u8 flags; /* flags */
279 u8 reserved[3]; /* Reserved for expansion of BSS properties */
280 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
281 44
282 __le16 ie_offset; /* offset at which IEs start, from beginning */ 45#define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256
283 __le32 ie_length; /* byte length of Information Elements */
284 __le16 SNR; /* average SNR of during frame reception */
285 /* Add new fields here */
286 /* variable length Information Elements */
287};
288
289struct brcm_rateset_le {
290 /* # rates in this set */
291 __le32 count;
292 /* rates in 500kbps units w/hi bit set if basic */
293 u8 rates[BRCMF_MAXRATES_IN_SET];
294};
295
296struct brcmf_ssid {
297 u32 SSID_len;
298 unsigned char SSID[32];
299};
300
301struct brcmf_ssid_le {
302 __le32 SSID_len;
303 unsigned char SSID[32];
304};
305
306struct brcmf_scan_params_le {
307 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
308 u8 bssid[ETH_ALEN]; /* default: bcast */
309 s8 bss_type; /* default: any,
310 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
311 */
312 u8 scan_type; /* flags, 0 use default */
313 __le32 nprobes; /* -1 use default, number of probes per channel */
314 __le32 active_time; /* -1 use default, dwell time per channel for
315 * active scanning
316 */
317 __le32 passive_time; /* -1 use default, dwell time per channel
318 * for passive scanning
319 */
320 __le32 home_time; /* -1 use default, dwell time for the
321 * home channel between channel scans
322 */
323 __le32 channel_num; /* count of channels and ssids that follow
324 *
325 * low half is count of channels in
326 * channel_list, 0 means default (use all
327 * available channels)
328 *
329 * high half is entries in struct brcmf_ssid
330 * array that follows channel_list, aligned for
331 * s32 (4 bytes) meaning an odd channel count
332 * implies a 2-byte pad between end of
333 * channel_list and first ssid
334 *
335 * if ssid count is zero, single ssid in the
336 * fixed parameter portion is assumed, otherwise
337 * ssid in the fixed portion is ignored
338 */
339 __le16 channel_list[1]; /* list of chanspecs */
340};
341
342struct brcmf_scan_results {
343 u32 buflen;
344 u32 version;
345 u32 count;
346 struct brcmf_bss_info_le bss_info_le[];
347};
348
349struct brcmf_escan_params_le {
350 __le32 version;
351 __le16 action;
352 __le16 sync_id;
353 struct brcmf_scan_params_le params_le;
354};
355
356struct brcmf_escan_result_le {
357 __le32 buflen;
358 __le32 version;
359 __le16 sync_id;
360 __le16 bss_count;
361 struct brcmf_bss_info_le bss_info_le;
362};
363
364#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
365 sizeof(struct brcmf_bss_info_le))
366
367/* used for association with a specific BSSID and chanspec list */
368struct brcmf_assoc_params_le {
369 /* 00:00:00:00:00:00: broadcast scan */
370 u8 bssid[ETH_ALEN];
371 /* 0: all available channels, otherwise count of chanspecs in
372 * chanspec_list */
373 __le32 chanspec_num;
374 /* list of chanspecs */
375 __le16 chanspec_list[1];
376};
377
378/* used for join with or without a specific bssid and channel list */
379struct brcmf_join_params {
380 struct brcmf_ssid_le ssid_le;
381 struct brcmf_assoc_params_le params_le;
382};
383
384/* scan params for extended join */
385struct brcmf_join_scan_params_le {
386 u8 scan_type; /* 0 use default, active or passive scan */
387 __le32 nprobes; /* -1 use default, nr of probes per channel */
388 __le32 active_time; /* -1 use default, dwell time per channel for
389 * active scanning
390 */
391 __le32 passive_time; /* -1 use default, dwell time per channel
392 * for passive scanning
393 */
394 __le32 home_time; /* -1 use default, dwell time for the home
395 * channel between channel scans
396 */
397};
398
399/* extended join params */
400struct brcmf_ext_join_params_le {
401 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
402 struct brcmf_join_scan_params_le scan_le;
403 struct brcmf_assoc_params_le assoc_le;
404};
405
406struct brcmf_wsec_key {
407 u32 index; /* key index */
408 u32 len; /* key length */
409 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
410 u32 pad_1[18];
411 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
412 u32 flags; /* misc flags */
413 u32 pad_2[3];
414 u32 iv_initialized; /* has IV been initialized already? */
415 u32 pad_3;
416 /* Rx IV */
417 struct {
418 u32 hi; /* upper 32 bits of IV */
419 u16 lo; /* lower 16 bits of IV */
420 } rxiv;
421 u32 pad_4[2];
422 u8 ea[ETH_ALEN]; /* per station */
423};
424
425/*
426 * dongle requires same struct as above but with fields in little endian order
427 */
428struct brcmf_wsec_key_le {
429 __le32 index; /* key index */
430 __le32 len; /* key length */
431 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
432 __le32 pad_1[18];
433 __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
434 __le32 flags; /* misc flags */
435 __le32 pad_2[3];
436 __le32 iv_initialized; /* has IV been initialized already? */
437 __le32 pad_3;
438 /* Rx IV */
439 struct {
440 __le32 hi; /* upper 32 bits of IV */
441 __le16 lo; /* lower 16 bits of IV */
442 } rxiv;
443 __le32 pad_4[2];
444 u8 ea[ETH_ALEN]; /* per station */
445};
446
447/* Used to get specific STA parameters */
448struct brcmf_scb_val_le {
449 __le32 val;
450 u8 ea[ETH_ALEN];
451};
452
453/* channel encoding */
454struct brcmf_channel_info_le {
455 __le32 hw_channel;
456 __le32 target_channel;
457 __le32 scan_channel;
458};
459
460struct brcmf_sta_info_le {
461 __le16 ver; /* version of this struct */
462 __le16 len; /* length in bytes of this structure */
463 __le16 cap; /* sta's advertised capabilities */
464 __le32 flags; /* flags defined below */
465 __le32 idle; /* time since data pkt rx'd from sta */
466 u8 ea[ETH_ALEN]; /* Station address */
467 __le32 count; /* # rates in this set */
468 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
469 /* w/hi bit set if basic */
470 __le32 in; /* seconds elapsed since associated */
471 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
472 __le32 tx_pkts; /* # of packets transmitted */
473 __le32 tx_failures; /* # of packets failed */
474 __le32 rx_ucast_pkts; /* # of unicast packets received */
475 __le32 rx_mcast_pkts; /* # of multicast packets received */
476 __le32 tx_rate; /* Rate of last successful tx frame */
477 __le32 rx_rate; /* Rate of last successful rx frame */
478 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
479 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
480};
481
482struct brcmf_chanspec_list {
483 __le32 count; /* # of entries */
484 __le32 element[1]; /* variable length uint32 list */
485};
486 46
487/* 47/* Length of firmware version string stored for
488 * WLC_E_PROBRESP_MSG 48 * ethtool driver info which uses 32 bytes as well.
489 * WLC_E_P2P_PROBREQ_MSG
490 * WLC_E_ACTION_FRAME_RX
491 */ 49 */
492struct brcmf_rx_mgmt_data { 50#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
493 __be16 version;
494 __be16 chanspec;
495 __be32 rssi;
496 __be32 mactime;
497 __be32 rate;
498};
499 51
500/* Bus independent dongle command */ 52/* Bus independent dongle command */
501struct brcmf_dcmd { 53struct brcmf_dcmd {
@@ -535,7 +87,7 @@ struct brcmf_fws_info; /* firmware signalling info */
535struct brcmf_pub { 87struct brcmf_pub {
536 /* Linkage ponters */ 88 /* Linkage ponters */
537 struct brcmf_bus *bus_if; 89 struct brcmf_bus *bus_if;
538 struct brcmf_proto *prot; 90 struct brcmf_proto *proto;
539 struct brcmf_cfg80211_info *config; 91 struct brcmf_cfg80211_info *config;
540 92
541 /* Internal brcmf items */ 93 /* Internal brcmf items */
@@ -544,7 +96,7 @@ struct brcmf_pub {
544 u8 wme_dp; /* wme discard priority */ 96 u8 wme_dp; /* wme discard priority */
545 97
546 /* Dongle media info */ 98 /* Dongle media info */
547 unsigned long drv_version; /* Version of dongle-resident driver */ 99 char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
548 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ 100 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
549 101
550 /* Multicast data packets sent to dongle */ 102 /* Multicast data packets sent to dongle */
@@ -566,14 +118,6 @@ struct brcmf_pub {
566#endif 118#endif
567}; 119};
568 120
569struct brcmf_if_event {
570 u8 ifidx;
571 u8 action;
572 u8 flags;
573 u8 bssidx;
574 u8 role;
575};
576
577/* forward declarations */ 121/* forward declarations */
578struct brcmf_cfg80211_vif; 122struct brcmf_cfg80211_vif;
579struct brcmf_fws_mac_descriptor; 123struct brcmf_fws_mac_descriptor;
@@ -635,16 +179,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
635/* Return pointer to interface name */ 179/* Return pointer to interface name */
636char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 180char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
637 181
638/* Query dongle */
639int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
640 void *buf, uint len);
641int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
642 void *buf, uint len);
643
644/* Remove any protocol-specific data header. */
645int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
646 struct sk_buff *rxp);
647
648int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); 182int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
649struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, 183struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
650 char *name, u8 *mac_addr); 184 char *name, u8 *mac_addr);
@@ -655,4 +189,7 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp);
655void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, 189void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
656 bool success); 190 bool success);
657 191
192/* Sets dongle media info (drv_version, mac address). */
193int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
194
658#endif /* _BRCMF_H_ */ 195#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index a6eb09e5d46f..c4535616064e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -17,13 +17,23 @@
17#ifndef _BRCMF_BUS_H_ 17#ifndef _BRCMF_BUS_H_
18#define _BRCMF_BUS_H_ 18#define _BRCMF_BUS_H_
19 19
20#include "dhd_dbg.h"
21
20/* The level of bus communication with the dongle */ 22/* The level of bus communication with the dongle */
21enum brcmf_bus_state { 23enum brcmf_bus_state {
24 BRCMF_BUS_UNKNOWN, /* Not determined yet */
25 BRCMF_BUS_NOMEDIUM, /* No medium access to dongle */
22 BRCMF_BUS_DOWN, /* Not ready for frame transfers */ 26 BRCMF_BUS_DOWN, /* Not ready for frame transfers */
23 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ 27 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
24 BRCMF_BUS_DATA /* Ready for frame transfers */ 28 BRCMF_BUS_DATA /* Ready for frame transfers */
25}; 29};
26 30
31/* The level of bus communication with the dongle */
32enum brcmf_bus_protocol_type {
33 BRCMF_PROTO_BCDC,
34 BRCMF_PROTO_MSGBUF
35};
36
27struct brcmf_bus_dcmd { 37struct brcmf_bus_dcmd {
28 char *name; 38 char *name;
29 char *param; 39 char *param;
@@ -34,6 +44,7 @@ struct brcmf_bus_dcmd {
34/** 44/**
35 * struct brcmf_bus_ops - bus callback operations. 45 * struct brcmf_bus_ops - bus callback operations.
36 * 46 *
47 * @preinit: execute bus/device specific dongle init commands (optional).
37 * @init: prepare for communication with dongle. 48 * @init: prepare for communication with dongle.
38 * @stop: clear pending frames, disable data flow. 49 * @stop: clear pending frames, disable data flow.
39 * @txdata: send a data frame to the dongle. When the data 50 * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +62,7 @@ struct brcmf_bus_dcmd {
51 * indicated otherwise these callbacks are mandatory. 62 * indicated otherwise these callbacks are mandatory.
52 */ 63 */
53struct brcmf_bus_ops { 64struct brcmf_bus_ops {
65 int (*preinit)(struct device *dev);
54 int (*init)(struct device *dev); 66 int (*init)(struct device *dev);
55 void (*stop)(struct device *dev); 67 void (*stop)(struct device *dev);
56 int (*txdata)(struct device *dev, struct sk_buff *skb); 68 int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -63,6 +75,7 @@ struct brcmf_bus_ops {
63 * struct brcmf_bus - interface structure between common and bus layer 75 * struct brcmf_bus - interface structure between common and bus layer
64 * 76 *
65 * @bus_priv: pointer to private bus device. 77 * @bus_priv: pointer to private bus device.
78 * @proto_type: protocol type, bcdc or msgbuf
66 * @dev: device pointer of bus device. 79 * @dev: device pointer of bus device.
67 * @drvr: public driver information. 80 * @drvr: public driver information.
68 * @state: operational state of the bus interface. 81 * @state: operational state of the bus interface.
@@ -78,6 +91,7 @@ struct brcmf_bus {
78 struct brcmf_sdio_dev *sdio; 91 struct brcmf_sdio_dev *sdio;
79 struct brcmf_usbdev *usb; 92 struct brcmf_usbdev *usb;
80 } bus_priv; 93 } bus_priv;
94 enum brcmf_bus_protocol_type proto_type;
81 struct device *dev; 95 struct device *dev;
82 struct brcmf_pub *drvr; 96 struct brcmf_pub *drvr;
83 enum brcmf_bus_state state; 97 enum brcmf_bus_state state;
@@ -85,7 +99,6 @@ struct brcmf_bus {
85 unsigned long tx_realloc; 99 unsigned long tx_realloc;
86 u32 chip; 100 u32 chip;
87 u32 chiprev; 101 u32 chiprev;
88 struct list_head dcmd_list;
89 102
90 struct brcmf_bus_ops *ops; 103 struct brcmf_bus_ops *ops;
91}; 104};
@@ -93,6 +106,13 @@ struct brcmf_bus {
93/* 106/*
94 * callback wrappers 107 * callback wrappers
95 */ 108 */
109static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
110{
111 if (!bus->ops->preinit)
112 return 0;
113 return bus->ops->preinit(bus->dev);
114}
115
96static inline int brcmf_bus_init(struct brcmf_bus *bus) 116static inline int brcmf_bus_init(struct brcmf_bus *bus)
97{ 117{
98 return bus->ops->init(bus->dev); 118 return bus->ops->init(bus->dev);
@@ -128,6 +148,23 @@ struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus)
128 148
129 return bus->ops->gettxq(bus->dev); 149 return bus->ops->gettxq(bus->dev);
130} 150}
151
152static inline bool brcmf_bus_ready(struct brcmf_bus *bus)
153{
154 return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA;
155}
156
157static inline void brcmf_bus_change_state(struct brcmf_bus *bus,
158 enum brcmf_bus_state new_state)
159{
160 /* NOMEDIUM is permanent */
161 if (bus->state == BRCMF_BUS_NOMEDIUM)
162 return;
163
164 brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state);
165 bus->state = new_state;
166}
167
131/* 168/*
132 * interface functions from common layer 169 * interface functions from common layer
133 */ 170 */
@@ -139,7 +176,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
139void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); 176void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
140 177
141/* Indication from bus module regarding presence/insertion of dongle. */ 178/* Indication from bus module regarding presence/insertion of dongle. */
142int brcmf_attach(uint bus_hdrlen, struct device *dev); 179int brcmf_attach(struct device *dev);
143/* Indication from bus module regarding removal/absence of dongle */ 180/* Indication from bus module regarding removal/absence of dongle */
144void brcmf_detach(struct device *dev); 181void brcmf_detach(struct device *dev);
145/* Indication from bus module that dongle should be reset */ 182/* Indication from bus module that dongle should be reset */
@@ -151,6 +188,9 @@ void brcmf_txflowblock(struct device *dev, bool state);
151void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 188void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
152 189
153int brcmf_bus_start(struct device *dev); 190int brcmf_bus_start(struct device *dev);
191s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
192 u32 len);
193void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
154 194
155#ifdef CONFIG_BRCMFMAC_SDIO 195#ifdef CONFIG_BRCMFMAC_SDIO
156void brcmf_sdio_exit(void); 196void brcmf_sdio_exit(void);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
deleted file mode 100644
index dd85401063cb..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ /dev/null
@@ -1,392 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*******************************************************************************
18 * Communicates with the dongle by using dcmd codes.
19 * For certain dcmd codes, the dongle interprets string data from the host.
20 ******************************************************************************/
21
22#include <linux/types.h>
23#include <linux/netdevice.h>
24
25#include <brcmu_utils.h>
26#include <brcmu_wifi.h>
27
28#include "dhd.h"
29#include "dhd_proto.h"
30#include "dhd_bus.h"
31#include "fwsignal.h"
32#include "dhd_dbg.h"
33#include "tracepoint.h"
34
35struct brcmf_proto_cdc_dcmd {
36 __le32 cmd; /* dongle command value */
37 __le32 len; /* lower 16: output buflen;
38 * upper 16: input buflen (excludes header) */
39 __le32 flags; /* flag defns given below */
40 __le32 status; /* status code returned from the device */
41};
42
43/* Max valid buffer size that can be sent to the dongle */
44#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
45
46/* CDC flag definitions */
47#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
48#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
49#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
50#define CDC_DCMD_IF_SHIFT 12
51#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
52#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
53#define CDC_DCMD_ID(flags) \
54 (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
55
56/*
57 * BDC header - Broadcom specific extension of CDC.
58 * Used on data packets to convey priority across USB.
59 */
60#define BDC_HEADER_LEN 4
61#define BDC_PROTO_VER 2 /* Protocol version */
62#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
63#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
64#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
65#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
66#define BDC_PRIORITY_MASK 0x7
67#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
68#define BDC_FLAG2_IF_SHIFT 0
69
70#define BDC_GET_IF_IDX(hdr) \
71 ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
72#define BDC_SET_IF_IDX(hdr, idx) \
73 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
74 ((idx) << BDC_FLAG2_IF_SHIFT)))
75
76/**
77 * struct brcmf_proto_bdc_header - BDC header format
78 *
79 * @flags: flags contain protocol and checksum info.
80 * @priority: 802.1d priority and USB flow control info (bit 4:7).
81 * @flags2: additional flags containing dongle interface index.
82 * @data_offset: start of packet data. header is following by firmware signals.
83 */
84struct brcmf_proto_bdc_header {
85 u8 flags;
86 u8 priority;
87 u8 flags2;
88 u8 data_offset;
89};
90
91/*
92 * maximum length of firmware signal data between
93 * the BDC header and packet data in the tx path.
94 */
95#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
96
97#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
98#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
99 * (amount of header tha might be added)
100 * plus any space that might be needed
101 * for bus alignment padding.
102 */
103#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for
104 * round off at the end of buffer
105 * Currently is SDIO
106 */
107
108struct brcmf_proto {
109 u16 reqid;
110 u8 bus_header[BUS_HEADER_LEN];
111 struct brcmf_proto_cdc_dcmd msg;
112 unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
113};
114
115static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
116{
117 struct brcmf_proto *prot = drvr->prot;
118 int len = le32_to_cpu(prot->msg.len) +
119 sizeof(struct brcmf_proto_cdc_dcmd);
120
121 brcmf_dbg(CDC, "Enter\n");
122
123 /* NOTE : cdc->msg.len holds the desired length of the buffer to be
124 * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
125 * is actually sent to the dongle
126 */
127 if (len > CDC_MAX_MSG_SIZE)
128 len = CDC_MAX_MSG_SIZE;
129
130 /* Send request */
131 return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len);
132}
133
134static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
135{
136 int ret;
137 struct brcmf_proto *prot = drvr->prot;
138
139 brcmf_dbg(CDC, "Enter\n");
140 len += sizeof(struct brcmf_proto_cdc_dcmd);
141 do {
142 ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
143 len);
144 if (ret < 0)
145 break;
146 } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
147
148 return ret;
149}
150
151int
152brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
153 void *buf, uint len)
154{
155 struct brcmf_proto *prot = drvr->prot;
156 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
157 void *info;
158 int ret = 0, retries = 0;
159 u32 id, flags;
160
161 brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
162
163 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
164
165 msg->cmd = cpu_to_le32(cmd);
166 msg->len = cpu_to_le32(len);
167 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
168 flags = (flags & ~CDC_DCMD_IF_MASK) |
169 (ifidx << CDC_DCMD_IF_SHIFT);
170 msg->flags = cpu_to_le32(flags);
171
172 if (buf)
173 memcpy(prot->buf, buf, len);
174
175 ret = brcmf_proto_cdc_msg(drvr);
176 if (ret < 0) {
177 brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n",
178 ret);
179 goto done;
180 }
181
182retry:
183 /* wait for interrupt and get first fragment */
184 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
185 if (ret < 0)
186 goto done;
187
188 flags = le32_to_cpu(msg->flags);
189 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
190
191 if ((id < prot->reqid) && (++retries < RETRIES))
192 goto retry;
193 if (id != prot->reqid) {
194 brcmf_err("%s: unexpected request id %d (expected %d)\n",
195 brcmf_ifname(drvr, ifidx), id, prot->reqid);
196 ret = -EINVAL;
197 goto done;
198 }
199
200 /* Check info buffer */
201 info = (void *)&msg[1];
202
203 /* Copy info buffer */
204 if (buf) {
205 if (ret < (int)len)
206 len = ret;
207 memcpy(buf, info, len);
208 }
209
210 /* Check the ERROR flag */
211 if (flags & CDC_DCMD_ERROR)
212 ret = le32_to_cpu(msg->status);
213
214done:
215 return ret;
216}
217
218int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
219 void *buf, uint len)
220{
221 struct brcmf_proto *prot = drvr->prot;
222 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
223 int ret = 0;
224 u32 flags, id;
225
226 brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
227
228 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
229
230 msg->cmd = cpu_to_le32(cmd);
231 msg->len = cpu_to_le32(len);
232 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
233 flags = (flags & ~CDC_DCMD_IF_MASK) |
234 (ifidx << CDC_DCMD_IF_SHIFT);
235 msg->flags = cpu_to_le32(flags);
236
237 if (buf)
238 memcpy(prot->buf, buf, len);
239
240 ret = brcmf_proto_cdc_msg(drvr);
241 if (ret < 0)
242 goto done;
243
244 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
245 if (ret < 0)
246 goto done;
247
248 flags = le32_to_cpu(msg->flags);
249 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
250
251 if (id != prot->reqid) {
252 brcmf_err("%s: unexpected request id %d (expected %d)\n",
253 brcmf_ifname(drvr, ifidx), id, prot->reqid);
254 ret = -EINVAL;
255 goto done;
256 }
257
258 /* Check the ERROR flag */
259 if (flags & CDC_DCMD_ERROR)
260 ret = le32_to_cpu(msg->status);
261
262done:
263 return ret;
264}
265
266static bool pkt_sum_needed(struct sk_buff *skb)
267{
268 return skb->ip_summed == CHECKSUM_PARTIAL;
269}
270
271static void pkt_set_sum_good(struct sk_buff *skb, bool x)
272{
273 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
274}
275
276void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
277 struct sk_buff *pktbuf)
278{
279 struct brcmf_proto_bdc_header *h;
280
281 brcmf_dbg(CDC, "Enter\n");
282
283 /* Push BDC header used to convey priority for buses that don't */
284 skb_push(pktbuf, BDC_HEADER_LEN);
285
286 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
287
288 h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
289 if (pkt_sum_needed(pktbuf))
290 h->flags |= BDC_FLAG_SUM_NEEDED;
291
292 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
293 h->flags2 = 0;
294 h->data_offset = offset;
295 BDC_SET_IF_IDX(h, ifidx);
296 trace_brcmf_bdchdr(pktbuf->data);
297}
298
299int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
300 struct sk_buff *pktbuf)
301{
302 struct brcmf_proto_bdc_header *h;
303
304 brcmf_dbg(CDC, "Enter\n");
305
306 /* Pop BDC header used to convey priority for buses that don't */
307
308 if (pktbuf->len <= BDC_HEADER_LEN) {
309 brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
310 pktbuf->len, BDC_HEADER_LEN);
311 return -EBADE;
312 }
313
314 trace_brcmf_bdchdr(pktbuf->data);
315 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
316
317 *ifidx = BDC_GET_IF_IDX(h);
318 if (*ifidx >= BRCMF_MAX_IFS) {
319 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
320 return -EBADE;
321 }
322 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
323 * events this is easy because it contains the bssidx which maps
324 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
325 * bssidx 1 is used for p2p0 and no data can be received or
326 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
327 */
328 if (*ifidx)
329 (*ifidx)++;
330
331 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
332 BDC_PROTO_VER) {
333 brcmf_err("%s: non-BDC packet received, flags 0x%x\n",
334 brcmf_ifname(drvr, *ifidx), h->flags);
335 return -EBADE;
336 }
337
338 if (h->flags & BDC_FLAG_SUM_GOOD) {
339 brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
340 brcmf_ifname(drvr, *ifidx), h->flags);
341 pkt_set_sum_good(pktbuf, true);
342 }
343
344 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
345
346 skb_pull(pktbuf, BDC_HEADER_LEN);
347 if (do_fws)
348 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
349 else
350 skb_pull(pktbuf, h->data_offset << 2);
351
352 if (pktbuf->len == 0)
353 return -ENODATA;
354 return 0;
355}
356
357int brcmf_proto_attach(struct brcmf_pub *drvr)
358{
359 struct brcmf_proto *cdc;
360
361 cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
362 if (!cdc)
363 goto fail;
364
365 /* ensure that the msg buf directly follows the cdc msg struct */
366 if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
367 brcmf_err("struct brcmf_proto is not correctly defined\n");
368 goto fail;
369 }
370
371 drvr->prot = cdc;
372 drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
373 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
374 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
375 return 0;
376
377fail:
378 kfree(cdc);
379 return -ENOMEM;
380}
381
382/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
383void brcmf_proto_detach(struct brcmf_pub *drvr)
384{
385 kfree(drvr->prot);
386 drvr->prot = NULL;
387}
388
389void brcmf_proto_stop(struct brcmf_pub *drvr)
390{
391 /* Nothing to do for CDC */
392}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 9431af2465f3..6a8983a1fb9c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -21,9 +21,9 @@
21#include <brcmu_utils.h> 21#include <brcmu_utils.h>
22#include "dhd.h" 22#include "dhd.h"
23#include "dhd_bus.h" 23#include "dhd_bus.h"
24#include "dhd_proto.h"
25#include "dhd_dbg.h" 24#include "dhd_dbg.h"
26#include "fwil.h" 25#include "fwil.h"
26#include "fwil_types.h"
27#include "tracepoint.h" 27#include "tracepoint.h"
28 28
29#define PKTFILTER_BUF_SIZE 128 29#define PKTFILTER_BUF_SIZE 128
@@ -32,15 +32,6 @@
32#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 32#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
33#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" 33#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
34 34
35#ifdef DEBUG
36static const char brcmf_version[] =
37 "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
38 __DATE__ " at " __TIME__;
39#else
40static const char brcmf_version[] =
41 "Dongle Host Driver, version " BRCMF_VERSION_STR;
42#endif
43
44 35
45bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 36bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
46 struct sk_buff *pkt, int prec) 37 struct sk_buff *pkt, int prec)
@@ -257,8 +248,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
257 u8 buf[BRCMF_DCMD_SMLEN]; 248 u8 buf[BRCMF_DCMD_SMLEN];
258 char *ptr; 249 char *ptr;
259 s32 err; 250 s32 err;
260 struct brcmf_bus_dcmd *cmdlst;
261 struct list_head *cur, *q;
262 251
263 /* retreive mac address */ 252 /* retreive mac address */
264 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, 253 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -281,9 +270,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
281 } 270 }
282 ptr = (char *)buf; 271 ptr = (char *)buf;
283 strsep(&ptr, "\n"); 272 strsep(&ptr, "\n");
273
284 /* Print fw version info */ 274 /* Print fw version info */
285 brcmf_err("Firmware version = %s\n", buf); 275 brcmf_err("Firmware version = %s\n", buf);
286 276
277 /* locate firmware version number for ethtool */
278 ptr = strrchr(buf, ' ') + 1;
279 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
280
287 /* 281 /*
288 * Setup timeout if Beacons are lost and roam is off to report 282 * Setup timeout if Beacons are lost and roam is off to report
289 * link down 283 * link down
@@ -342,17 +336,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
342 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, 336 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
343 0, true); 337 0, true);
344 338
345 /* set bus specific command if there is any */ 339 /* do bus specific preinit here */
346 list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { 340 err = brcmf_bus_preinit(ifp->drvr->bus_if);
347 cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
348 if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
349 brcmf_fil_iovar_data_set(ifp, cmdlst->name,
350 cmdlst->param,
351 cmdlst->param_len);
352 }
353 list_del(cur);
354 kfree(cmdlst);
355 }
356done: 341done:
357 return err; 342 return err;
358} 343}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 0f9e9057e7dd..03fe8aca4d32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -22,7 +22,6 @@
22#include "dhd.h" 22#include "dhd.h"
23#include "dhd_bus.h" 23#include "dhd_bus.h"
24#include "dhd_dbg.h" 24#include "dhd_dbg.h"
25#include "tracepoint.h"
26 25
27static struct dentry *root_folder; 26static struct dentry *root_folder;
28 27
@@ -42,6 +41,40 @@ void brcmf_debugfs_exit(void)
42 root_folder = NULL; 41 root_folder = NULL;
43} 42}
44 43
44static
45ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
46 size_t count, loff_t *ppos)
47{
48 struct brcmf_pub *drvr = f->private_data;
49 struct brcmf_bus *bus = drvr->bus_if;
50 char buf[40];
51 int res;
52
53 /* only allow read from start */
54 if (*ppos > 0)
55 return 0;
56
57 res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
58 bus->chip, bus->chip, bus->chiprev);
59 return simple_read_from_buffer(data, count, ppos, buf, res);
60}
61
62static const struct file_operations brcmf_debugfs_chipinfo_ops = {
63 .owner = THIS_MODULE,
64 .open = simple_open,
65 .read = brcmf_debugfs_chipinfo_read
66};
67
68static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
69{
70 struct dentry *dentry = drvr->dbgfs_dir;
71
72 if (!IS_ERR_OR_NULL(dentry))
73 debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
74 &brcmf_debugfs_chipinfo_ops);
75 return 0;
76}
77
45int brcmf_debugfs_attach(struct brcmf_pub *drvr) 78int brcmf_debugfs_attach(struct brcmf_pub *drvr)
46{ 79{
47 struct device *dev = drvr->bus_if->dev; 80 struct device *dev = drvr->bus_if->dev;
@@ -50,6 +83,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
50 return -ENODEV; 83 return -ENODEV;
51 84
52 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 85 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
86 brcmf_debugfs_create_chipinfo(drvr);
53 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 87 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
54} 88}
55 89
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index 0af1f5dc583a..ef52ed7abc69 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -33,7 +33,7 @@
33#define BRCMF_USB_VAL 0x00002000 33#define BRCMF_USB_VAL 0x00002000
34#define BRCMF_SCAN_VAL 0x00004000 34#define BRCMF_SCAN_VAL 0x00004000
35#define BRCMF_CONN_VAL 0x00008000 35#define BRCMF_CONN_VAL 0x00008000
36#define BRCMF_CDC_VAL 0x00010000 36#define BRCMF_BCDC_VAL 0x00010000
37#define BRCMF_SDIO_VAL 0x00020000 37#define BRCMF_SDIO_VAL 0x00020000
38 38
39/* set default print format */ 39/* set default print format */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 64e9cff241b9..d4d966beb840 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -24,13 +24,13 @@
24 24
25#include "dhd.h" 25#include "dhd.h"
26#include "dhd_bus.h" 26#include "dhd_bus.h"
27#include "dhd_proto.h"
28#include "dhd_dbg.h" 27#include "dhd_dbg.h"
29#include "fwil_types.h" 28#include "fwil_types.h"
30#include "p2p.h" 29#include "p2p.h"
31#include "wl_cfg80211.h" 30#include "wl_cfg80211.h"
32#include "fwil.h" 31#include "fwil.h"
33#include "fwsignal.h" 32#include "fwsignal.h"
33#include "proto.h"
34 34
35MODULE_AUTHOR("Broadcom Corporation"); 35MODULE_AUTHOR("Broadcom Corporation");
36MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); 36MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -592,28 +592,6 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
592 return &ifp->stats; 592 return &ifp->stats;
593} 593}
594 594
595/*
596 * Set current toe component enables in toe_ol iovar,
597 * and set toe global enable iovar
598 */
599static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
600{
601 s32 err;
602
603 err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
604 if (err < 0) {
605 brcmf_err("Setting toe_ol failed, %d\n", err);
606 return err;
607 }
608
609 err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
610 if (err < 0)
611 brcmf_err("Setting toe failed, %d\n", err);
612
613 return err;
614
615}
616
617static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 595static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
618 struct ethtool_drvinfo *info) 596 struct ethtool_drvinfo *info)
619{ 597{
@@ -621,8 +599,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
621 struct brcmf_pub *drvr = ifp->drvr; 599 struct brcmf_pub *drvr = ifp->drvr;
622 600
623 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 601 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
624 snprintf(info->version, sizeof(info->version), "%lu", 602 snprintf(info->version, sizeof(info->version), "n/a");
625 drvr->drv_version); 603 strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
626 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev), 604 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
627 sizeof(info->bus_info)); 605 sizeof(info->bus_info));
628} 606}
@@ -631,124 +609,6 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
631 .get_drvinfo = brcmf_ethtool_get_drvinfo, 609 .get_drvinfo = brcmf_ethtool_get_drvinfo,
632}; 610};
633 611
634static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
635{
636 struct brcmf_pub *drvr = ifp->drvr;
637 struct ethtool_drvinfo info;
638 char drvname[sizeof(info.driver)];
639 u32 cmd;
640 struct ethtool_value edata;
641 u32 toe_cmpnt, csum_dir;
642 int ret;
643
644 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
645
646 /* all ethtool calls start with a cmd word */
647 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
648 return -EFAULT;
649
650 switch (cmd) {
651 case ETHTOOL_GDRVINFO:
652 /* Copy out any request driver name */
653 if (copy_from_user(&info, uaddr, sizeof(info)))
654 return -EFAULT;
655 strncpy(drvname, info.driver, sizeof(info.driver));
656 drvname[sizeof(info.driver) - 1] = '\0';
657
658 /* clear struct for return */
659 memset(&info, 0, sizeof(info));
660 info.cmd = cmd;
661
662 /* if requested, identify ourselves */
663 if (strcmp(drvname, "?dhd") == 0) {
664 sprintf(info.driver, "dhd");
665 strcpy(info.version, BRCMF_VERSION_STR);
666 }
667 /* report dongle driver type */
668 else
669 sprintf(info.driver, "wl");
670
671 sprintf(info.version, "%lu", drvr->drv_version);
672 if (copy_to_user(uaddr, &info, sizeof(info)))
673 return -EFAULT;
674 brcmf_dbg(TRACE, "given %*s, returning %s\n",
675 (int)sizeof(drvname), drvname, info.driver);
676 break;
677
678 /* Get toe offload components from dongle */
679 case ETHTOOL_GRXCSUM:
680 case ETHTOOL_GTXCSUM:
681 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
682 if (ret < 0)
683 return ret;
684
685 csum_dir =
686 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
687
688 edata.cmd = cmd;
689 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
690
691 if (copy_to_user(uaddr, &edata, sizeof(edata)))
692 return -EFAULT;
693 break;
694
695 /* Set toe offload components in dongle */
696 case ETHTOOL_SRXCSUM:
697 case ETHTOOL_STXCSUM:
698 if (copy_from_user(&edata, uaddr, sizeof(edata)))
699 return -EFAULT;
700
701 /* Read the current settings, update and write back */
702 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
703 if (ret < 0)
704 return ret;
705
706 csum_dir =
707 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
708
709 if (edata.data != 0)
710 toe_cmpnt |= csum_dir;
711 else
712 toe_cmpnt &= ~csum_dir;
713
714 ret = brcmf_toe_set(ifp, toe_cmpnt);
715 if (ret < 0)
716 return ret;
717
718 /* If setting TX checksum mode, tell Linux the new mode */
719 if (cmd == ETHTOOL_STXCSUM) {
720 if (edata.data)
721 ifp->ndev->features |= NETIF_F_IP_CSUM;
722 else
723 ifp->ndev->features &= ~NETIF_F_IP_CSUM;
724 }
725
726 break;
727
728 default:
729 return -EOPNOTSUPP;
730 }
731
732 return 0;
733}
734
735static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
736 int cmd)
737{
738 struct brcmf_if *ifp = netdev_priv(ndev);
739 struct brcmf_pub *drvr = ifp->drvr;
740
741 brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
742
743 if (!drvr->iflist[ifp->bssidx])
744 return -1;
745
746 if (cmd == SIOCETHTOOL)
747 return brcmf_ethtool(ifp, ifr->ifr_data);
748
749 return -EOPNOTSUPP;
750}
751
752static int brcmf_netdev_stop(struct net_device *ndev) 612static int brcmf_netdev_stop(struct net_device *ndev)
753{ 613{
754 struct brcmf_if *ifp = netdev_priv(ndev); 614 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -769,7 +629,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
769 struct brcmf_pub *drvr = ifp->drvr; 629 struct brcmf_pub *drvr = ifp->drvr;
770 struct brcmf_bus *bus_if = drvr->bus_if; 630 struct brcmf_bus *bus_if = drvr->bus_if;
771 u32 toe_ol; 631 u32 toe_ol;
772 s32 ret = 0;
773 632
774 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); 633 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
775 634
@@ -788,21 +647,20 @@ static int brcmf_netdev_open(struct net_device *ndev)
788 else 647 else
789 ndev->features &= ~NETIF_F_IP_CSUM; 648 ndev->features &= ~NETIF_F_IP_CSUM;
790 649
791 /* Allow transmit calls */
792 netif_start_queue(ndev);
793 if (brcmf_cfg80211_up(ndev)) { 650 if (brcmf_cfg80211_up(ndev)) {
794 brcmf_err("failed to bring up cfg80211\n"); 651 brcmf_err("failed to bring up cfg80211\n");
795 return -1; 652 return -EIO;
796 } 653 }
797 654
798 return ret; 655 /* Allow transmit calls */
656 netif_start_queue(ndev);
657 return 0;
799} 658}
800 659
801static const struct net_device_ops brcmf_netdev_ops_pri = { 660static const struct net_device_ops brcmf_netdev_ops_pri = {
802 .ndo_open = brcmf_netdev_open, 661 .ndo_open = brcmf_netdev_open,
803 .ndo_stop = brcmf_netdev_stop, 662 .ndo_stop = brcmf_netdev_stop,
804 .ndo_get_stats = brcmf_netdev_get_stats, 663 .ndo_get_stats = brcmf_netdev_get_stats,
805 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
806 .ndo_start_xmit = brcmf_netdev_start_xmit, 664 .ndo_start_xmit = brcmf_netdev_start_xmit,
807 .ndo_set_mac_address = brcmf_netdev_set_mac_address, 665 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
808 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 666 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
@@ -844,7 +702,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
844 702
845 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); 703 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
846 704
847 ndev->destructor = free_netdev; 705 ndev->destructor = brcmf_cfg80211_free_netdev;
848 return 0; 706 return 0;
849 707
850fail: 708fail:
@@ -868,13 +726,6 @@ static int brcmf_net_p2p_stop(struct net_device *ndev)
868 return brcmf_cfg80211_down(ndev); 726 return brcmf_cfg80211_down(ndev);
869} 727}
870 728
871static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
872 struct ifreq *ifr, int cmd)
873{
874 brcmf_dbg(TRACE, "Enter\n");
875 return 0;
876}
877
878static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb, 729static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
879 struct net_device *ndev) 730 struct net_device *ndev)
880{ 731{
@@ -887,7 +738,6 @@ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
887static const struct net_device_ops brcmf_netdev_ops_p2p = { 738static const struct net_device_ops brcmf_netdev_ops_p2p = {
888 .ndo_open = brcmf_net_p2p_open, 739 .ndo_open = brcmf_net_p2p_open,
889 .ndo_stop = brcmf_net_p2p_stop, 740 .ndo_stop = brcmf_net_p2p_stop,
890 .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
891 .ndo_start_xmit = brcmf_net_p2p_start_xmit 741 .ndo_start_xmit = brcmf_net_p2p_start_xmit
892}; 742};
893 743
@@ -1009,14 +859,12 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
1009 } 859 }
1010 /* unregister will take care of freeing it */ 860 /* unregister will take care of freeing it */
1011 unregister_netdev(ifp->ndev); 861 unregister_netdev(ifp->ndev);
1012 if (bssidx == 0)
1013 brcmf_cfg80211_detach(drvr->config);
1014 } else { 862 } else {
1015 kfree(ifp); 863 kfree(ifp);
1016 } 864 }
1017} 865}
1018 866
1019int brcmf_attach(uint bus_hdrlen, struct device *dev) 867int brcmf_attach(struct device *dev)
1020{ 868{
1021 struct brcmf_pub *drvr = NULL; 869 struct brcmf_pub *drvr = NULL;
1022 int ret = 0; 870 int ret = 0;
@@ -1031,7 +879,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
1031 mutex_init(&drvr->proto_block); 879 mutex_init(&drvr->proto_block);
1032 880
1033 /* Link to bus module */ 881 /* Link to bus module */
1034 drvr->hdrlen = bus_hdrlen; 882 drvr->hdrlen = 0;
1035 drvr->bus_if = dev_get_drvdata(dev); 883 drvr->bus_if = dev_get_drvdata(dev);
1036 drvr->bus_if->drvr = drvr; 884 drvr->bus_if->drvr = drvr;
1037 885
@@ -1048,8 +896,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
1048 /* attach firmware event handler */ 896 /* attach firmware event handler */
1049 brcmf_fweh_attach(drvr); 897 brcmf_fweh_attach(drvr);
1050 898
1051 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
1052
1053 return ret; 899 return ret;
1054 900
1055fail: 901fail:
@@ -1088,7 +934,7 @@ int brcmf_bus_start(struct device *dev)
1088 p2p_ifp = NULL; 934 p2p_ifp = NULL;
1089 935
1090 /* signal bus ready */ 936 /* signal bus ready */
1091 bus_if->state = BRCMF_BUS_DATA; 937 brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA);
1092 938
1093 /* Bus is ready, do any initialization */ 939 /* Bus is ready, do any initialization */
1094 ret = brcmf_c_preinit_dcmds(ifp); 940 ret = brcmf_c_preinit_dcmds(ifp);
@@ -1115,8 +961,7 @@ int brcmf_bus_start(struct device *dev)
1115fail: 961fail:
1116 if (ret < 0) { 962 if (ret < 0) {
1117 brcmf_err("failed: %d\n", ret); 963 brcmf_err("failed: %d\n", ret);
1118 if (drvr->config) 964 brcmf_cfg80211_detach(drvr->config);
1119 brcmf_cfg80211_detach(drvr->config);
1120 if (drvr->fws) { 965 if (drvr->fws) {
1121 brcmf_fws_del_interface(ifp); 966 brcmf_fws_del_interface(ifp);
1122 brcmf_fws_deinit(drvr); 967 brcmf_fws_deinit(drvr);
@@ -1138,14 +983,21 @@ fail:
1138 return 0; 983 return 0;
1139} 984}
1140 985
986void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
987{
988 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
989 struct brcmf_pub *drvr = bus_if->drvr;
990
991 if (drvr) {
992 drvr->hdrlen += len;
993 }
994}
995
1141static void brcmf_bus_detach(struct brcmf_pub *drvr) 996static void brcmf_bus_detach(struct brcmf_pub *drvr)
1142{ 997{
1143 brcmf_dbg(TRACE, "Enter\n"); 998 brcmf_dbg(TRACE, "Enter\n");
1144 999
1145 if (drvr) { 1000 if (drvr) {
1146 /* Stop the protocol module */
1147 brcmf_proto_stop(drvr);
1148
1149 /* Stop the bus module */ 1001 /* Stop the bus module */
1150 brcmf_bus_stop(drvr->bus_if); 1002 brcmf_bus_stop(drvr->bus_if);
1151 } 1003 }
@@ -1177,6 +1029,8 @@ void brcmf_detach(struct device *dev)
1177 /* stop firmware event handling */ 1029 /* stop firmware event handling */
1178 brcmf_fweh_detach(drvr); 1030 brcmf_fweh_detach(drvr);
1179 1031
1032 brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1033
1180 /* make sure primary interface removed last */ 1034 /* make sure primary interface removed last */
1181 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 1035 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1182 if (drvr->iflist[i]) { 1036 if (drvr->iflist[i]) {
@@ -1184,10 +1038,11 @@ void brcmf_detach(struct device *dev)
1184 brcmf_del_if(drvr, i); 1038 brcmf_del_if(drvr, i);
1185 } 1039 }
1186 1040
1041 brcmf_cfg80211_detach(drvr->config);
1042
1187 brcmf_bus_detach(drvr); 1043 brcmf_bus_detach(drvr);
1188 1044
1189 if (drvr->prot) 1045 brcmf_proto_detach(drvr);
1190 brcmf_proto_detach(drvr);
1191 1046
1192 brcmf_fws_deinit(drvr); 1047 brcmf_fws_deinit(drvr);
1193 1048
@@ -1196,6 +1051,14 @@ void brcmf_detach(struct device *dev)
1196 kfree(drvr); 1051 kfree(drvr);
1197} 1052}
1198 1053
1054s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
1055{
1056 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1057 struct brcmf_if *ifp = bus_if->drvr->iflist[0];
1058
1059 return brcmf_fil_iovar_data_set(ifp, name, data, len);
1060}
1061
1199static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp) 1062static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1200{ 1063{
1201 return atomic_read(&ifp->pend_8021x_cnt); 1064 return atomic_read(&ifp->pend_8021x_cnt);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
deleted file mode 100644
index 53c6e710f2cb..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_PROTO_H_
18#define _BRCMF_PROTO_H_
19
20/*
21 * Exported from the brcmf protocol module (brcmf_cdc)
22 */
23
24/* Linkage, sets prot link and updates hdrlen in pub */
25int brcmf_proto_attach(struct brcmf_pub *drvr);
26
27/* Unlink, frees allocated protocol memory (including brcmf_proto) */
28void brcmf_proto_detach(struct brcmf_pub *drvr);
29
30/* Stop protocol: sync w/dongle state. */
31void brcmf_proto_stop(struct brcmf_pub *drvr);
32
33/* Add any protocol-specific data header.
34 * Caller must reserve prot_hdrlen prepend space.
35 */
36void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
37 struct sk_buff *txp);
38
39/* Sets dongle media info (drv_version, mac address). */
40int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
41
42#endif /* _BRCMF_PROTO_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index b02953c4ade7..3e991897d7ca 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -32,6 +32,7 @@
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
34#include <linux/platform_data/brcmfmac-sdio.h> 34#include <linux/platform_data/brcmfmac-sdio.h>
35#include <linux/moduleparam.h>
35#include <asm/unaligned.h> 36#include <asm/unaligned.h>
36#include <defs.h> 37#include <defs.h>
37#include <brcmu_wifi.h> 38#include <brcmu_wifi.h>
@@ -40,6 +41,7 @@
40#include <soc.h> 41#include <soc.h>
41#include "sdio_host.h" 42#include "sdio_host.h"
42#include "sdio_chip.h" 43#include "sdio_chip.h"
44#include "nvram.h"
43 45
44#define DCMD_RESP_TIMEOUT 2000 /* In milli second */ 46#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
45 47
@@ -110,6 +112,8 @@ struct rte_console {
110#define BRCMF_TXBOUND 20 /* Default for max tx frames in 112#define BRCMF_TXBOUND 20 /* Default for max tx frames in
111 one scheduling */ 113 one scheduling */
112 114
115#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
116
113#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 117#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
114 118
115#define MEMBLOCK 2048 /* Block size used for downloading 119#define MEMBLOCK 2048 /* Block size used for downloading
@@ -257,9 +261,6 @@ struct rte_console {
257#define MAX_HDR_READ (1 << 6) 261#define MAX_HDR_READ (1 << 6)
258#define MAX_RX_DATASZ 2048 262#define MAX_RX_DATASZ 2048
259 263
260/* Maximum milliseconds to wait for F2 to come up */
261#define BRCMF_WAIT_F2RDY 3000
262
263/* Bump up limit on waiting for HT to account for first startup; 264/* Bump up limit on waiting for HT to account for first startup;
264 * if the image is doing a CRC calculation before programming the PMU 265 * if the image is doing a CRC calculation before programming the PMU
265 * for HT availability, it could take a couple hundred ms more, so 266 * for HT availability, it could take a couple hundred ms more, so
@@ -360,15 +361,15 @@ struct brcmf_sdio_hdrinfo {
360 u16 len_left; 361 u16 len_left;
361 u16 len_nxtfrm; 362 u16 len_nxtfrm;
362 u8 dat_offset; 363 u8 dat_offset;
364 bool lastfrm;
365 u16 tail_pad;
363}; 366};
364 367
365/* misc chip info needed by some of the routines */ 368/* misc chip info needed by some of the routines */
366/* Private data for SDIO bus interaction */ 369/* Private data for SDIO bus interaction */
367struct brcmf_sdio { 370struct brcmf_sdio {
368 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ 371 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
369 struct chip_info *ci; /* Chip info struct */ 372 struct brcmf_chip *ci; /* Chip info struct */
370 char *vars; /* Variables (from CIS and/or other) */
371 uint varsz; /* Size of variables buffer */
372 373
373 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ 374 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
374 375
@@ -384,7 +385,7 @@ struct brcmf_sdio {
384 u8 tx_seq; /* Transmit sequence number (next) */ 385 u8 tx_seq; /* Transmit sequence number (next) */
385 u8 tx_max; /* Maximum transmit sequence allowed */ 386 u8 tx_max; /* Maximum transmit sequence allowed */
386 387
387 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; 388 u8 *hdrbuf; /* buffer for handling rx frame */
388 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ 389 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
389 u8 rx_seq; /* Receive sequence number (expected) */ 390 u8 rx_seq; /* Receive sequence number (expected) */
390 struct brcmf_sdio_hdrinfo cur_read; 391 struct brcmf_sdio_hdrinfo cur_read;
@@ -455,6 +456,10 @@ struct brcmf_sdio {
455 bool sleeping; /* SDIO bus sleeping */ 456 bool sleeping; /* SDIO bus sleeping */
456 457
457 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 458 u8 tx_hdrlen; /* sdio bus header length for tx packet */
459 bool txglom; /* host tx glomming enable flag */
460 struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */
461 u16 head_align; /* buffer pointer alignment */
462 u16 sgentry_align; /* scatter-gather buffer alignment */
458}; 463};
459 464
460/* clkstate */ 465/* clkstate */
@@ -479,6 +484,10 @@ static const uint max_roundup = 512;
479 484
480#define ALIGNMENT 4 485#define ALIGNMENT 4
481 486
487static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
488module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
489MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
490
482enum brcmf_sdio_frmtype { 491enum brcmf_sdio_frmtype {
483 BRCMF_SDIO_FT_NORMAL, 492 BRCMF_SDIO_FT_NORMAL,
484 BRCMF_SDIO_FT_SUPER, 493 BRCMF_SDIO_FT_SUPER,
@@ -499,6 +508,10 @@ enum brcmf_sdio_frmtype {
499#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" 508#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
500#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" 509#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
501#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" 510#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
511#define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin"
512#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
513#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
514#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
502 515
503MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); 516MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
504MODULE_FIRMWARE(BCM43143_NVRAM_NAME); 517MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
@@ -514,6 +527,10 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
514MODULE_FIRMWARE(BCM4334_NVRAM_NAME); 527MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
515MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); 528MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
516MODULE_FIRMWARE(BCM4335_NVRAM_NAME); 529MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
530MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
531MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
532MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
533MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
517 534
518struct brcmf_firmware_names { 535struct brcmf_firmware_names {
519 u32 chipid; 536 u32 chipid;
@@ -537,11 +554,13 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
537 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, 554 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
538 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, 555 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
539 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 556 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
540 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) } 557 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
558 { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
559 { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
541}; 560};
542 561
543 562
544static const struct firmware *brcmf_sdbrcm_get_fw(struct brcmf_sdio *bus, 563static const struct firmware *brcmf_sdio_get_fw(struct brcmf_sdio *bus,
545 enum brcmf_firmware_type type) 564 enum brcmf_firmware_type type)
546{ 565{
547 const struct firmware *fw; 566 const struct firmware *fw;
@@ -606,8 +625,8 @@ r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
606 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 625 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
607 int ret; 626 int ret;
608 627
609 *regvar = brcmf_sdio_regrl(bus->sdiodev, 628 *regvar = brcmf_sdiod_regrl(bus->sdiodev,
610 bus->ci->c_inf[idx].base + offset, &ret); 629 bus->ci->c_inf[idx].base + offset, &ret);
611 630
612 return ret; 631 return ret;
613} 632}
@@ -618,15 +637,15 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
618 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); 637 u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
619 int ret; 638 int ret;
620 639
621 brcmf_sdio_regwl(bus->sdiodev, 640 brcmf_sdiod_regwl(bus->sdiodev,
622 bus->ci->c_inf[idx].base + reg_offset, 641 bus->ci->c_inf[idx].base + reg_offset,
623 regval, &ret); 642 regval, &ret);
624 643
625 return ret; 644 return ret;
626} 645}
627 646
628static int 647static int
629brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) 648brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
630{ 649{
631 u8 wr_val = 0, rd_val, cmp_val, bmask; 650 u8 wr_val = 0, rd_val, cmp_val, bmask;
632 int err = 0; 651 int err = 0;
@@ -636,8 +655,8 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on)
636 655
637 wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); 656 wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
638 /* 1st KSO write goes to AOS wake up core if device is asleep */ 657 /* 1st KSO write goes to AOS wake up core if device is asleep */
639 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 658 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
640 wr_val, &err); 659 wr_val, &err);
641 if (err) { 660 if (err) {
642 brcmf_err("SDIO_AOS KSO write error: %d\n", err); 661 brcmf_err("SDIO_AOS KSO write error: %d\n", err);
643 return err; 662 return err;
@@ -667,15 +686,15 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on)
667 * just one write attempt may fail, 686 * just one write attempt may fail,
668 * read it back until it matches written value 687 * read it back until it matches written value
669 */ 688 */
670 rd_val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 689 rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
671 &err); 690 &err);
672 if (((rd_val & bmask) == cmp_val) && !err) 691 if (((rd_val & bmask) == cmp_val) && !err)
673 break; 692 break;
674 brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n", 693 brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n",
675 try_cnt, MAX_KSO_ATTEMPTS, err); 694 try_cnt, MAX_KSO_ATTEMPTS, err);
676 udelay(KSO_WAIT_US); 695 udelay(KSO_WAIT_US);
677 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 696 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
678 wr_val, &err); 697 wr_val, &err);
679 } while (try_cnt++ < MAX_KSO_ATTEMPTS); 698 } while (try_cnt++ < MAX_KSO_ATTEMPTS);
680 699
681 return err; 700 return err;
@@ -686,7 +705,7 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on)
686#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) 705#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
687 706
688/* Turn backplane clock on or off */ 707/* Turn backplane clock on or off */
689static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) 708static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
690{ 709{
691 int err; 710 int err;
692 u8 clkctl, clkreq, devctl; 711 u8 clkctl, clkreq, devctl;
@@ -706,16 +725,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
706 clkreq = 725 clkreq =
707 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; 726 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
708 727
709 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 728 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
710 clkreq, &err); 729 clkreq, &err);
711 if (err) { 730 if (err) {
712 brcmf_err("HT Avail request error: %d\n", err); 731 brcmf_err("HT Avail request error: %d\n", err);
713 return -EBADE; 732 return -EBADE;
714 } 733 }
715 734
716 /* Check current status */ 735 /* Check current status */
717 clkctl = brcmf_sdio_regrb(bus->sdiodev, 736 clkctl = brcmf_sdiod_regrb(bus->sdiodev,
718 SBSDIO_FUNC1_CHIPCLKCSR, &err); 737 SBSDIO_FUNC1_CHIPCLKCSR, &err);
719 if (err) { 738 if (err) {
720 brcmf_err("HT Avail read error: %d\n", err); 739 brcmf_err("HT Avail read error: %d\n", err);
721 return -EBADE; 740 return -EBADE;
@@ -724,8 +743,8 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
724 /* Go to pending and await interrupt if appropriate */ 743 /* Go to pending and await interrupt if appropriate */
725 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { 744 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
726 /* Allow only clock-available interrupt */ 745 /* Allow only clock-available interrupt */
727 devctl = brcmf_sdio_regrb(bus->sdiodev, 746 devctl = brcmf_sdiod_regrb(bus->sdiodev,
728 SBSDIO_DEVICE_CTL, &err); 747 SBSDIO_DEVICE_CTL, &err);
729 if (err) { 748 if (err) {
730 brcmf_err("Devctl error setting CA: %d\n", 749 brcmf_err("Devctl error setting CA: %d\n",
731 err); 750 err);
@@ -733,28 +752,28 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
733 } 752 }
734 753
735 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; 754 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
736 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 755 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
737 devctl, &err); 756 devctl, &err);
738 brcmf_dbg(SDIO, "CLKCTL: set PENDING\n"); 757 brcmf_dbg(SDIO, "CLKCTL: set PENDING\n");
739 bus->clkstate = CLK_PENDING; 758 bus->clkstate = CLK_PENDING;
740 759
741 return 0; 760 return 0;
742 } else if (bus->clkstate == CLK_PENDING) { 761 } else if (bus->clkstate == CLK_PENDING) {
743 /* Cancel CA-only interrupt filter */ 762 /* Cancel CA-only interrupt filter */
744 devctl = brcmf_sdio_regrb(bus->sdiodev, 763 devctl = brcmf_sdiod_regrb(bus->sdiodev,
745 SBSDIO_DEVICE_CTL, &err); 764 SBSDIO_DEVICE_CTL, &err);
746 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 765 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
747 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 766 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
748 devctl, &err); 767 devctl, &err);
749 } 768 }
750 769
751 /* Otherwise, wait here (polling) for HT Avail */ 770 /* Otherwise, wait here (polling) for HT Avail */
752 timeout = jiffies + 771 timeout = jiffies +
753 msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); 772 msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
754 while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { 773 while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
755 clkctl = brcmf_sdio_regrb(bus->sdiodev, 774 clkctl = brcmf_sdiod_regrb(bus->sdiodev,
756 SBSDIO_FUNC1_CHIPCLKCSR, 775 SBSDIO_FUNC1_CHIPCLKCSR,
757 &err); 776 &err);
758 if (time_after(jiffies, timeout)) 777 if (time_after(jiffies, timeout))
759 break; 778 break;
760 else 779 else
@@ -787,16 +806,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
787 806
788 if (bus->clkstate == CLK_PENDING) { 807 if (bus->clkstate == CLK_PENDING) {
789 /* Cancel CA-only interrupt filter */ 808 /* Cancel CA-only interrupt filter */
790 devctl = brcmf_sdio_regrb(bus->sdiodev, 809 devctl = brcmf_sdiod_regrb(bus->sdiodev,
791 SBSDIO_DEVICE_CTL, &err); 810 SBSDIO_DEVICE_CTL, &err);
792 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 811 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
793 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 812 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
794 devctl, &err); 813 devctl, &err);
795 } 814 }
796 815
797 bus->clkstate = CLK_SDONLY; 816 bus->clkstate = CLK_SDONLY;
798 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 817 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
799 clkreq, &err); 818 clkreq, &err);
800 brcmf_dbg(SDIO, "CLKCTL: turned OFF\n"); 819 brcmf_dbg(SDIO, "CLKCTL: turned OFF\n");
801 if (err) { 820 if (err) {
802 brcmf_err("Failed access turning clock off: %d\n", 821 brcmf_err("Failed access turning clock off: %d\n",
@@ -808,7 +827,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
808} 827}
809 828
810/* Change idle/active SD state */ 829/* Change idle/active SD state */
811static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) 830static int brcmf_sdio_sdclk(struct brcmf_sdio *bus, bool on)
812{ 831{
813 brcmf_dbg(SDIO, "Enter\n"); 832 brcmf_dbg(SDIO, "Enter\n");
814 833
@@ -821,7 +840,7 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
821} 840}
822 841
823/* Transition SD and backplane clock readiness */ 842/* Transition SD and backplane clock readiness */
824static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) 843static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
825{ 844{
826#ifdef DEBUG 845#ifdef DEBUG
827 uint oldstate = bus->clkstate; 846 uint oldstate = bus->clkstate;
@@ -832,7 +851,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
832 /* Early exit if we're already there */ 851 /* Early exit if we're already there */
833 if (bus->clkstate == target) { 852 if (bus->clkstate == target) {
834 if (target == CLK_AVAIL) { 853 if (target == CLK_AVAIL) {
835 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 854 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
836 bus->activity = true; 855 bus->activity = true;
837 } 856 }
838 return 0; 857 return 0;
@@ -842,32 +861,32 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
842 case CLK_AVAIL: 861 case CLK_AVAIL:
843 /* Make sure SD clock is available */ 862 /* Make sure SD clock is available */
844 if (bus->clkstate == CLK_NONE) 863 if (bus->clkstate == CLK_NONE)
845 brcmf_sdbrcm_sdclk(bus, true); 864 brcmf_sdio_sdclk(bus, true);
846 /* Now request HT Avail on the backplane */ 865 /* Now request HT Avail on the backplane */
847 brcmf_sdbrcm_htclk(bus, true, pendok); 866 brcmf_sdio_htclk(bus, true, pendok);
848 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 867 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
849 bus->activity = true; 868 bus->activity = true;
850 break; 869 break;
851 870
852 case CLK_SDONLY: 871 case CLK_SDONLY:
853 /* Remove HT request, or bring up SD clock */ 872 /* Remove HT request, or bring up SD clock */
854 if (bus->clkstate == CLK_NONE) 873 if (bus->clkstate == CLK_NONE)
855 brcmf_sdbrcm_sdclk(bus, true); 874 brcmf_sdio_sdclk(bus, true);
856 else if (bus->clkstate == CLK_AVAIL) 875 else if (bus->clkstate == CLK_AVAIL)
857 brcmf_sdbrcm_htclk(bus, false, false); 876 brcmf_sdio_htclk(bus, false, false);
858 else 877 else
859 brcmf_err("request for %d -> %d\n", 878 brcmf_err("request for %d -> %d\n",
860 bus->clkstate, target); 879 bus->clkstate, target);
861 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 880 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
862 break; 881 break;
863 882
864 case CLK_NONE: 883 case CLK_NONE:
865 /* Make sure to remove HT request */ 884 /* Make sure to remove HT request */
866 if (bus->clkstate == CLK_AVAIL) 885 if (bus->clkstate == CLK_AVAIL)
867 brcmf_sdbrcm_htclk(bus, false, false); 886 brcmf_sdio_htclk(bus, false, false);
868 /* Now remove the SD clock */ 887 /* Now remove the SD clock */
869 brcmf_sdbrcm_sdclk(bus, false); 888 brcmf_sdio_sdclk(bus, false);
870 brcmf_sdbrcm_wd_timer(bus, 0); 889 brcmf_sdio_wd_timer(bus, 0);
871 break; 890 break;
872 } 891 }
873#ifdef DEBUG 892#ifdef DEBUG
@@ -878,7 +897,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
878} 897}
879 898
880static int 899static int
881brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) 900brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
882{ 901{
883 int err = 0; 902 int err = 0;
884 brcmf_dbg(TRACE, "Enter\n"); 903 brcmf_dbg(TRACE, "Enter\n");
@@ -901,13 +920,13 @@ brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
901 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 920 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
902 data_ok(bus))) 921 data_ok(bus)))
903 return -EBUSY; 922 return -EBUSY;
904 err = brcmf_sdbrcm_kso_control(bus, false); 923 err = brcmf_sdio_kso_control(bus, false);
905 /* disable watchdog */ 924 /* disable watchdog */
906 if (!err) 925 if (!err)
907 brcmf_sdbrcm_wd_timer(bus, 0); 926 brcmf_sdio_wd_timer(bus, 0);
908 } else { 927 } else {
909 bus->idlecount = 0; 928 bus->idlecount = 0;
910 err = brcmf_sdbrcm_kso_control(bus, true); 929 err = brcmf_sdio_kso_control(bus, true);
911 } 930 }
912 if (!err) { 931 if (!err) {
913 /* Change state */ 932 /* Change state */
@@ -925,16 +944,16 @@ end:
925 /* control clocks */ 944 /* control clocks */
926 if (sleep) { 945 if (sleep) {
927 if (!bus->sr_enabled) 946 if (!bus->sr_enabled)
928 brcmf_sdbrcm_clkctl(bus, CLK_NONE, pendok); 947 brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
929 } else { 948 } else {
930 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, pendok); 949 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
931 } 950 }
932 951
933 return err; 952 return err;
934 953
935} 954}
936 955
937static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) 956static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
938{ 957{
939 u32 intstatus = 0; 958 u32 intstatus = 0;
940 u32 hmb_data; 959 u32 hmb_data;
@@ -1010,7 +1029,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
1010 return intstatus; 1029 return intstatus;
1011} 1030}
1012 1031
1013static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) 1032static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1014{ 1033{
1015 uint retries = 0; 1034 uint retries = 0;
1016 u16 lastrbc; 1035 u16 lastrbc;
@@ -1022,18 +1041,18 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1022 rtx ? ", send NAK" : ""); 1041 rtx ? ", send NAK" : "");
1023 1042
1024 if (abort) 1043 if (abort)
1025 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 1044 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
1026 1045
1027 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 1046 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
1028 SFC_RF_TERM, &err); 1047 SFC_RF_TERM, &err);
1029 bus->sdcnt.f1regdata++; 1048 bus->sdcnt.f1regdata++;
1030 1049
1031 /* Wait until the packet has been flushed (device/FIFO stable) */ 1050 /* Wait until the packet has been flushed (device/FIFO stable) */
1032 for (lastrbc = retries = 0xffff; retries > 0; retries--) { 1051 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
1033 hi = brcmf_sdio_regrb(bus->sdiodev, 1052 hi = brcmf_sdiod_regrb(bus->sdiodev,
1034 SBSDIO_FUNC1_RFRAMEBCHI, &err); 1053 SBSDIO_FUNC1_RFRAMEBCHI, &err);
1035 lo = brcmf_sdio_regrb(bus->sdiodev, 1054 lo = brcmf_sdiod_regrb(bus->sdiodev,
1036 SBSDIO_FUNC1_RFRAMEBCLO, &err); 1055 SBSDIO_FUNC1_RFRAMEBCLO, &err);
1037 bus->sdcnt.f1regdata += 2; 1056 bus->sdcnt.f1regdata += 2;
1038 1057
1039 if ((hi == 0) && (lo == 0)) 1058 if ((hi == 0) && (lo == 0))
@@ -1063,14 +1082,10 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1063 1082
1064 /* Clear partial in any case */ 1083 /* Clear partial in any case */
1065 bus->cur_read.len = 0; 1084 bus->cur_read.len = 0;
1066
1067 /* If we can't reach the device, signal failure */
1068 if (err)
1069 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
1070} 1085}
1071 1086
1072/* return total length of buffer chain */ 1087/* return total length of buffer chain */
1073static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) 1088static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
1074{ 1089{
1075 struct sk_buff *p; 1090 struct sk_buff *p;
1076 uint total; 1091 uint total;
@@ -1081,7 +1096,7 @@ static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
1081 return total; 1096 return total;
1082} 1097}
1083 1098
1084static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) 1099static void brcmf_sdio_free_glom(struct brcmf_sdio *bus)
1085{ 1100{
1086 struct sk_buff *cur, *next; 1101 struct sk_buff *cur, *next;
1087 1102
@@ -1097,10 +1112,18 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1097 * host and WiFi dongle which contains information needed for SDIO core and 1112 * host and WiFi dongle which contains information needed for SDIO core and
1098 * firmware 1113 * firmware
1099 * 1114 *
1100 * It consists of 2 parts: hw header and software header 1115 * It consists of 3 parts: hardware header, hardware extension header and
1116 * software header
1101 * hardware header (frame tag) - 4 bytes 1117 * hardware header (frame tag) - 4 bytes
1102 * Byte 0~1: Frame length 1118 * Byte 0~1: Frame length
1103 * Byte 2~3: Checksum, bit-wise inverse of frame length 1119 * Byte 2~3: Checksum, bit-wise inverse of frame length
1120 * hardware extension header - 8 bytes
1121 * Tx glom mode only, N/A for Rx or normal Tx
1122 * Byte 0~1: Packet length excluding hw frame tag
1123 * Byte 2: Reserved
1124 * Byte 3: Frame flags, bit 0: last frame indication
1125 * Byte 4~5: Reserved
1126 * Byte 6~7: Tail padding length
1104 * software header - 8 bytes 1127 * software header - 8 bytes
1105 * Byte 0: Rx/Tx sequence number 1128 * Byte 0: Rx/Tx sequence number
1106 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag 1129 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
@@ -1111,6 +1134,7 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1111 * Byte 6~7: Reserved 1134 * Byte 6~7: Reserved
1112 */ 1135 */
1113#define SDPCM_HWHDR_LEN 4 1136#define SDPCM_HWHDR_LEN 4
1137#define SDPCM_HWEXT_LEN 8
1114#define SDPCM_SWHDR_LEN 8 1138#define SDPCM_SWHDR_LEN 8
1115#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN) 1139#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
1116/* software header */ 1140/* software header */
@@ -1147,7 +1171,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1147 u8 rx_seq, fc, tx_seq_max; 1171 u8 rx_seq, fc, tx_seq_max;
1148 u32 swheader; 1172 u32 swheader;
1149 1173
1150 trace_brcmf_sdpcm_hdr(false, header); 1174 trace_brcmf_sdpcm_hdr(SDPCM_RX, header);
1151 1175
1152 /* hw header */ 1176 /* hw header */
1153 len = get_unaligned_le16(header); 1177 len = get_unaligned_le16(header);
@@ -1160,7 +1184,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1160 if ((u16)(~(len ^ checksum))) { 1184 if ((u16)(~(len ^ checksum))) {
1161 brcmf_err("HW header checksum error\n"); 1185 brcmf_err("HW header checksum error\n");
1162 bus->sdcnt.rx_badhdr++; 1186 bus->sdcnt.rx_badhdr++;
1163 brcmf_sdbrcm_rxfail(bus, false, false); 1187 brcmf_sdio_rxfail(bus, false, false);
1164 return -EIO; 1188 return -EIO;
1165 } 1189 }
1166 if (len < SDPCM_HDRLEN) { 1190 if (len < SDPCM_HDRLEN) {
@@ -1192,7 +1216,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1192 type != BRCMF_SDIO_FT_SUPER) { 1216 type != BRCMF_SDIO_FT_SUPER) {
1193 brcmf_err("HW header length too long\n"); 1217 brcmf_err("HW header length too long\n");
1194 bus->sdcnt.rx_toolong++; 1218 bus->sdcnt.rx_toolong++;
1195 brcmf_sdbrcm_rxfail(bus, false, false); 1219 brcmf_sdio_rxfail(bus, false, false);
1196 rd->len = 0; 1220 rd->len = 0;
1197 return -EPROTO; 1221 return -EPROTO;
1198 } 1222 }
@@ -1211,7 +1235,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1211 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { 1235 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
1212 brcmf_err("seq %d: bad data offset\n", rx_seq); 1236 brcmf_err("seq %d: bad data offset\n", rx_seq);
1213 bus->sdcnt.rx_badhdr++; 1237 bus->sdcnt.rx_badhdr++;
1214 brcmf_sdbrcm_rxfail(bus, false, false); 1238 brcmf_sdio_rxfail(bus, false, false);
1215 rd->len = 0; 1239 rd->len = 0;
1216 return -ENXIO; 1240 return -ENXIO;
1217 } 1241 }
@@ -1260,25 +1284,34 @@ static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length)
1260static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, 1284static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
1261 struct brcmf_sdio_hdrinfo *hd_info) 1285 struct brcmf_sdio_hdrinfo *hd_info)
1262{ 1286{
1263 u32 sw_header; 1287 u32 hdrval;
1288 u8 hdr_offset;
1264 1289
1265 brcmf_sdio_update_hwhdr(header, hd_info->len); 1290 brcmf_sdio_update_hwhdr(header, hd_info->len);
1266 1291 hdr_offset = SDPCM_HWHDR_LEN;
1267 sw_header = bus->tx_seq; 1292
1268 sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & 1293 if (bus->txglom) {
1269 SDPCM_CHANNEL_MASK; 1294 hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24);
1270 sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & 1295 *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
1271 SDPCM_DOFFSET_MASK; 1296 hdrval = (u16)hd_info->tail_pad << 16;
1272 *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); 1297 *(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval);
1273 *(((__le32 *)header) + 2) = 0; 1298 hdr_offset += SDPCM_HWEXT_LEN;
1274 trace_brcmf_sdpcm_hdr(true, header); 1299 }
1300
1301 hdrval = hd_info->seq_num;
1302 hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
1303 SDPCM_CHANNEL_MASK;
1304 hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
1305 SDPCM_DOFFSET_MASK;
1306 *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
1307 *(((__le32 *)(header + hdr_offset)) + 1) = 0;
1308 trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header);
1275} 1309}
1276 1310
1277static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1311static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1278{ 1312{
1279 u16 dlen, totlen; 1313 u16 dlen, totlen;
1280 u8 *dptr, num = 0; 1314 u8 *dptr, num = 0;
1281 u32 align = 0;
1282 u16 sublen; 1315 u16 sublen;
1283 struct sk_buff *pfirst, *pnext; 1316 struct sk_buff *pfirst, *pnext;
1284 1317
@@ -1293,11 +1326,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1293 brcmf_dbg(SDIO, "start: glomd %p glom %p\n", 1326 brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
1294 bus->glomd, skb_peek(&bus->glom)); 1327 bus->glomd, skb_peek(&bus->glom));
1295 1328
1296 if (bus->sdiodev->pdata)
1297 align = bus->sdiodev->pdata->sd_sgentry_align;
1298 if (align < 4)
1299 align = 4;
1300
1301 /* If there's a descriptor, generate the packet chain */ 1329 /* If there's a descriptor, generate the packet chain */
1302 if (bus->glomd) { 1330 if (bus->glomd) {
1303 pfirst = pnext = NULL; 1331 pfirst = pnext = NULL;
@@ -1321,9 +1349,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1321 pnext = NULL; 1349 pnext = NULL;
1322 break; 1350 break;
1323 } 1351 }
1324 if (sublen % align) { 1352 if (sublen % bus->sgentry_align) {
1325 brcmf_err("sublen %d not multiple of %d\n", 1353 brcmf_err("sublen %d not multiple of %d\n",
1326 sublen, align); 1354 sublen, bus->sgentry_align);
1327 } 1355 }
1328 totlen += sublen; 1356 totlen += sublen;
1329 1357
@@ -1336,7 +1364,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1336 } 1364 }
1337 1365
1338 /* Allocate/chain packet for next subframe */ 1366 /* Allocate/chain packet for next subframe */
1339 pnext = brcmu_pkt_buf_get_skb(sublen + align); 1367 pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align);
1340 if (pnext == NULL) { 1368 if (pnext == NULL) {
1341 brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n", 1369 brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
1342 num, sublen); 1370 num, sublen);
@@ -1345,7 +1373,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1345 skb_queue_tail(&bus->glom, pnext); 1373 skb_queue_tail(&bus->glom, pnext);
1346 1374
1347 /* Adhere to start alignment requirements */ 1375 /* Adhere to start alignment requirements */
1348 pkt_align(pnext, sublen, align); 1376 pkt_align(pnext, sublen, bus->sgentry_align);
1349 } 1377 }
1350 1378
1351 /* If all allocations succeeded, save packet chain 1379 /* If all allocations succeeded, save packet chain
@@ -1360,7 +1388,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1360 } 1388 }
1361 pfirst = pnext = NULL; 1389 pfirst = pnext = NULL;
1362 } else { 1390 } else {
1363 brcmf_sdbrcm_free_glom(bus); 1391 brcmf_sdio_free_glom(bus);
1364 num = 0; 1392 num = 0;
1365 } 1393 }
1366 1394
@@ -1383,16 +1411,15 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1383 } 1411 }
1384 1412
1385 pfirst = skb_peek(&bus->glom); 1413 pfirst = skb_peek(&bus->glom);
1386 dlen = (u16) brcmf_sdbrcm_glom_len(bus); 1414 dlen = (u16) brcmf_sdio_glom_len(bus);
1387 1415
1388 /* Do an SDIO read for the superframe. Configurable iovar to 1416 /* Do an SDIO read for the superframe. Configurable iovar to
1389 * read directly into the chained packet, or allocate a large 1417 * read directly into the chained packet, or allocate a large
1390 * packet and and copy into the chain. 1418 * packet and and copy into the chain.
1391 */ 1419 */
1392 sdio_claim_host(bus->sdiodev->func[1]); 1420 sdio_claim_host(bus->sdiodev->func[1]);
1393 errcode = brcmf_sdcard_recv_chain(bus->sdiodev, 1421 errcode = brcmf_sdiod_recv_chain(bus->sdiodev,
1394 bus->sdiodev->sbwad, 1422 &bus->glom, dlen);
1395 SDIO_FUNC_2, F2SYNC, &bus->glom, dlen);
1396 sdio_release_host(bus->sdiodev->func[1]); 1423 sdio_release_host(bus->sdiodev->func[1]);
1397 bus->sdcnt.f2rxdata++; 1424 bus->sdcnt.f2rxdata++;
1398 1425
@@ -1403,12 +1430,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1403 1430
1404 sdio_claim_host(bus->sdiodev->func[1]); 1431 sdio_claim_host(bus->sdiodev->func[1]);
1405 if (bus->glomerr++ < 3) { 1432 if (bus->glomerr++ < 3) {
1406 brcmf_sdbrcm_rxfail(bus, true, true); 1433 brcmf_sdio_rxfail(bus, true, true);
1407 } else { 1434 } else {
1408 bus->glomerr = 0; 1435 bus->glomerr = 0;
1409 brcmf_sdbrcm_rxfail(bus, true, false); 1436 brcmf_sdio_rxfail(bus, true, false);
1410 bus->sdcnt.rxglomfail++; 1437 bus->sdcnt.rxglomfail++;
1411 brcmf_sdbrcm_free_glom(bus); 1438 brcmf_sdio_free_glom(bus);
1412 } 1439 }
1413 sdio_release_host(bus->sdiodev->func[1]); 1440 sdio_release_host(bus->sdiodev->func[1]);
1414 return 0; 1441 return 0;
@@ -1456,12 +1483,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1456 if (bus->glomerr++ < 3) { 1483 if (bus->glomerr++ < 3) {
1457 /* Restore superframe header space */ 1484 /* Restore superframe header space */
1458 skb_push(pfirst, sfdoff); 1485 skb_push(pfirst, sfdoff);
1459 brcmf_sdbrcm_rxfail(bus, true, true); 1486 brcmf_sdio_rxfail(bus, true, true);
1460 } else { 1487 } else {
1461 bus->glomerr = 0; 1488 bus->glomerr = 0;
1462 brcmf_sdbrcm_rxfail(bus, true, false); 1489 brcmf_sdio_rxfail(bus, true, false);
1463 bus->sdcnt.rxglomfail++; 1490 bus->sdcnt.rxglomfail++;
1464 brcmf_sdbrcm_free_glom(bus); 1491 brcmf_sdio_free_glom(bus);
1465 } 1492 }
1466 sdio_release_host(bus->sdiodev->func[1]); 1493 sdio_release_host(bus->sdiodev->func[1]);
1467 bus->cur_read.len = 0; 1494 bus->cur_read.len = 0;
@@ -1505,8 +1532,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1505 return num; 1532 return num;
1506} 1533}
1507 1534
1508static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition, 1535static int brcmf_sdio_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
1509 bool *pending) 1536 bool *pending)
1510{ 1537{
1511 DECLARE_WAITQUEUE(wait, current); 1538 DECLARE_WAITQUEUE(wait, current);
1512 int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT); 1539 int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
@@ -1527,7 +1554,7 @@ static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
1527 return timeout; 1554 return timeout;
1528} 1555}
1529 1556
1530static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus) 1557static int brcmf_sdio_dcmd_resp_wake(struct brcmf_sdio *bus)
1531{ 1558{
1532 if (waitqueue_active(&bus->dcmd_resp_wait)) 1559 if (waitqueue_active(&bus->dcmd_resp_wait))
1533 wake_up_interruptible(&bus->dcmd_resp_wait); 1560 wake_up_interruptible(&bus->dcmd_resp_wait);
@@ -1535,7 +1562,7 @@ static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus)
1535 return 0; 1562 return 0;
1536} 1563}
1537static void 1564static void
1538brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) 1565brcmf_sdio_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1539{ 1566{
1540 uint rdlen, pad; 1567 uint rdlen, pad;
1541 u8 *buf = NULL, *rbuf; 1568 u8 *buf = NULL, *rbuf;
@@ -1549,9 +1576,9 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1549 goto done; 1576 goto done;
1550 1577
1551 rbuf = bus->rxbuf; 1578 rbuf = bus->rxbuf;
1552 pad = ((unsigned long)rbuf % BRCMF_SDALIGN); 1579 pad = ((unsigned long)rbuf % bus->head_align);
1553 if (pad) 1580 if (pad)
1554 rbuf += (BRCMF_SDALIGN - pad); 1581 rbuf += (bus->head_align - pad);
1555 1582
1556 /* Copy the already-read portion over */ 1583 /* Copy the already-read portion over */
1557 memcpy(buf, hdr, BRCMF_FIRSTREAD); 1584 memcpy(buf, hdr, BRCMF_FIRSTREAD);
@@ -1565,19 +1592,15 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1565 if ((pad <= bus->roundup) && (pad < bus->blocksize) && 1592 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
1566 ((len + pad) < bus->sdiodev->bus_if->maxctl)) 1593 ((len + pad) < bus->sdiodev->bus_if->maxctl))
1567 rdlen += pad; 1594 rdlen += pad;
1568 } else if (rdlen % BRCMF_SDALIGN) { 1595 } else if (rdlen % bus->head_align) {
1569 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); 1596 rdlen += bus->head_align - (rdlen % bus->head_align);
1570 } 1597 }
1571 1598
1572 /* Satisfy length-alignment requirements */
1573 if (rdlen & (ALIGNMENT - 1))
1574 rdlen = roundup(rdlen, ALIGNMENT);
1575
1576 /* Drop if the read is too big or it exceeds our maximum */ 1599 /* Drop if the read is too big or it exceeds our maximum */
1577 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { 1600 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
1578 brcmf_err("%d-byte control read exceeds %d-byte buffer\n", 1601 brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
1579 rdlen, bus->sdiodev->bus_if->maxctl); 1602 rdlen, bus->sdiodev->bus_if->maxctl);
1580 brcmf_sdbrcm_rxfail(bus, false, false); 1603 brcmf_sdio_rxfail(bus, false, false);
1581 goto done; 1604 goto done;
1582 } 1605 }
1583 1606
@@ -1585,15 +1608,12 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1585 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", 1608 brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1586 len, len - doff, bus->sdiodev->bus_if->maxctl); 1609 len, len - doff, bus->sdiodev->bus_if->maxctl);
1587 bus->sdcnt.rx_toolong++; 1610 bus->sdcnt.rx_toolong++;
1588 brcmf_sdbrcm_rxfail(bus, false, false); 1611 brcmf_sdio_rxfail(bus, false, false);
1589 goto done; 1612 goto done;
1590 } 1613 }
1591 1614
1592 /* Read remain of frame body */ 1615 /* Read remain of frame body */
1593 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, 1616 sdret = brcmf_sdiod_recv_buf(bus->sdiodev, rbuf, rdlen);
1594 bus->sdiodev->sbwad,
1595 SDIO_FUNC_2,
1596 F2SYNC, rbuf, rdlen);
1597 bus->sdcnt.f2rxdata++; 1617 bus->sdcnt.f2rxdata++;
1598 1618
1599 /* Control frame failures need retransmission */ 1619 /* Control frame failures need retransmission */
@@ -1601,7 +1621,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1601 brcmf_err("read %d control bytes failed: %d\n", 1621 brcmf_err("read %d control bytes failed: %d\n",
1602 rdlen, sdret); 1622 rdlen, sdret);
1603 bus->sdcnt.rxc_errors++; 1623 bus->sdcnt.rxc_errors++;
1604 brcmf_sdbrcm_rxfail(bus, true, true); 1624 brcmf_sdio_rxfail(bus, true, true);
1605 goto done; 1625 goto done;
1606 } else 1626 } else
1607 memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); 1627 memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen);
@@ -1626,19 +1646,19 @@ gotpkt:
1626 1646
1627done: 1647done:
1628 /* Awake any waiters */ 1648 /* Awake any waiters */
1629 brcmf_sdbrcm_dcmd_resp_wake(bus); 1649 brcmf_sdio_dcmd_resp_wake(bus);
1630} 1650}
1631 1651
1632/* Pad read to blocksize for efficiency */ 1652/* Pad read to blocksize for efficiency */
1633static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) 1653static void brcmf_sdio_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
1634{ 1654{
1635 if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) { 1655 if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
1636 *pad = bus->blocksize - (*rdlen % bus->blocksize); 1656 *pad = bus->blocksize - (*rdlen % bus->blocksize);
1637 if (*pad <= bus->roundup && *pad < bus->blocksize && 1657 if (*pad <= bus->roundup && *pad < bus->blocksize &&
1638 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ) 1658 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
1639 *rdlen += *pad; 1659 *rdlen += *pad;
1640 } else if (*rdlen % BRCMF_SDALIGN) { 1660 } else if (*rdlen % bus->head_align) {
1641 *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN); 1661 *rdlen += bus->head_align - (*rdlen % bus->head_align);
1642 } 1662 }
1643} 1663}
1644 1664
@@ -1658,8 +1678,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1658 bus->rxpending = true; 1678 bus->rxpending = true;
1659 1679
1660 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1680 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1661 !bus->rxskip && rxleft && 1681 !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if);
1662 bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
1663 rd->seq_num++, rxleft--) { 1682 rd->seq_num++, rxleft--) {
1664 1683
1665 /* Handle glomming separately */ 1684 /* Handle glomming separately */
@@ -1667,7 +1686,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1667 u8 cnt; 1686 u8 cnt;
1668 brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", 1687 brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
1669 bus->glomd, skb_peek(&bus->glom)); 1688 bus->glomd, skb_peek(&bus->glom));
1670 cnt = brcmf_sdbrcm_rxglom(bus, rd->seq_num); 1689 cnt = brcmf_sdio_rxglom(bus, rd->seq_num);
1671 brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); 1690 brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
1672 rd->seq_num += cnt - 1; 1691 rd->seq_num += cnt - 1;
1673 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; 1692 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
@@ -1678,17 +1697,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1678 /* read header first for unknow frame length */ 1697 /* read header first for unknow frame length */
1679 sdio_claim_host(bus->sdiodev->func[1]); 1698 sdio_claim_host(bus->sdiodev->func[1]);
1680 if (!rd->len) { 1699 if (!rd->len) {
1681 ret = brcmf_sdcard_recv_buf(bus->sdiodev, 1700 ret = brcmf_sdiod_recv_buf(bus->sdiodev,
1682 bus->sdiodev->sbwad, 1701 bus->rxhdr, BRCMF_FIRSTREAD);
1683 SDIO_FUNC_2, F2SYNC,
1684 bus->rxhdr,
1685 BRCMF_FIRSTREAD);
1686 bus->sdcnt.f2rxhdrs++; 1702 bus->sdcnt.f2rxhdrs++;
1687 if (ret < 0) { 1703 if (ret < 0) {
1688 brcmf_err("RXHEADER FAILED: %d\n", 1704 brcmf_err("RXHEADER FAILED: %d\n",
1689 ret); 1705 ret);
1690 bus->sdcnt.rx_hdrfail++; 1706 bus->sdcnt.rx_hdrfail++;
1691 brcmf_sdbrcm_rxfail(bus, true, true); 1707 brcmf_sdio_rxfail(bus, true, true);
1692 sdio_release_host(bus->sdiodev->func[1]); 1708 sdio_release_host(bus->sdiodev->func[1]);
1693 continue; 1709 continue;
1694 } 1710 }
@@ -1707,9 +1723,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1707 } 1723 }
1708 1724
1709 if (rd->channel == SDPCM_CONTROL_CHANNEL) { 1725 if (rd->channel == SDPCM_CONTROL_CHANNEL) {
1710 brcmf_sdbrcm_read_control(bus, bus->rxhdr, 1726 brcmf_sdio_read_control(bus, bus->rxhdr,
1711 rd->len, 1727 rd->len,
1712 rd->dat_offset); 1728 rd->dat_offset);
1713 /* prepare the descriptor for the next read */ 1729 /* prepare the descriptor for the next read */
1714 rd->len = rd->len_nxtfrm << 4; 1730 rd->len = rd->len_nxtfrm << 4;
1715 rd->len_nxtfrm = 0; 1731 rd->len_nxtfrm = 0;
@@ -1723,23 +1739,22 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1723 head_read = BRCMF_FIRSTREAD; 1739 head_read = BRCMF_FIRSTREAD;
1724 } 1740 }
1725 1741
1726 brcmf_pad(bus, &pad, &rd->len_left); 1742 brcmf_sdio_pad(bus, &pad, &rd->len_left);
1727 1743
1728 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read + 1744 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read +
1729 BRCMF_SDALIGN); 1745 bus->head_align);
1730 if (!pkt) { 1746 if (!pkt) {
1731 /* Give up on data, request rtx of events */ 1747 /* Give up on data, request rtx of events */
1732 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); 1748 brcmf_err("brcmu_pkt_buf_get_skb failed\n");
1733 brcmf_sdbrcm_rxfail(bus, false, 1749 brcmf_sdio_rxfail(bus, false,
1734 RETRYCHAN(rd->channel)); 1750 RETRYCHAN(rd->channel));
1735 sdio_release_host(bus->sdiodev->func[1]); 1751 sdio_release_host(bus->sdiodev->func[1]);
1736 continue; 1752 continue;
1737 } 1753 }
1738 skb_pull(pkt, head_read); 1754 skb_pull(pkt, head_read);
1739 pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); 1755 pkt_align(pkt, rd->len_left, bus->head_align);
1740 1756
1741 ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1757 ret = brcmf_sdiod_recv_pkt(bus->sdiodev, pkt);
1742 SDIO_FUNC_2, F2SYNC, pkt);
1743 bus->sdcnt.f2rxdata++; 1758 bus->sdcnt.f2rxdata++;
1744 sdio_release_host(bus->sdiodev->func[1]); 1759 sdio_release_host(bus->sdiodev->func[1]);
1745 1760
@@ -1748,7 +1763,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1748 rd->len, rd->channel, ret); 1763 rd->len, rd->channel, ret);
1749 brcmu_pkt_buf_free_skb(pkt); 1764 brcmu_pkt_buf_free_skb(pkt);
1750 sdio_claim_host(bus->sdiodev->func[1]); 1765 sdio_claim_host(bus->sdiodev->func[1]);
1751 brcmf_sdbrcm_rxfail(bus, true, 1766 brcmf_sdio_rxfail(bus, true,
1752 RETRYCHAN(rd->channel)); 1767 RETRYCHAN(rd->channel));
1753 sdio_release_host(bus->sdiodev->func[1]); 1768 sdio_release_host(bus->sdiodev->func[1]);
1754 continue; 1769 continue;
@@ -1773,7 +1788,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1773 rd->len, 1788 rd->len,
1774 roundup(rd_new.len, 16) >> 4); 1789 roundup(rd_new.len, 16) >> 4);
1775 rd->len = 0; 1790 rd->len = 0;
1776 brcmf_sdbrcm_rxfail(bus, true, true); 1791 brcmf_sdio_rxfail(bus, true, true);
1777 sdio_release_host(bus->sdiodev->func[1]); 1792 sdio_release_host(bus->sdiodev->func[1]);
1778 brcmu_pkt_buf_free_skb(pkt); 1793 brcmu_pkt_buf_free_skb(pkt);
1779 continue; 1794 continue;
@@ -1795,7 +1810,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1795 /* Force retry w/normal header read */ 1810 /* Force retry w/normal header read */
1796 rd->len = 0; 1811 rd->len = 0;
1797 sdio_claim_host(bus->sdiodev->func[1]); 1812 sdio_claim_host(bus->sdiodev->func[1]);
1798 brcmf_sdbrcm_rxfail(bus, false, true); 1813 brcmf_sdio_rxfail(bus, false, true);
1799 sdio_release_host(bus->sdiodev->func[1]); 1814 sdio_release_host(bus->sdiodev->func[1]);
1800 brcmu_pkt_buf_free_skb(pkt); 1815 brcmu_pkt_buf_free_skb(pkt);
1801 continue; 1816 continue;
@@ -1820,7 +1835,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1820 brcmf_err("%s: glom superframe w/o " 1835 brcmf_err("%s: glom superframe w/o "
1821 "descriptor!\n", __func__); 1836 "descriptor!\n", __func__);
1822 sdio_claim_host(bus->sdiodev->func[1]); 1837 sdio_claim_host(bus->sdiodev->func[1]);
1823 brcmf_sdbrcm_rxfail(bus, false, false); 1838 brcmf_sdio_rxfail(bus, false, false);
1824 sdio_release_host(bus->sdiodev->func[1]); 1839 sdio_release_host(bus->sdiodev->func[1]);
1825 } 1840 }
1826 /* prepare the descriptor for the next read */ 1841 /* prepare the descriptor for the next read */
@@ -1864,13 +1879,36 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1864} 1879}
1865 1880
1866static void 1881static void
1867brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) 1882brcmf_sdio_wait_event_wakeup(struct brcmf_sdio *bus)
1868{ 1883{
1869 if (waitqueue_active(&bus->ctrl_wait)) 1884 if (waitqueue_active(&bus->ctrl_wait))
1870 wake_up_interruptible(&bus->ctrl_wait); 1885 wake_up_interruptible(&bus->ctrl_wait);
1871 return; 1886 return;
1872} 1887}
1873 1888
1889static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
1890{
1891 u16 head_pad;
1892 u8 *dat_buf;
1893
1894 dat_buf = (u8 *)(pkt->data);
1895
1896 /* Check head padding */
1897 head_pad = ((unsigned long)dat_buf % bus->head_align);
1898 if (head_pad) {
1899 if (skb_headroom(pkt) < head_pad) {
1900 bus->sdiodev->bus_if->tx_realloc++;
1901 head_pad = 0;
1902 if (skb_cow(pkt, head_pad))
1903 return -ENOMEM;
1904 }
1905 skb_push(pkt, head_pad);
1906 dat_buf = (u8 *)(pkt->data);
1907 memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
1908 }
1909 return head_pad;
1910}
1911
1874/** 1912/**
1875 * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for 1913 * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
1876 * bus layer usage. 1914 * bus layer usage.
@@ -1880,32 +1918,40 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
1880/* bit mask of data length chopped from the previous packet */ 1918/* bit mask of data length chopped from the previous packet */
1881#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff 1919#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff
1882 1920
1883static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, 1921static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
1884 struct sk_buff_head *pktq, 1922 struct sk_buff_head *pktq,
1885 struct sk_buff *pkt, uint chan) 1923 struct sk_buff *pkt, u16 total_len)
1886{ 1924{
1925 struct brcmf_sdio_dev *sdiodev;
1887 struct sk_buff *pkt_pad; 1926 struct sk_buff *pkt_pad;
1888 u16 tail_pad, tail_chop, sg_align; 1927 u16 tail_pad, tail_chop, chain_pad;
1889 unsigned int blksize; 1928 unsigned int blksize;
1890 u8 *dat_buf; 1929 bool lastfrm;
1891 int ntail; 1930 int ntail, ret;
1892 1931
1932 sdiodev = bus->sdiodev;
1893 blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; 1933 blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
1894 sg_align = 4;
1895 if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
1896 sg_align = sdiodev->pdata->sd_sgentry_align;
1897 /* sg entry alignment should be a divisor of block size */ 1934 /* sg entry alignment should be a divisor of block size */
1898 WARN_ON(blksize % sg_align); 1935 WARN_ON(blksize % bus->sgentry_align);
1899 1936
1900 /* Check tail padding */ 1937 /* Check tail padding */
1901 pkt_pad = NULL; 1938 lastfrm = skb_queue_is_last(pktq, pkt);
1902 tail_chop = pkt->len % sg_align; 1939 tail_pad = 0;
1903 tail_pad = sg_align - tail_chop; 1940 tail_chop = pkt->len % bus->sgentry_align;
1904 tail_pad += blksize - (pkt->len + tail_pad) % blksize; 1941 if (tail_chop)
1942 tail_pad = bus->sgentry_align - tail_chop;
1943 chain_pad = (total_len + tail_pad) % blksize;
1944 if (lastfrm && chain_pad)
1945 tail_pad += blksize - chain_pad;
1905 if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { 1946 if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) {
1906 pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); 1947 pkt_pad = bus->txglom_sgpad;
1948 if (pkt_pad == NULL)
1949 brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
1907 if (pkt_pad == NULL) 1950 if (pkt_pad == NULL)
1908 return -ENOMEM; 1951 return -ENOMEM;
1952 ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad);
1953 if (unlikely(ret < 0))
1954 return ret;
1909 memcpy(pkt_pad->data, 1955 memcpy(pkt_pad->data,
1910 pkt->data + pkt->len - tail_chop, 1956 pkt->data + pkt->len - tail_chop,
1911 tail_chop); 1957 tail_chop);
@@ -1920,14 +1966,10 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
1920 return -ENOMEM; 1966 return -ENOMEM;
1921 if (skb_linearize(pkt)) 1967 if (skb_linearize(pkt))
1922 return -ENOMEM; 1968 return -ENOMEM;
1923 dat_buf = (u8 *)(pkt->data);
1924 __skb_put(pkt, tail_pad); 1969 __skb_put(pkt, tail_pad);
1925 } 1970 }
1926 1971
1927 if (pkt_pad) 1972 return tail_pad;
1928 return pkt->len + tail_chop;
1929 else
1930 return pkt->len - tail_pad;
1931} 1973}
1932 1974
1933/** 1975/**
@@ -1946,58 +1988,66 @@ static int
1946brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, 1988brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
1947 uint chan) 1989 uint chan)
1948{ 1990{
1949 u16 head_pad, head_align; 1991 u16 head_pad, total_len;
1950 struct sk_buff *pkt_next; 1992 struct sk_buff *pkt_next;
1951 u8 *dat_buf; 1993 u8 txseq;
1952 int err; 1994 int ret;
1953 struct brcmf_sdio_hdrinfo hd_info = {0}; 1995 struct brcmf_sdio_hdrinfo hd_info = {0};
1954 1996
1955 /* SDIO ADMA requires at least 32 bit alignment */ 1997 txseq = bus->tx_seq;
1956 head_align = 4; 1998 total_len = 0;
1957 if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) 1999 skb_queue_walk(pktq, pkt_next) {
1958 head_align = bus->sdiodev->pdata->sd_head_align; 2000 /* alignment packet inserted in previous
2001 * loop cycle can be skipped as it is
2002 * already properly aligned and does not
2003 * need an sdpcm header.
2004 */
2005 if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
2006 continue;
1959 2007
1960 pkt_next = pktq->next; 2008 /* align packet data pointer */
1961 dat_buf = (u8 *)(pkt_next->data); 2009 ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next);
2010 if (ret < 0)
2011 return ret;
2012 head_pad = (u16)ret;
2013 if (head_pad)
2014 memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen);
1962 2015
1963 /* Check head padding */ 2016 total_len += pkt_next->len;
1964 head_pad = ((unsigned long)dat_buf % head_align);
1965 if (head_pad) {
1966 if (skb_headroom(pkt_next) < head_pad) {
1967 bus->sdiodev->bus_if->tx_realloc++;
1968 head_pad = 0;
1969 if (skb_cow(pkt_next, head_pad))
1970 return -ENOMEM;
1971 }
1972 skb_push(pkt_next, head_pad);
1973 dat_buf = (u8 *)(pkt_next->data);
1974 memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
1975 }
1976 2017
1977 if (bus->sdiodev->sg_support && pktq->qlen > 1) {
1978 err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq,
1979 pkt_next, chan);
1980 if (err < 0)
1981 return err;
1982 hd_info.len = (u16)err;
1983 } else {
1984 hd_info.len = pkt_next->len; 2018 hd_info.len = pkt_next->len;
1985 } 2019 hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next);
1986 2020 if (bus->txglom && pktq->qlen > 1) {
1987 hd_info.channel = chan; 2021 ret = brcmf_sdio_txpkt_prep_sg(bus, pktq,
1988 hd_info.dat_offset = head_pad + bus->tx_hdrlen; 2022 pkt_next, total_len);
1989 2023 if (ret < 0)
1990 /* Now fill the header */ 2024 return ret;
1991 brcmf_sdio_hdpack(bus, dat_buf, &hd_info); 2025 hd_info.tail_pad = (u16)ret;
1992 2026 total_len += (u16)ret;
1993 if (BRCMF_BYTES_ON() && 2027 }
1994 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
1995 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
1996 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n");
1997 else if (BRCMF_HDRS_ON())
1998 brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen,
1999 "Tx Header:\n");
2000 2028
2029 hd_info.channel = chan;
2030 hd_info.dat_offset = head_pad + bus->tx_hdrlen;
2031 hd_info.seq_num = txseq++;
2032
2033 /* Now fill the header */
2034 brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info);
2035
2036 if (BRCMF_BYTES_ON() &&
2037 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
2038 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
2039 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
2040 "Tx Frame:\n");
2041 else if (BRCMF_HDRS_ON())
2042 brcmf_dbg_hex_dump(true, pkt_next,
2043 head_pad + bus->tx_hdrlen,
2044 "Tx Header:\n");
2045 }
2046 /* Hardware length tag of the first packet should be total
2047 * length of the chain (including padding)
2048 */
2049 if (bus->txglom)
2050 brcmf_sdio_update_hwhdr(pktq->next->data, total_len);
2001 return 0; 2051 return 0;
2002} 2052}
2003 2053
@@ -2015,6 +2065,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2015{ 2065{
2016 u8 *hdr; 2066 u8 *hdr;
2017 u32 dat_offset; 2067 u32 dat_offset;
2068 u16 tail_pad;
2018 u32 dummy_flags, chop_len; 2069 u32 dummy_flags, chop_len;
2019 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2070 struct sk_buff *pkt_next, *tmp, *pkt_prev;
2020 2071
@@ -2024,42 +2075,41 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2024 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2075 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
2025 if (chop_len) { 2076 if (chop_len) {
2026 pkt_prev = pkt_next->prev; 2077 pkt_prev = pkt_next->prev;
2027 memcpy(pkt_prev->data + pkt_prev->len,
2028 pkt_next->data, chop_len);
2029 skb_put(pkt_prev, chop_len); 2078 skb_put(pkt_prev, chop_len);
2030 } 2079 }
2031 __skb_unlink(pkt_next, pktq); 2080 __skb_unlink(pkt_next, pktq);
2032 brcmu_pkt_buf_free_skb(pkt_next); 2081 brcmu_pkt_buf_free_skb(pkt_next);
2033 } else { 2082 } else {
2034 hdr = pkt_next->data + SDPCM_HWHDR_LEN; 2083 hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN;
2035 dat_offset = le32_to_cpu(*(__le32 *)hdr); 2084 dat_offset = le32_to_cpu(*(__le32 *)hdr);
2036 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> 2085 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >>
2037 SDPCM_DOFFSET_SHIFT; 2086 SDPCM_DOFFSET_SHIFT;
2038 skb_pull(pkt_next, dat_offset); 2087 skb_pull(pkt_next, dat_offset);
2088 if (bus->txglom) {
2089 tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2));
2090 skb_trim(pkt_next, pkt_next->len - tail_pad);
2091 }
2039 } 2092 }
2040 } 2093 }
2041} 2094}
2042 2095
2043/* Writes a HW/SW header into the packet and sends it. */ 2096/* Writes a HW/SW header into the packet and sends it. */
2044/* Assumes: (a) header space already there, (b) caller holds lock */ 2097/* Assumes: (a) header space already there, (b) caller holds lock */
2045static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, 2098static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2046 uint chan) 2099 uint chan)
2047{ 2100{
2048 int ret; 2101 int ret;
2049 int i; 2102 int i;
2050 struct sk_buff_head localq; 2103 struct sk_buff *pkt_next, *tmp;
2051 2104
2052 brcmf_dbg(TRACE, "Enter\n"); 2105 brcmf_dbg(TRACE, "Enter\n");
2053 2106
2054 __skb_queue_head_init(&localq); 2107 ret = brcmf_sdio_txpkt_prep(bus, pktq, chan);
2055 __skb_queue_tail(&localq, pkt);
2056 ret = brcmf_sdio_txpkt_prep(bus, &localq, chan);
2057 if (ret) 2108 if (ret)
2058 goto done; 2109 goto done;
2059 2110
2060 sdio_claim_host(bus->sdiodev->func[1]); 2111 sdio_claim_host(bus->sdiodev->func[1]);
2061 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 2112 ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
2062 SDIO_FUNC_2, F2SYNC, &localq);
2063 bus->sdcnt.f2txdata++; 2113 bus->sdcnt.f2txdata++;
2064 2114
2065 if (ret < 0) { 2115 if (ret < 0) {
@@ -2068,57 +2118,71 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
2068 ret); 2118 ret);
2069 bus->sdcnt.tx_sderrs++; 2119 bus->sdcnt.tx_sderrs++;
2070 2120
2071 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2121 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2072 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2122 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2073 SFC_WF_TERM, NULL); 2123 SFC_WF_TERM, NULL);
2074 bus->sdcnt.f1regdata++; 2124 bus->sdcnt.f1regdata++;
2075 2125
2076 for (i = 0; i < 3; i++) { 2126 for (i = 0; i < 3; i++) {
2077 u8 hi, lo; 2127 u8 hi, lo;
2078 hi = brcmf_sdio_regrb(bus->sdiodev, 2128 hi = brcmf_sdiod_regrb(bus->sdiodev,
2079 SBSDIO_FUNC1_WFRAMEBCHI, NULL); 2129 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2080 lo = brcmf_sdio_regrb(bus->sdiodev, 2130 lo = brcmf_sdiod_regrb(bus->sdiodev,
2081 SBSDIO_FUNC1_WFRAMEBCLO, NULL); 2131 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2082 bus->sdcnt.f1regdata += 2; 2132 bus->sdcnt.f1regdata += 2;
2083 if ((hi == 0) && (lo == 0)) 2133 if ((hi == 0) && (lo == 0))
2084 break; 2134 break;
2085 } 2135 }
2086
2087 } 2136 }
2088 sdio_release_host(bus->sdiodev->func[1]); 2137 sdio_release_host(bus->sdiodev->func[1]);
2089 if (ret == 0)
2090 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2091 2138
2092done: 2139done:
2093 brcmf_sdio_txpkt_postp(bus, &localq); 2140 brcmf_sdio_txpkt_postp(bus, pktq);
2094 __skb_dequeue_tail(&localq); 2141 if (ret == 0)
2095 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); 2142 bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
2143 skb_queue_walk_safe(pktq, pkt_next, tmp) {
2144 __skb_unlink(pkt_next, pktq);
2145 brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
2146 }
2096 return ret; 2147 return ret;
2097} 2148}
2098 2149
2099static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) 2150static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2100{ 2151{
2101 struct sk_buff *pkt; 2152 struct sk_buff *pkt;
2153 struct sk_buff_head pktq;
2102 u32 intstatus = 0; 2154 u32 intstatus = 0;
2103 int ret = 0, prec_out; 2155 int ret = 0, prec_out, i;
2104 uint cnt = 0; 2156 uint cnt = 0;
2105 u8 tx_prec_map; 2157 u8 tx_prec_map, pkt_num;
2106 2158
2107 brcmf_dbg(TRACE, "Enter\n"); 2159 brcmf_dbg(TRACE, "Enter\n");
2108 2160
2109 tx_prec_map = ~bus->flowcontrol; 2161 tx_prec_map = ~bus->flowcontrol;
2110 2162
2111 /* Send frames until the limit or some other event */ 2163 /* Send frames until the limit or some other event */
2112 for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) { 2164 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
2165 pkt_num = 1;
2166 __skb_queue_head_init(&pktq);
2167 if (bus->txglom)
2168 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2169 brcmf_sdio_txglomsz);
2170 pkt_num = min_t(u32, pkt_num,
2171 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
2113 spin_lock_bh(&bus->txqlock); 2172 spin_lock_bh(&bus->txqlock);
2114 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); 2173 for (i = 0; i < pkt_num; i++) {
2115 if (pkt == NULL) { 2174 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
2116 spin_unlock_bh(&bus->txqlock); 2175 &prec_out);
2117 break; 2176 if (pkt == NULL)
2177 break;
2178 __skb_queue_tail(&pktq, pkt);
2118 } 2179 }
2119 spin_unlock_bh(&bus->txqlock); 2180 spin_unlock_bh(&bus->txqlock);
2181 if (i == 0)
2182 break;
2120 2183
2121 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL); 2184 ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
2185 cnt += i;
2122 2186
2123 /* In poll mode, need to check for other events */ 2187 /* In poll mode, need to check for other events */
2124 if (!bus->intr && cnt) { 2188 if (!bus->intr && cnt) {
@@ -2146,7 +2210,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2146 return cnt; 2210 return cnt;
2147} 2211}
2148 2212
2149static void brcmf_sdbrcm_bus_stop(struct device *dev) 2213static void brcmf_sdio_bus_stop(struct device *dev)
2150{ 2214{
2151 u32 local_hostintmask; 2215 u32 local_hostintmask;
2152 u8 saveclk; 2216 u8 saveclk;
@@ -2163,62 +2227,57 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2163 bus->watchdog_tsk = NULL; 2227 bus->watchdog_tsk = NULL;
2164 } 2228 }
2165 2229
2166 sdio_claim_host(bus->sdiodev->func[1]); 2230 if (bus_if->state == BRCMF_BUS_DOWN) {
2167 2231 sdio_claim_host(sdiodev->func[1]);
2168 /* Enable clock for device interrupts */ 2232
2169 brcmf_sdbrcm_bus_sleep(bus, false, false); 2233 /* Enable clock for device interrupts */
2234 brcmf_sdio_bus_sleep(bus, false, false);
2235
2236 /* Disable and clear interrupts at the chip level also */
2237 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
2238 local_hostintmask = bus->hostintmask;
2239 bus->hostintmask = 0;
2240
2241 /* Force backplane clocks to assure F2 interrupt propagates */
2242 saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2243 &err);
2244 if (!err)
2245 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2246 (saveclk | SBSDIO_FORCE_HT), &err);
2247 if (err)
2248 brcmf_err("Failed to force clock for F2: err %d\n",
2249 err);
2170 2250
2171 /* Disable and clear interrupts at the chip level also */ 2251 /* Turn off the bus (F2), free any pending packets */
2172 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); 2252 brcmf_dbg(INTR, "disable SDIO interrupts\n");
2173 local_hostintmask = bus->hostintmask; 2253 sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
2174 bus->hostintmask = 0;
2175 2254
2176 /* Change our idea of bus state */ 2255 /* Clear any pending interrupts now that F2 is disabled */
2177 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2256 w_sdreg32(bus, local_hostintmask,
2257 offsetof(struct sdpcmd_regs, intstatus));
2178 2258
2179 /* Force clocks on backplane to be sure F2 interrupt propagates */ 2259 sdio_release_host(sdiodev->func[1]);
2180 saveclk = brcmf_sdio_regrb(bus->sdiodev,
2181 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2182 if (!err) {
2183 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
2184 (saveclk | SBSDIO_FORCE_HT), &err);
2185 } 2260 }
2186 if (err)
2187 brcmf_err("Failed to force clock for F2: err %d\n", err);
2188
2189 /* Turn off the bus (F2), free any pending packets */
2190 brcmf_dbg(INTR, "disable SDIO interrupts\n");
2191 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
2192 NULL);
2193
2194 /* Clear any pending interrupts now that F2 is disabled */
2195 w_sdreg32(bus, local_hostintmask,
2196 offsetof(struct sdpcmd_regs, intstatus));
2197
2198 /* Turn off the backplane clock (only) */
2199 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
2200 sdio_release_host(bus->sdiodev->func[1]);
2201
2202 /* Clear the data packet queues */ 2261 /* Clear the data packet queues */
2203 brcmu_pktq_flush(&bus->txq, true, NULL, NULL); 2262 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
2204 2263
2205 /* Clear any held glomming stuff */ 2264 /* Clear any held glomming stuff */
2206 if (bus->glomd) 2265 if (bus->glomd)
2207 brcmu_pkt_buf_free_skb(bus->glomd); 2266 brcmu_pkt_buf_free_skb(bus->glomd);
2208 brcmf_sdbrcm_free_glom(bus); 2267 brcmf_sdio_free_glom(bus);
2209 2268
2210 /* Clear rx control and wake any waiters */ 2269 /* Clear rx control and wake any waiters */
2211 spin_lock_bh(&bus->rxctl_lock); 2270 spin_lock_bh(&bus->rxctl_lock);
2212 bus->rxlen = 0; 2271 bus->rxlen = 0;
2213 spin_unlock_bh(&bus->rxctl_lock); 2272 spin_unlock_bh(&bus->rxctl_lock);
2214 brcmf_sdbrcm_dcmd_resp_wake(bus); 2273 brcmf_sdio_dcmd_resp_wake(bus);
2215 2274
2216 /* Reset some F2 state stuff */ 2275 /* Reset some F2 state stuff */
2217 bus->rxskip = false; 2276 bus->rxskip = false;
2218 bus->tx_seq = bus->rx_seq = 0; 2277 bus->tx_seq = bus->rx_seq = 0;
2219} 2278}
2220 2279
2221static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) 2280static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
2222{ 2281{
2223 unsigned long flags; 2282 unsigned long flags;
2224 2283
@@ -2243,7 +2302,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2243 addr = bus->ci->c_inf[idx].base + 2302 addr = bus->ci->c_inf[idx].base +
2244 offsetof(struct sdpcmd_regs, intstatus); 2303 offsetof(struct sdpcmd_regs, intstatus);
2245 2304
2246 ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, false); 2305 val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
2247 bus->sdcnt.f1regdata++; 2306 bus->sdcnt.f1regdata++;
2248 if (ret != 0) 2307 if (ret != 0)
2249 val = 0; 2308 val = 0;
@@ -2253,7 +2312,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2253 2312
2254 /* Clear interrupts */ 2313 /* Clear interrupts */
2255 if (val) { 2314 if (val) {
2256 ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, true); 2315 brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
2257 bus->sdcnt.f1regdata++; 2316 bus->sdcnt.f1regdata++;
2258 } 2317 }
2259 2318
@@ -2267,7 +2326,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2267 return ret; 2326 return ret;
2268} 2327}
2269 2328
2270static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) 2329static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2271{ 2330{
2272 u32 newstatus = 0; 2331 u32 newstatus = 0;
2273 unsigned long intstatus; 2332 unsigned long intstatus;
@@ -2286,48 +2345,29 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2286 2345
2287#ifdef DEBUG 2346#ifdef DEBUG
2288 /* Check for inconsistent device control */ 2347 /* Check for inconsistent device control */
2289 devctl = brcmf_sdio_regrb(bus->sdiodev, 2348 devctl = brcmf_sdiod_regrb(bus->sdiodev,
2290 SBSDIO_DEVICE_CTL, &err); 2349 SBSDIO_DEVICE_CTL, &err);
2291 if (err) {
2292 brcmf_err("error reading DEVCTL: %d\n", err);
2293 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2294 }
2295#endif /* DEBUG */ 2350#endif /* DEBUG */
2296 2351
2297 /* Read CSR, if clock on switch to AVAIL, else ignore */ 2352 /* Read CSR, if clock on switch to AVAIL, else ignore */
2298 clkctl = brcmf_sdio_regrb(bus->sdiodev, 2353 clkctl = brcmf_sdiod_regrb(bus->sdiodev,
2299 SBSDIO_FUNC1_CHIPCLKCSR, &err); 2354 SBSDIO_FUNC1_CHIPCLKCSR, &err);
2300 if (err) {
2301 brcmf_err("error reading CSR: %d\n",
2302 err);
2303 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2304 }
2305 2355
2306 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", 2356 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
2307 devctl, clkctl); 2357 devctl, clkctl);
2308 2358
2309 if (SBSDIO_HTAV(clkctl)) { 2359 if (SBSDIO_HTAV(clkctl)) {
2310 devctl = brcmf_sdio_regrb(bus->sdiodev, 2360 devctl = brcmf_sdiod_regrb(bus->sdiodev,
2311 SBSDIO_DEVICE_CTL, &err); 2361 SBSDIO_DEVICE_CTL, &err);
2312 if (err) {
2313 brcmf_err("error reading DEVCTL: %d\n",
2314 err);
2315 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2316 }
2317 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; 2362 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
2318 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, 2363 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
2319 devctl, &err); 2364 devctl, &err);
2320 if (err) {
2321 brcmf_err("error writing DEVCTL: %d\n",
2322 err);
2323 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2324 }
2325 bus->clkstate = CLK_AVAIL; 2365 bus->clkstate = CLK_AVAIL;
2326 } 2366 }
2327 } 2367 }
2328 2368
2329 /* Make sure backplane clock is on */ 2369 /* Make sure backplane clock is on */
2330 brcmf_sdbrcm_bus_sleep(bus, false, true); 2370 brcmf_sdio_bus_sleep(bus, false, true);
2331 2371
2332 /* Pending interrupt indicates new device status */ 2372 /* Pending interrupt indicates new device status */
2333 if (atomic_read(&bus->ipend) > 0) { 2373 if (atomic_read(&bus->ipend) > 0) {
@@ -2358,7 +2398,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2358 /* Handle host mailbox indication */ 2398 /* Handle host mailbox indication */
2359 if (intstatus & I_HMB_HOST_INT) { 2399 if (intstatus & I_HMB_HOST_INT) {
2360 intstatus &= ~I_HMB_HOST_INT; 2400 intstatus &= ~I_HMB_HOST_INT;
2361 intstatus |= brcmf_sdbrcm_hostmail(bus); 2401 intstatus |= brcmf_sdio_hostmail(bus);
2362 } 2402 }
2363 2403
2364 sdio_release_host(bus->sdiodev->func[1]); 2404 sdio_release_host(bus->sdiodev->func[1]);
@@ -2403,16 +2443,15 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2403 set_bit(n, (unsigned long *)&bus->intstatus.counter); 2443 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2404 } 2444 }
2405 2445
2406 brcmf_sdbrcm_clrintr(bus); 2446 brcmf_sdio_clrintr(bus);
2407 2447
2408 if (data_ok(bus) && bus->ctrl_frame_stat && 2448 if (data_ok(bus) && bus->ctrl_frame_stat &&
2409 (bus->clkstate == CLK_AVAIL)) { 2449 (bus->clkstate == CLK_AVAIL)) {
2410 int i; 2450 int i;
2411 2451
2412 sdio_claim_host(bus->sdiodev->func[1]); 2452 sdio_claim_host(bus->sdiodev->func[1]);
2413 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, 2453 err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf,
2414 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, 2454 (u32)bus->ctrl_frame_len);
2415 (u32) bus->ctrl_frame_len);
2416 2455
2417 if (err < 0) { 2456 if (err < 0) {
2418 /* On failure, abort the command and 2457 /* On failure, abort the command and
@@ -2421,20 +2460,20 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2421 err); 2460 err);
2422 bus->sdcnt.tx_sderrs++; 2461 bus->sdcnt.tx_sderrs++;
2423 2462
2424 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2463 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2425 2464
2426 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2465 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2427 SFC_WF_TERM, &err); 2466 SFC_WF_TERM, &err);
2428 bus->sdcnt.f1regdata++; 2467 bus->sdcnt.f1regdata++;
2429 2468
2430 for (i = 0; i < 3; i++) { 2469 for (i = 0; i < 3; i++) {
2431 u8 hi, lo; 2470 u8 hi, lo;
2432 hi = brcmf_sdio_regrb(bus->sdiodev, 2471 hi = brcmf_sdiod_regrb(bus->sdiodev,
2433 SBSDIO_FUNC1_WFRAMEBCHI, 2472 SBSDIO_FUNC1_WFRAMEBCHI,
2434 &err); 2473 &err);
2435 lo = brcmf_sdio_regrb(bus->sdiodev, 2474 lo = brcmf_sdiod_regrb(bus->sdiodev,
2436 SBSDIO_FUNC1_WFRAMEBCLO, 2475 SBSDIO_FUNC1_WFRAMEBCLO,
2437 &err); 2476 &err);
2438 bus->sdcnt.f1regdata += 2; 2477 bus->sdcnt.f1regdata += 2;
2439 if ((hi == 0) && (lo == 0)) 2478 if ((hi == 0) && (lo == 0))
2440 break; 2479 break;
@@ -2445,7 +2484,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2445 } 2484 }
2446 sdio_release_host(bus->sdiodev->func[1]); 2485 sdio_release_host(bus->sdiodev->func[1]);
2447 bus->ctrl_frame_stat = false; 2486 bus->ctrl_frame_stat = false;
2448 brcmf_sdbrcm_wait_event_wakeup(bus); 2487 brcmf_sdio_wait_event_wakeup(bus);
2449 } 2488 }
2450 /* Send queued frames (limit 1 if rx may still be pending) */ 2489 /* Send queued frames (limit 1 if rx may still be pending) */
2451 else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) && 2490 else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
@@ -2453,13 +2492,12 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2453 && data_ok(bus)) { 2492 && data_ok(bus)) {
2454 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) : 2493 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
2455 txlimit; 2494 txlimit;
2456 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt); 2495 framecnt = brcmf_sdio_sendfromq(bus, framecnt);
2457 txlimit -= framecnt; 2496 txlimit -= framecnt;
2458 } 2497 }
2459 2498
2460 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) { 2499 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
2461 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2500 brcmf_err("failed backplane access over SDIO, halting operation\n");
2462 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2463 atomic_set(&bus->intstatus, 0); 2501 atomic_set(&bus->intstatus, 0);
2464 } else if (atomic_read(&bus->intstatus) || 2502 } else if (atomic_read(&bus->intstatus) ||
2465 atomic_read(&bus->ipend) > 0 || 2503 atomic_read(&bus->ipend) > 0 ||
@@ -2475,12 +2513,12 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2475 bus->activity = false; 2513 bus->activity = false;
2476 brcmf_dbg(SDIO, "idle state\n"); 2514 brcmf_dbg(SDIO, "idle state\n");
2477 sdio_claim_host(bus->sdiodev->func[1]); 2515 sdio_claim_host(bus->sdiodev->func[1]);
2478 brcmf_sdbrcm_bus_sleep(bus, true, false); 2516 brcmf_sdio_bus_sleep(bus, true, false);
2479 sdio_release_host(bus->sdiodev->func[1]); 2517 sdio_release_host(bus->sdiodev->func[1]);
2480 } 2518 }
2481} 2519}
2482 2520
2483static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev) 2521static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
2484{ 2522{
2485 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2523 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2486 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2524 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
@@ -2489,7 +2527,7 @@ static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev)
2489 return &bus->txq; 2527 return &bus->txq;
2490} 2528}
2491 2529
2492static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2530static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2493{ 2531{
2494 int ret = -EBADE; 2532 int ret = -EBADE;
2495 uint datalen, prec; 2533 uint datalen, prec;
@@ -2545,7 +2583,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2545#ifdef DEBUG 2583#ifdef DEBUG
2546#define CONSOLE_LINE_MAX 192 2584#define CONSOLE_LINE_MAX 192
2547 2585
2548static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) 2586static int brcmf_sdio_readconsole(struct brcmf_sdio *bus)
2549{ 2587{
2550 struct brcmf_console *c = &bus->console; 2588 struct brcmf_console *c = &bus->console;
2551 u8 line[CONSOLE_LINE_MAX], ch; 2589 u8 line[CONSOLE_LINE_MAX], ch;
@@ -2558,8 +2596,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
2558 2596
2559 /* Read console log struct */ 2597 /* Read console log struct */
2560 addr = bus->console_addr + offsetof(struct rte_console, log_le); 2598 addr = bus->console_addr + offsetof(struct rte_console, log_le);
2561 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le, 2599 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le,
2562 sizeof(c->log_le)); 2600 sizeof(c->log_le));
2563 if (rv < 0) 2601 if (rv < 0)
2564 return rv; 2602 return rv;
2565 2603
@@ -2584,7 +2622,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
2584 2622
2585 /* Read the console buffer */ 2623 /* Read the console buffer */
2586 addr = le32_to_cpu(c->log_le.buf); 2624 addr = le32_to_cpu(c->log_le.buf);
2587 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize); 2625 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize);
2588 if (rv < 0) 2626 if (rv < 0)
2589 return rv; 2627 return rv;
2590 2628
@@ -2622,14 +2660,13 @@ break2:
2622} 2660}
2623#endif /* DEBUG */ 2661#endif /* DEBUG */
2624 2662
2625static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) 2663static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2626{ 2664{
2627 int i; 2665 int i;
2628 int ret; 2666 int ret;
2629 2667
2630 bus->ctrl_frame_stat = false; 2668 bus->ctrl_frame_stat = false;
2631 ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, 2669 ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
2632 SDIO_FUNC_2, F2SYNC, frame, len);
2633 2670
2634 if (ret < 0) { 2671 if (ret < 0) {
2635 /* On failure, abort the command and terminate the frame */ 2672 /* On failure, abort the command and terminate the frame */
@@ -2637,18 +2674,18 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2637 ret); 2674 ret);
2638 bus->sdcnt.tx_sderrs++; 2675 bus->sdcnt.tx_sderrs++;
2639 2676
2640 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2677 brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
2641 2678
2642 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2679 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2643 SFC_WF_TERM, NULL); 2680 SFC_WF_TERM, NULL);
2644 bus->sdcnt.f1regdata++; 2681 bus->sdcnt.f1regdata++;
2645 2682
2646 for (i = 0; i < 3; i++) { 2683 for (i = 0; i < 3; i++) {
2647 u8 hi, lo; 2684 u8 hi, lo;
2648 hi = brcmf_sdio_regrb(bus->sdiodev, 2685 hi = brcmf_sdiod_regrb(bus->sdiodev,
2649 SBSDIO_FUNC1_WFRAMEBCHI, NULL); 2686 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2650 lo = brcmf_sdio_regrb(bus->sdiodev, 2687 lo = brcmf_sdiod_regrb(bus->sdiodev,
2651 SBSDIO_FUNC1_WFRAMEBCLO, NULL); 2688 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2652 bus->sdcnt.f1regdata += 2; 2689 bus->sdcnt.f1regdata += 2;
2653 if (hi == 0 && lo == 0) 2690 if (hi == 0 && lo == 0)
2654 break; 2691 break;
@@ -2662,10 +2699,10 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2662} 2699}
2663 2700
2664static int 2701static int
2665brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) 2702brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2666{ 2703{
2667 u8 *frame; 2704 u8 *frame;
2668 u16 len; 2705 u16 len, pad;
2669 uint retries = 0; 2706 uint retries = 0;
2670 u8 doff = 0; 2707 u8 doff = 0;
2671 int ret = -1; 2708 int ret = -1;
@@ -2681,41 +2718,45 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2681 len = (msglen += bus->tx_hdrlen); 2718 len = (msglen += bus->tx_hdrlen);
2682 2719
2683 /* Add alignment padding (optional for ctl frames) */ 2720 /* Add alignment padding (optional for ctl frames) */
2684 doff = ((unsigned long)frame % BRCMF_SDALIGN); 2721 doff = ((unsigned long)frame % bus->head_align);
2685 if (doff) { 2722 if (doff) {
2686 frame -= doff; 2723 frame -= doff;
2687 len += doff; 2724 len += doff;
2688 msglen += doff; 2725 msglen += doff;
2689 memset(frame, 0, doff + bus->tx_hdrlen); 2726 memset(frame, 0, doff + bus->tx_hdrlen);
2690 } 2727 }
2691 /* precondition: doff < BRCMF_SDALIGN */ 2728 /* precondition: doff < bus->head_align */
2692 doff += bus->tx_hdrlen; 2729 doff += bus->tx_hdrlen;
2693 2730
2694 /* Round send length to next SDIO block */ 2731 /* Round send length to next SDIO block */
2732 pad = 0;
2695 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { 2733 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2696 u16 pad = bus->blocksize - (len % bus->blocksize); 2734 pad = bus->blocksize - (len % bus->blocksize);
2697 if ((pad <= bus->roundup) && (pad < bus->blocksize)) 2735 if ((pad > bus->roundup) || (pad >= bus->blocksize))
2698 len += pad; 2736 pad = 0;
2699 } else if (len % BRCMF_SDALIGN) { 2737 } else if (len % bus->head_align) {
2700 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); 2738 pad = bus->head_align - (len % bus->head_align);
2701 } 2739 }
2702 2740 len += pad;
2703 /* Satisfy length-alignment requirements */
2704 if (len & (ALIGNMENT - 1))
2705 len = roundup(len, ALIGNMENT);
2706 2741
2707 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ 2742 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2708 2743
2709 /* Make sure backplane clock is on */ 2744 /* Make sure backplane clock is on */
2710 sdio_claim_host(bus->sdiodev->func[1]); 2745 sdio_claim_host(bus->sdiodev->func[1]);
2711 brcmf_sdbrcm_bus_sleep(bus, false, false); 2746 brcmf_sdio_bus_sleep(bus, false, false);
2712 sdio_release_host(bus->sdiodev->func[1]); 2747 sdio_release_host(bus->sdiodev->func[1]);
2713 2748
2714 hd_info.len = (u16)msglen; 2749 hd_info.len = (u16)msglen;
2715 hd_info.channel = SDPCM_CONTROL_CHANNEL; 2750 hd_info.channel = SDPCM_CONTROL_CHANNEL;
2716 hd_info.dat_offset = doff; 2751 hd_info.dat_offset = doff;
2752 hd_info.seq_num = bus->tx_seq;
2753 hd_info.lastfrm = true;
2754 hd_info.tail_pad = pad;
2717 brcmf_sdio_hdpack(bus, frame, &hd_info); 2755 brcmf_sdio_hdpack(bus, frame, &hd_info);
2718 2756
2757 if (bus->txglom)
2758 brcmf_sdio_update_hwhdr(frame, len);
2759
2719 if (!data_ok(bus)) { 2760 if (!data_ok(bus)) {
2720 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", 2761 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
2721 bus->tx_max, bus->tx_seq); 2762 bus->tx_max, bus->tx_seq);
@@ -2746,7 +2787,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2746 2787
2747 do { 2788 do {
2748 sdio_claim_host(bus->sdiodev->func[1]); 2789 sdio_claim_host(bus->sdiodev->func[1]);
2749 ret = brcmf_tx_frame(bus, frame, len); 2790 ret = brcmf_sdio_tx_frame(bus, frame, len);
2750 sdio_release_host(bus->sdiodev->func[1]); 2791 sdio_release_host(bus->sdiodev->func[1]);
2751 } while (ret < 0 && retries++ < TXRETRIES); 2792 } while (ret < 0 && retries++ < TXRETRIES);
2752 } 2793 }
@@ -2756,7 +2797,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2756 bus->activity = false; 2797 bus->activity = false;
2757 sdio_claim_host(bus->sdiodev->func[1]); 2798 sdio_claim_host(bus->sdiodev->func[1]);
2758 brcmf_dbg(INFO, "idle\n"); 2799 brcmf_dbg(INFO, "idle\n");
2759 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); 2800 brcmf_sdio_clkctl(bus, CLK_NONE, true);
2760 sdio_release_host(bus->sdiodev->func[1]); 2801 sdio_release_host(bus->sdiodev->func[1]);
2761 } 2802 }
2762 2803
@@ -2790,8 +2831,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2790 * address of sdpcm_shared structure 2831 * address of sdpcm_shared structure
2791 */ 2832 */
2792 sdio_claim_host(bus->sdiodev->func[1]); 2833 sdio_claim_host(bus->sdiodev->func[1]);
2793 brcmf_sdbrcm_bus_sleep(bus, false, false); 2834 brcmf_sdio_bus_sleep(bus, false, false);
2794 rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); 2835 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
2795 sdio_release_host(bus->sdiodev->func[1]); 2836 sdio_release_host(bus->sdiodev->func[1]);
2796 if (rv < 0) 2837 if (rv < 0)
2797 return rv; 2838 return rv;
@@ -2811,8 +2852,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2811 } 2852 }
2812 2853
2813 /* Read hndrte_shared structure */ 2854 /* Read hndrte_shared structure */
2814 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, 2855 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
2815 sizeof(struct sdpcm_shared_le)); 2856 sizeof(struct sdpcm_shared_le));
2816 if (rv < 0) 2857 if (rv < 0)
2817 return rv; 2858 return rv;
2818 2859
@@ -2848,22 +2889,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2848 2889
2849 /* obtain console information from device memory */ 2890 /* obtain console information from device memory */
2850 addr = sh->console_addr + offsetof(struct rte_console, log_le); 2891 addr = sh->console_addr + offsetof(struct rte_console, log_le);
2851 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, 2892 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr,
2852 (u8 *)&sh_val, sizeof(u32)); 2893 (u8 *)&sh_val, sizeof(u32));
2853 if (rv < 0) 2894 if (rv < 0)
2854 return rv; 2895 return rv;
2855 console_ptr = le32_to_cpu(sh_val); 2896 console_ptr = le32_to_cpu(sh_val);
2856 2897
2857 addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); 2898 addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size);
2858 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, 2899 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr,
2859 (u8 *)&sh_val, sizeof(u32)); 2900 (u8 *)&sh_val, sizeof(u32));
2860 if (rv < 0) 2901 if (rv < 0)
2861 return rv; 2902 return rv;
2862 console_size = le32_to_cpu(sh_val); 2903 console_size = le32_to_cpu(sh_val);
2863 2904
2864 addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); 2905 addr = sh->console_addr + offsetof(struct rte_console, log_le.idx);
2865 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, 2906 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr,
2866 (u8 *)&sh_val, sizeof(u32)); 2907 (u8 *)&sh_val, sizeof(u32));
2867 if (rv < 0) 2908 if (rv < 0)
2868 return rv; 2909 return rv;
2869 console_index = le32_to_cpu(sh_val); 2910 console_index = le32_to_cpu(sh_val);
@@ -2877,8 +2918,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2877 2918
2878 /* obtain the console data from device */ 2919 /* obtain the console data from device */
2879 conbuf[console_size] = '\0'; 2920 conbuf[console_size] = '\0';
2880 rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf, 2921 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf,
2881 console_size); 2922 console_size);
2882 if (rv < 0) 2923 if (rv < 0)
2883 goto done; 2924 goto done;
2884 2925
@@ -2915,8 +2956,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2915 return 0; 2956 return 0;
2916 } 2957 }
2917 2958
2918 error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr, 2959 error = brcmf_sdiod_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr,
2919 sizeof(struct brcmf_trap_info)); 2960 sizeof(struct brcmf_trap_info));
2920 if (error < 0) 2961 if (error < 0)
2921 return error; 2962 return error;
2922 2963
@@ -2959,14 +3000,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2959 3000
2960 sdio_claim_host(bus->sdiodev->func[1]); 3001 sdio_claim_host(bus->sdiodev->func[1]);
2961 if (sh->assert_file_addr != 0) { 3002 if (sh->assert_file_addr != 0) {
2962 error = brcmf_sdio_ramrw(bus->sdiodev, false, 3003 error = brcmf_sdiod_ramrw(bus->sdiodev, false,
2963 sh->assert_file_addr, (u8 *)file, 80); 3004 sh->assert_file_addr, (u8 *)file, 80);
2964 if (error < 0) 3005 if (error < 0)
2965 return error; 3006 return error;
2966 } 3007 }
2967 if (sh->assert_exp_addr != 0) { 3008 if (sh->assert_exp_addr != 0) {
2968 error = brcmf_sdio_ramrw(bus->sdiodev, false, 3009 error = brcmf_sdiod_ramrw(bus->sdiodev, false,
2969 sh->assert_exp_addr, (u8 *)expr, 80); 3010 sh->assert_exp_addr, (u8 *)expr, 80);
2970 if (error < 0) 3011 if (error < 0)
2971 return error; 3012 return error;
2972 } 3013 }
@@ -2978,7 +3019,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2978 return simple_read_from_buffer(data, count, &pos, buf, res); 3019 return simple_read_from_buffer(data, count, &pos, buf, res);
2979} 3020}
2980 3021
2981static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) 3022static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
2982{ 3023{
2983 int error; 3024 int error;
2984 struct sdpcm_shared sh; 3025 struct sdpcm_shared sh;
@@ -2999,8 +3040,8 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
2999 return 0; 3040 return 0;
3000} 3041}
3001 3042
3002static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, 3043static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data,
3003 size_t count, loff_t *ppos) 3044 size_t count, loff_t *ppos)
3004{ 3045{
3005 int error = 0; 3046 int error = 0;
3006 struct sdpcm_shared sh; 3047 struct sdpcm_shared sh;
@@ -3041,7 +3082,7 @@ static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data,
3041 struct brcmf_sdio *bus = f->private_data; 3082 struct brcmf_sdio *bus = f->private_data;
3042 int res; 3083 int res;
3043 3084
3044 res = brcmf_sdbrcm_died_dump(bus, data, count, ppos); 3085 res = brcmf_sdio_died_dump(bus, data, count, ppos);
3045 if (res > 0) 3086 if (res > 0)
3046 *ppos += res; 3087 *ppos += res;
3047 return (ssize_t)res; 3088 return (ssize_t)res;
@@ -3066,7 +3107,7 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3066 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); 3107 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
3067} 3108}
3068#else 3109#else
3069static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) 3110static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
3070{ 3111{
3071 return 0; 3112 return 0;
3072} 3113}
@@ -3077,7 +3118,7 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
3077#endif /* DEBUG */ 3118#endif /* DEBUG */
3078 3119
3079static int 3120static int
3080brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) 3121brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3081{ 3122{
3082 int timeleft; 3123 int timeleft;
3083 uint rxlen = 0; 3124 uint rxlen = 0;
@@ -3090,7 +3131,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3090 brcmf_dbg(TRACE, "Enter\n"); 3131 brcmf_dbg(TRACE, "Enter\n");
3091 3132
3092 /* Wait until control frame is available */ 3133 /* Wait until control frame is available */
3093 timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); 3134 timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending);
3094 3135
3095 spin_lock_bh(&bus->rxctl_lock); 3136 spin_lock_bh(&bus->rxctl_lock);
3096 rxlen = bus->rxlen; 3137 rxlen = bus->rxlen;
@@ -3107,13 +3148,13 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3107 rxlen, msglen); 3148 rxlen, msglen);
3108 } else if (timeleft == 0) { 3149 } else if (timeleft == 0) {
3109 brcmf_err("resumed on timeout\n"); 3150 brcmf_err("resumed on timeout\n");
3110 brcmf_sdbrcm_checkdied(bus); 3151 brcmf_sdio_checkdied(bus);
3111 } else if (pending) { 3152 } else if (pending) {
3112 brcmf_dbg(CTL, "cancelled\n"); 3153 brcmf_dbg(CTL, "cancelled\n");
3113 return -ERESTARTSYS; 3154 return -ERESTARTSYS;
3114 } else { 3155 } else {
3115 brcmf_dbg(CTL, "resumed for unknown reason?\n"); 3156 brcmf_dbg(CTL, "resumed for unknown reason?\n");
3116 brcmf_sdbrcm_checkdied(bus); 3157 brcmf_sdio_checkdied(bus);
3117 } 3158 }
3118 3159
3119 if (rxlen) 3160 if (rxlen)
@@ -3124,46 +3165,69 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3124 return rxlen ? (int)rxlen : -ETIMEDOUT; 3165 return rxlen ? (int)rxlen : -ETIMEDOUT;
3125} 3166}
3126 3167
3127static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) 3168#ifdef DEBUG
3169static bool
3170brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,
3171 u8 *ram_data, uint ram_sz)
3128{ 3172{
3129 struct chip_info *ci = bus->ci; 3173 char *ram_cmp;
3130 3174 int err;
3131 /* To enter download state, disable ARM and reset SOCRAM. 3175 bool ret = true;
3132 * To exit download state, simply reset ARM (default is RAM boot). 3176 int address;
3133 */ 3177 int offset;
3134 if (enter) { 3178 int len;
3135 bus->alp_only = true;
3136 3179
3137 brcmf_sdio_chip_enter_download(bus->sdiodev, ci); 3180 /* read back and verify */
3138 } else { 3181 brcmf_dbg(INFO, "Compare RAM dl & ul at 0x%08x; size=%d\n", ram_addr,
3139 if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars, 3182 ram_sz);
3140 bus->varsz)) 3183 ram_cmp = kmalloc(MEMBLOCK, GFP_KERNEL);
3141 return false; 3184 /* do not proceed while no memory but */
3185 if (!ram_cmp)
3186 return true;
3142 3187
3143 /* Allow HT Clock now that the ARM is running. */ 3188 address = ram_addr;
3144 bus->alp_only = false; 3189 offset = 0;
3145 3190 while (offset < ram_sz) {
3146 bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; 3191 len = ((offset + MEMBLOCK) < ram_sz) ? MEMBLOCK :
3192 ram_sz - offset;
3193 err = brcmf_sdiod_ramrw(sdiodev, false, address, ram_cmp, len);
3194 if (err) {
3195 brcmf_err("error %d on reading %d membytes at 0x%08x\n",
3196 err, len, address);
3197 ret = false;
3198 break;
3199 } else if (memcmp(ram_cmp, &ram_data[offset], len)) {
3200 brcmf_err("Downloaded RAM image is corrupted, block offset is %d, len is %d\n",
3201 offset, len);
3202 ret = false;
3203 break;
3204 }
3205 offset += len;
3206 address += len;
3147 } 3207 }
3148 3208
3209 kfree(ram_cmp);
3210
3211 return ret;
3212}
3213#else /* DEBUG */
3214static bool
3215brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,
3216 u8 *ram_data, uint ram_sz)
3217{
3149 return true; 3218 return true;
3150} 3219}
3220#endif /* DEBUG */
3151 3221
3152static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) 3222static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus,
3223 const struct firmware *fw)
3153{ 3224{
3154 const struct firmware *fw;
3155 int err; 3225 int err;
3156 int offset; 3226 int offset;
3157 int address; 3227 int address;
3158 int len; 3228 int len;
3159 3229
3160 fw = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_BIN); 3230 brcmf_dbg(TRACE, "Enter\n");
3161 if (fw == NULL)
3162 return -ENOENT;
3163
3164 if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) !=
3165 BRCMF_MAX_CORENUM)
3166 memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec));
3167 3231
3168 err = 0; 3232 err = 0;
3169 offset = 0; 3233 offset = 0;
@@ -3171,148 +3235,113 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
3171 while (offset < fw->size) { 3235 while (offset < fw->size) {
3172 len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK : 3236 len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
3173 fw->size - offset; 3237 fw->size - offset;
3174 err = brcmf_sdio_ramrw(bus->sdiodev, true, address, 3238 err = brcmf_sdiod_ramrw(bus->sdiodev, true, address,
3175 (u8 *)&fw->data[offset], len); 3239 (u8 *)&fw->data[offset], len);
3176 if (err) { 3240 if (err) {
3177 brcmf_err("error %d on writing %d membytes at 0x%08x\n", 3241 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3178 err, len, address); 3242 err, len, address);
3179 goto failure; 3243 return err;
3180 } 3244 }
3181 offset += len; 3245 offset += len;
3182 address += len; 3246 address += len;
3183 } 3247 }
3184 3248 if (!err)
3185failure: 3249 if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
3186 release_firmware(fw); 3250 (u8 *)fw->data, fw->size))
3251 err = -EIO;
3187 3252
3188 return err; 3253 return err;
3189} 3254}
3190 3255
3191/* 3256static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
3192 * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file 3257 const struct firmware *nv)
3193 * and ending in a NUL. 3258{
3194 * Removes carriage returns, empty lines, comment lines, and converts 3259 void *vars;
3195 * newlines to NULs. 3260 u32 varsz;
3196 * Shortens buffer as needed and pads with NULs. End of buffer is marked 3261 int address;
3197 * by two NULs. 3262 int err;
3198*/
3199
3200static int brcmf_process_nvram_vars(struct brcmf_sdio *bus,
3201 const struct firmware *nv)
3202{
3203 char *varbuf;
3204 char *dp;
3205 bool findNewline;
3206 int column;
3207 int ret = 0;
3208 uint buf_len, n, len;
3209
3210 len = nv->size;
3211 varbuf = vmalloc(len);
3212 if (!varbuf)
3213 return -ENOMEM;
3214
3215 memcpy(varbuf, nv->data, len);
3216 dp = varbuf;
3217
3218 findNewline = false;
3219 column = 0;
3220
3221 for (n = 0; n < len; n++) {
3222 if (varbuf[n] == 0)
3223 break;
3224 if (varbuf[n] == '\r')
3225 continue;
3226 if (findNewline && varbuf[n] != '\n')
3227 continue;
3228 findNewline = false;
3229 if (varbuf[n] == '#') {
3230 findNewline = true;
3231 continue;
3232 }
3233 if (varbuf[n] == '\n') {
3234 if (column == 0)
3235 continue;
3236 *dp++ = 0;
3237 column = 0;
3238 continue;
3239 }
3240 *dp++ = varbuf[n];
3241 column++;
3242 }
3243 buf_len = dp - varbuf;
3244 while (dp < varbuf + n)
3245 *dp++ = 0;
3246
3247 kfree(bus->vars);
3248 /* roundup needed for download to device */
3249 bus->varsz = roundup(buf_len + 1, 4);
3250 bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
3251 if (bus->vars == NULL) {
3252 bus->varsz = 0;
3253 ret = -ENOMEM;
3254 goto err;
3255 }
3256 3263
3257 /* copy the processed variables and add null termination */ 3264 brcmf_dbg(TRACE, "Enter\n");
3258 memcpy(bus->vars, varbuf, buf_len);
3259 bus->vars[buf_len] = 0;
3260err:
3261 vfree(varbuf);
3262 return ret;
3263}
3264 3265
3265static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) 3266 vars = brcmf_nvram_strip(nv, &varsz);
3266{
3267 const struct firmware *nv;
3268 int ret;
3269 3267
3270 nv = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_NVRAM); 3268 if (vars == NULL)
3271 if (nv == NULL) 3269 return -EINVAL;
3272 return -ENOENT;
3273 3270
3274 ret = brcmf_process_nvram_vars(bus, nv); 3271 address = bus->ci->ramsize - varsz + bus->ci->rambase;
3272 err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);
3273 if (err)
3274 brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",
3275 err, varsz, address);
3276 else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))
3277 err = -EIO;
3275 3278
3276 release_firmware(nv); 3279 brcmf_nvram_free(vars);
3277 3280
3278 return ret; 3281 return err;
3279} 3282}
3280 3283
3281static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) 3284static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
3282{ 3285{
3283 int bcmerror = -1; 3286 int bcmerror = -EFAULT;
3287 const struct firmware *fw;
3288 u32 rstvec;
3289
3290 sdio_claim_host(bus->sdiodev->func[1]);
3291 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
3284 3292
3285 /* Keep arm in reset */ 3293 /* Keep arm in reset */
3286 if (!brcmf_sdbrcm_download_state(bus, true)) { 3294 brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);
3287 brcmf_err("error placing ARM core in reset\n"); 3295
3296 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
3297 if (fw == NULL) {
3298 bcmerror = -ENOENT;
3288 goto err; 3299 goto err;
3289 } 3300 }
3290 3301
3291 if (brcmf_sdbrcm_download_code_file(bus)) { 3302 rstvec = get_unaligned_le32(fw->data);
3303 brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
3304
3305 bcmerror = brcmf_sdio_download_code_file(bus, fw);
3306 release_firmware(fw);
3307 if (bcmerror) {
3292 brcmf_err("dongle image file download failed\n"); 3308 brcmf_err("dongle image file download failed\n");
3293 goto err; 3309 goto err;
3294 } 3310 }
3295 3311
3296 if (brcmf_sdbrcm_download_nvram(bus)) { 3312 fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
3313 if (fw == NULL) {
3314 bcmerror = -ENOENT;
3315 goto err;
3316 }
3317
3318 bcmerror = brcmf_sdio_download_nvram(bus, fw);
3319 release_firmware(fw);
3320 if (bcmerror) {
3297 brcmf_err("dongle nvram file download failed\n"); 3321 brcmf_err("dongle nvram file download failed\n");
3298 goto err; 3322 goto err;
3299 } 3323 }
3300 3324
3301 /* Take arm out of reset */ 3325 /* Take arm out of reset */
3302 if (!brcmf_sdbrcm_download_state(bus, false)) { 3326 if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {
3303 brcmf_err("error getting out of ARM core reset\n"); 3327 brcmf_err("error getting out of ARM core reset\n");
3304 goto err; 3328 goto err;
3305 } 3329 }
3306 3330
3331 /* Allow HT Clock now that the ARM is running. */
3332 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD);
3307 bcmerror = 0; 3333 bcmerror = 0;
3308 3334
3309err: 3335err:
3336 brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
3337 sdio_release_host(bus->sdiodev->func[1]);
3310 return bcmerror; 3338 return bcmerror;
3311} 3339}
3312 3340
3313static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) 3341static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus)
3314{ 3342{
3315 u32 addr, reg; 3343 u32 addr, reg, pmu_cc3_mask = ~0;
3344 int err;
3316 3345
3317 brcmf_dbg(TRACE, "Enter\n"); 3346 brcmf_dbg(TRACE, "Enter\n");
3318 3347
@@ -3320,49 +3349,61 @@ static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus)
3320 if (bus->ci->pmurev < 17) 3349 if (bus->ci->pmurev < 17)
3321 return false; 3350 return false;
3322 3351
3323 /* read PMU chipcontrol register 3*/ 3352 switch (bus->ci->chip) {
3324 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); 3353 case BCM43241_CHIP_ID:
3325 brcmf_sdio_regwl(bus->sdiodev, addr, 3, NULL); 3354 case BCM4335_CHIP_ID:
3326 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); 3355 case BCM4339_CHIP_ID:
3327 reg = brcmf_sdio_regrl(bus->sdiodev, addr, NULL); 3356 /* read PMU chipcontrol register 3 */
3357 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr);
3358 brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL);
3359 addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data);
3360 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
3361 return (reg & pmu_cc3_mask) != 0;
3362 default:
3363 addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext);
3364 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err);
3365 if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
3366 return false;
3328 3367
3329 return (bool)reg; 3368 addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl);
3369 reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
3370 return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
3371 PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
3372 }
3330} 3373}
3331 3374
3332static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) 3375static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
3333{ 3376{
3334 int err = 0; 3377 int err = 0;
3335 u8 val; 3378 u8 val;
3336 3379
3337 brcmf_dbg(TRACE, "Enter\n"); 3380 brcmf_dbg(TRACE, "Enter\n");
3338 3381
3339 val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, 3382 val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
3340 &err);
3341 if (err) { 3383 if (err) {
3342 brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); 3384 brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
3343 return; 3385 return;
3344 } 3386 }
3345 3387
3346 val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; 3388 val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
3347 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, 3389 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
3348 val, &err);
3349 if (err) { 3390 if (err) {
3350 brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); 3391 brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
3351 return; 3392 return;
3352 } 3393 }
3353 3394
3354 /* Add CMD14 Support */ 3395 /* Add CMD14 Support */
3355 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, 3396 brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
3356 (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | 3397 (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
3357 SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), 3398 SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
3358 &err); 3399 &err);
3359 if (err) { 3400 if (err) {
3360 brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); 3401 brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
3361 return; 3402 return;
3362 } 3403 }
3363 3404
3364 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 3405 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3365 SBSDIO_FORCE_HT, &err); 3406 SBSDIO_FORCE_HT, &err);
3366 if (err) { 3407 if (err) {
3367 brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); 3408 brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
3368 return; 3409 return;
@@ -3374,7 +3415,7 @@ static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus)
3374} 3415}
3375 3416
3376/* enable KSO bit */ 3417/* enable KSO bit */
3377static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) 3418static int brcmf_sdio_kso_init(struct brcmf_sdio *bus)
3378{ 3419{
3379 u8 val; 3420 u8 val;
3380 int err = 0; 3421 int err = 0;
@@ -3385,8 +3426,7 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus)
3385 if (bus->ci->c_inf[1].rev < 12) 3426 if (bus->ci->c_inf[1].rev < 12)
3386 return 0; 3427 return 0;
3387 3428
3388 val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 3429 val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
3389 &err);
3390 if (err) { 3430 if (err) {
3391 brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); 3431 brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n");
3392 return err; 3432 return err;
@@ -3395,8 +3435,8 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus)
3395 if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { 3435 if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
3396 val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << 3436 val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN <<
3397 SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); 3437 SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
3398 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, 3438 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
3399 val, &err); 3439 val, &err);
3400 if (err) { 3440 if (err) {
3401 brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); 3441 brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n");
3402 return err; 3442 return err;
@@ -3407,31 +3447,70 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus)
3407} 3447}
3408 3448
3409 3449
3410static bool 3450static int brcmf_sdio_bus_preinit(struct device *dev)
3411brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3412{ 3451{
3413 bool ret; 3452 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3414 3453 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3415 sdio_claim_host(bus->sdiodev->func[1]); 3454 struct brcmf_sdio *bus = sdiodev->bus;
3416 3455 uint pad_size;
3417 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3456 u32 value;
3457 u8 idx;
3458 int err;
3418 3459
3419 ret = _brcmf_sdbrcm_download_firmware(bus) == 0; 3460 /* the commands below use the terms tx and rx from
3461 * a device perspective, ie. bus:txglom affects the
3462 * bus transfers from device to host.
3463 */
3464 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
3465 if (bus->ci->c_inf[idx].rev < 12) {
3466 /* for sdio core rev < 12, disable txgloming */
3467 value = 0;
3468 err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
3469 sizeof(u32));
3470 } else {
3471 /* otherwise, set txglomalign */
3472 value = 4;
3473 if (sdiodev->pdata)
3474 value = sdiodev->pdata->sd_sgentry_align;
3475 /* SDIO ADMA requires at least 32 bit alignment */
3476 value = max_t(u32, value, 4);
3477 err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
3478 sizeof(u32));
3479 }
3420 3480
3421 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); 3481 if (err < 0)
3482 goto done;
3422 3483
3423 sdio_release_host(bus->sdiodev->func[1]); 3484 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
3485 if (sdiodev->sg_support) {
3486 bus->txglom = false;
3487 value = 1;
3488 pad_size = bus->sdiodev->func[2]->cur_blksize << 1;
3489 bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size);
3490 if (!bus->txglom_sgpad)
3491 brcmf_err("allocating txglom padding skb failed, reduced performance\n");
3492
3493 err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom",
3494 &value, sizeof(u32));
3495 if (err < 0) {
3496 /* bus:rxglom is allowed to fail */
3497 err = 0;
3498 } else {
3499 bus->txglom = true;
3500 bus->tx_hdrlen += SDPCM_HWEXT_LEN;
3501 }
3502 }
3503 brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
3424 3504
3425 return ret; 3505done:
3506 return err;
3426} 3507}
3427 3508
3428static int brcmf_sdbrcm_bus_init(struct device *dev) 3509static int brcmf_sdio_bus_init(struct device *dev)
3429{ 3510{
3430 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 3511 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3431 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 3512 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3432 struct brcmf_sdio *bus = sdiodev->bus; 3513 struct brcmf_sdio *bus = sdiodev->bus;
3433 unsigned long timeout;
3434 u8 ready, enable;
3435 int err, ret = 0; 3514 int err, ret = 0;
3436 u8 saveclk; 3515 u8 saveclk;
3437 3516
@@ -3439,8 +3518,11 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3439 3518
3440 /* try to download image and nvram to the dongle */ 3519 /* try to download image and nvram to the dongle */
3441 if (bus_if->state == BRCMF_BUS_DOWN) { 3520 if (bus_if->state == BRCMF_BUS_DOWN) {
3442 if (!(brcmf_sdbrcm_download_firmware(bus))) 3521 bus->alp_only = true;
3443 return -1; 3522 err = brcmf_sdio_download_firmware(bus);
3523 if (err)
3524 return err;
3525 bus->alp_only = false;
3444 } 3526 }
3445 3527
3446 if (!bus->sdiodev->bus_if->drvr) 3528 if (!bus->sdiodev->bus_if->drvr)
@@ -3448,21 +3530,21 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3448 3530
3449 /* Start the watchdog timer */ 3531 /* Start the watchdog timer */
3450 bus->sdcnt.tickcnt = 0; 3532 bus->sdcnt.tickcnt = 0;
3451 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3533 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
3452 3534
3453 sdio_claim_host(bus->sdiodev->func[1]); 3535 sdio_claim_host(bus->sdiodev->func[1]);
3454 3536
3455 /* Make sure backplane clock is on, needed to generate F2 interrupt */ 3537 /* Make sure backplane clock is on, needed to generate F2 interrupt */
3456 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 3538 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
3457 if (bus->clkstate != CLK_AVAIL) 3539 if (bus->clkstate != CLK_AVAIL)
3458 goto exit; 3540 goto exit;
3459 3541
3460 /* Force clocks on backplane to be sure F2 interrupt propagates */ 3542 /* Force clocks on backplane to be sure F2 interrupt propagates */
3461 saveclk = brcmf_sdio_regrb(bus->sdiodev, 3543 saveclk = brcmf_sdiod_regrb(bus->sdiodev,
3462 SBSDIO_FUNC1_CHIPCLKCSR, &err); 3544 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3463 if (!err) { 3545 if (!err) {
3464 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 3546 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3465 (saveclk | SBSDIO_FORCE_HT), &err); 3547 (saveclk | SBSDIO_FORCE_HT), &err);
3466 } 3548 }
3467 if (err) { 3549 if (err) {
3468 brcmf_err("Failed to force clock for F2: err %d\n", err); 3550 brcmf_err("Failed to force clock for F2: err %d\n", err);
@@ -3472,56 +3554,42 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3472 /* Enable function 2 (frame transfers) */ 3554 /* Enable function 2 (frame transfers) */
3473 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, 3555 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
3474 offsetof(struct sdpcmd_regs, tosbmailboxdata)); 3556 offsetof(struct sdpcmd_regs, tosbmailboxdata));
3475 enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); 3557 err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);
3476
3477 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
3478 3558
3479 timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
3480 ready = 0;
3481 while (enable != ready) {
3482 ready = brcmf_sdio_regrb(bus->sdiodev,
3483 SDIO_CCCR_IORx, NULL);
3484 if (time_after(jiffies, timeout))
3485 break;
3486 else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
3487 /* prevent busy waiting if it takes too long */
3488 msleep_interruptible(20);
3489 }
3490 3559
3491 brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready); 3560 brcmf_dbg(INFO, "enable F2: err=%d\n", err);
3492 3561
3493 /* If F2 successfully enabled, set core and enable interrupts */ 3562 /* If F2 successfully enabled, set core and enable interrupts */
3494 if (ready == enable) { 3563 if (!err) {
3495 /* Set up the interrupt mask and enable interrupts */ 3564 /* Set up the interrupt mask and enable interrupts */
3496 bus->hostintmask = HOSTINTMASK; 3565 bus->hostintmask = HOSTINTMASK;
3497 w_sdreg32(bus, bus->hostintmask, 3566 w_sdreg32(bus, bus->hostintmask,
3498 offsetof(struct sdpcmd_regs, hostintmask)); 3567 offsetof(struct sdpcmd_regs, hostintmask));
3499 3568
3500 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); 3569 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
3501 } else { 3570 } else {
3502 /* Disable F2 again */ 3571 /* Disable F2 again */
3503 enable = SDIO_FUNC_ENABLE_1; 3572 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
3504 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
3505 ret = -ENODEV; 3573 ret = -ENODEV;
3506 } 3574 }
3507 3575
3508 if (brcmf_sdbrcm_sr_capable(bus)) { 3576 if (brcmf_sdio_sr_capable(bus)) {
3509 brcmf_sdbrcm_sr_init(bus); 3577 brcmf_sdio_sr_init(bus);
3510 } else { 3578 } else {
3511 /* Restore previous clock setting */ 3579 /* Restore previous clock setting */
3512 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 3580 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3513 saveclk, &err); 3581 saveclk, &err);
3514 } 3582 }
3515 3583
3516 if (ret == 0) { 3584 if (ret == 0) {
3517 ret = brcmf_sdio_intr_register(bus->sdiodev); 3585 ret = brcmf_sdiod_intr_register(bus->sdiodev);
3518 if (ret != 0) 3586 if (ret != 0)
3519 brcmf_err("intr register failed:%d\n", ret); 3587 brcmf_err("intr register failed:%d\n", ret);
3520 } 3588 }
3521 3589
3522 /* If we didn't come up, turn off backplane clock */ 3590 /* If we didn't come up, turn off backplane clock */
3523 if (bus_if->state != BRCMF_BUS_DATA) 3591 if (ret != 0)
3524 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3592 brcmf_sdio_clkctl(bus, CLK_NONE, false);
3525 3593
3526exit: 3594exit:
3527 sdio_release_host(bus->sdiodev->func[1]); 3595 sdio_release_host(bus->sdiodev->func[1]);
@@ -3529,10 +3597,8 @@ exit:
3529 return ret; 3597 return ret;
3530} 3598}
3531 3599
3532void brcmf_sdbrcm_isr(void *arg) 3600void brcmf_sdio_isr(struct brcmf_sdio *bus)
3533{ 3601{
3534 struct brcmf_sdio *bus = (struct brcmf_sdio *) arg;
3535
3536 brcmf_dbg(TRACE, "Enter\n"); 3602 brcmf_dbg(TRACE, "Enter\n");
3537 3603
3538 if (!bus) { 3604 if (!bus) {
@@ -3540,7 +3606,7 @@ void brcmf_sdbrcm_isr(void *arg)
3540 return; 3606 return;
3541 } 3607 }
3542 3608
3543 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { 3609 if (!brcmf_bus_ready(bus->sdiodev->bus_if)) {
3544 brcmf_err("bus is down. we have nothing to do\n"); 3610 brcmf_err("bus is down. we have nothing to do\n");
3545 return; 3611 return;
3546 } 3612 }
@@ -3551,7 +3617,6 @@ void brcmf_sdbrcm_isr(void *arg)
3551 else 3617 else
3552 if (brcmf_sdio_intr_rstatus(bus)) { 3618 if (brcmf_sdio_intr_rstatus(bus)) {
3553 brcmf_err("failed backplane access\n"); 3619 brcmf_err("failed backplane access\n");
3554 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
3555 } 3620 }
3556 3621
3557 /* Disable additional interrupts (is this needed now)? */ 3622 /* Disable additional interrupts (is this needed now)? */
@@ -3562,7 +3627,7 @@ void brcmf_sdbrcm_isr(void *arg)
3562 queue_work(bus->brcmf_wq, &bus->datawork); 3627 queue_work(bus->brcmf_wq, &bus->datawork);
3563} 3628}
3564 3629
3565static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) 3630static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3566{ 3631{
3567#ifdef DEBUG 3632#ifdef DEBUG
3568 struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); 3633 struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
@@ -3586,9 +3651,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3586 u8 devpend; 3651 u8 devpend;
3587 3652
3588 sdio_claim_host(bus->sdiodev->func[1]); 3653 sdio_claim_host(bus->sdiodev->func[1]);
3589 devpend = brcmf_sdio_regrb(bus->sdiodev, 3654 devpend = brcmf_sdiod_regrb(bus->sdiodev,
3590 SDIO_CCCR_INTx, 3655 SDIO_CCCR_INTx,
3591 NULL); 3656 NULL);
3592 sdio_release_host(bus->sdiodev->func[1]); 3657 sdio_release_host(bus->sdiodev->func[1]);
3593 intstatus = 3658 intstatus =
3594 devpend & (INTR_STATUS_FUNC1 | 3659 devpend & (INTR_STATUS_FUNC1 |
@@ -3618,8 +3683,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3618 bus->console.count -= bus->console_interval; 3683 bus->console.count -= bus->console_interval;
3619 sdio_claim_host(bus->sdiodev->func[1]); 3684 sdio_claim_host(bus->sdiodev->func[1]);
3620 /* Make sure backplane clock is on */ 3685 /* Make sure backplane clock is on */
3621 brcmf_sdbrcm_bus_sleep(bus, false, false); 3686 brcmf_sdio_bus_sleep(bus, false, false);
3622 if (brcmf_sdbrcm_readconsole(bus) < 0) 3687 if (brcmf_sdio_readconsole(bus) < 0)
3623 /* stop on error */ 3688 /* stop on error */
3624 bus->console_interval = 0; 3689 bus->console_interval = 0;
3625 sdio_release_host(bus->sdiodev->func[1]); 3690 sdio_release_host(bus->sdiodev->func[1]);
@@ -3633,11 +3698,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3633 bus->idlecount = 0; 3698 bus->idlecount = 0;
3634 if (bus->activity) { 3699 if (bus->activity) {
3635 bus->activity = false; 3700 bus->activity = false;
3636 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3701 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
3637 } else { 3702 } else {
3638 brcmf_dbg(SDIO, "idle\n"); 3703 brcmf_dbg(SDIO, "idle\n");
3639 sdio_claim_host(bus->sdiodev->func[1]); 3704 sdio_claim_host(bus->sdiodev->func[1]);
3640 brcmf_sdbrcm_bus_sleep(bus, true, false); 3705 brcmf_sdio_bus_sleep(bus, true, false);
3641 sdio_release_host(bus->sdiodev->func[1]); 3706 sdio_release_host(bus->sdiodev->func[1]);
3642 } 3707 }
3643 } 3708 }
@@ -3652,38 +3717,13 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3652 datawork); 3717 datawork);
3653 3718
3654 while (atomic_read(&bus->dpc_tskcnt)) { 3719 while (atomic_read(&bus->dpc_tskcnt)) {
3655 brcmf_sdbrcm_dpc(bus); 3720 brcmf_sdio_dpc(bus);
3656 atomic_dec(&bus->dpc_tskcnt); 3721 atomic_dec(&bus->dpc_tskcnt);
3657 } 3722 }
3658} 3723}
3659 3724
3660static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
3661{
3662 brcmf_dbg(TRACE, "Enter\n");
3663
3664 kfree(bus->rxbuf);
3665 bus->rxctl = bus->rxbuf = NULL;
3666 bus->rxlen = 0;
3667}
3668
3669static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
3670{
3671 brcmf_dbg(TRACE, "Enter\n");
3672
3673 if (bus->sdiodev->bus_if->maxctl) {
3674 bus->rxblen =
3675 roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
3676 ALIGNMENT) + BRCMF_SDALIGN;
3677 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
3678 if (!(bus->rxbuf))
3679 return false;
3680 }
3681
3682 return true;
3683}
3684
3685static bool 3725static bool
3686brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) 3726brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3687{ 3727{
3688 u8 clkctl = 0; 3728 u8 clkctl = 0;
3689 int err = 0; 3729 int err = 0;
@@ -3691,23 +3731,21 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3691 u32 reg_val; 3731 u32 reg_val;
3692 u32 drivestrength; 3732 u32 drivestrength;
3693 3733
3694 bus->alp_only = true;
3695
3696 sdio_claim_host(bus->sdiodev->func[1]); 3734 sdio_claim_host(bus->sdiodev->func[1]);
3697 3735
3698 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3736 pr_debug("F1 signature read @0x18000000=0x%4x\n",
3699 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); 3737 brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
3700 3738
3701 /* 3739 /*
3702 * Force PLL off until brcmf_sdio_chip_attach() 3740 * Force PLL off until brcmf_sdio_chip_attach()
3703 * programs PLL control regs 3741 * programs PLL control regs
3704 */ 3742 */
3705 3743
3706 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 3744 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3707 BRCMF_INIT_CLKCTL1, &err); 3745 BRCMF_INIT_CLKCTL1, &err);
3708 if (!err) 3746 if (!err)
3709 clkctl = brcmf_sdio_regrb(bus->sdiodev, 3747 clkctl = brcmf_sdiod_regrb(bus->sdiodev,
3710 SBSDIO_FUNC1_CHIPCLKCSR, &err); 3748 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3711 3749
3712 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { 3750 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
3713 brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", 3751 brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
@@ -3715,12 +3753,17 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3715 goto fail; 3753 goto fail;
3716 } 3754 }
3717 3755
3718 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) { 3756 /* SDIO register access works so moving
3757 * state from UNKNOWN to DOWN.
3758 */
3759 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
3760
3761 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {
3719 brcmf_err("brcmf_sdio_chip_attach failed!\n"); 3762 brcmf_err("brcmf_sdio_chip_attach failed!\n");
3720 goto fail; 3763 goto fail;
3721 } 3764 }
3722 3765
3723 if (brcmf_sdbrcm_kso_init(bus)) { 3766 if (brcmf_sdio_kso_init(bus)) {
3724 brcmf_err("error enabling KSO\n"); 3767 brcmf_err("error enabling KSO\n");
3725 goto fail; 3768 goto fail;
3726 } 3769 }
@@ -3739,33 +3782,33 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3739 } 3782 }
3740 3783
3741 /* Set card control so an SDIO card reset does a WLAN backplane reset */ 3784 /* Set card control so an SDIO card reset does a WLAN backplane reset */
3742 reg_val = brcmf_sdio_regrb(bus->sdiodev, 3785 reg_val = brcmf_sdiod_regrb(bus->sdiodev,
3743 SDIO_CCCR_BRCM_CARDCTRL, &err); 3786 SDIO_CCCR_BRCM_CARDCTRL, &err);
3744 if (err) 3787 if (err)
3745 goto fail; 3788 goto fail;
3746 3789
3747 reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; 3790 reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
3748 3791
3749 brcmf_sdio_regwb(bus->sdiodev, 3792 brcmf_sdiod_regwb(bus->sdiodev,
3750 SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); 3793 SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
3751 if (err) 3794 if (err)
3752 goto fail; 3795 goto fail;
3753 3796
3754 /* set PMUControl so a backplane reset does PMU state reload */ 3797 /* set PMUControl so a backplane reset does PMU state reload */
3755 reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base, 3798 reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base,
3756 pmucontrol); 3799 pmucontrol);
3757 reg_val = brcmf_sdio_regrl(bus->sdiodev, 3800 reg_val = brcmf_sdiod_regrl(bus->sdiodev,
3758 reg_addr, 3801 reg_addr,
3759 &err); 3802 &err);
3760 if (err) 3803 if (err)
3761 goto fail; 3804 goto fail;
3762 3805
3763 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); 3806 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
3764 3807
3765 brcmf_sdio_regwl(bus->sdiodev, 3808 brcmf_sdiod_regwl(bus->sdiodev,
3766 reg_addr, 3809 reg_addr,
3767 reg_val, 3810 reg_val,
3768 &err); 3811 &err);
3769 if (err) 3812 if (err)
3770 goto fail; 3813 goto fail;
3771 3814
@@ -3774,9 +3817,13 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3774 3817
3775 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3818 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3776 3819
3820 /* allocate header buffer */
3821 bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
3822 if (!bus->hdrbuf)
3823 return false;
3777 /* Locate an appropriately-aligned portion of hdrbuf */ 3824 /* Locate an appropriately-aligned portion of hdrbuf */
3778 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], 3825 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
3779 BRCMF_SDALIGN); 3826 bus->head_align);
3780 3827
3781 /* Set the poll and/or interrupt flags */ 3828 /* Set the poll and/or interrupt flags */
3782 bus->intr = true; 3829 bus->intr = true;
@@ -3791,42 +3838,8 @@ fail:
3791 return false; 3838 return false;
3792} 3839}
3793 3840
3794static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
3795{
3796 brcmf_dbg(TRACE, "Enter\n");
3797
3798 sdio_claim_host(bus->sdiodev->func[1]);
3799
3800 /* Disable F2 to clear any intermediate frame state on the dongle */
3801 brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
3802 SDIO_FUNC_ENABLE_1, NULL);
3803
3804 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
3805 bus->rxflow = false;
3806
3807 /* Done with backplane-dependent accesses, can drop clock... */
3808 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3809
3810 sdio_release_host(bus->sdiodev->func[1]);
3811
3812 /* ...and initialize clock/power states */
3813 bus->clkstate = CLK_SDONLY;
3814 bus->idletime = BRCMF_IDLE_INTERVAL;
3815 bus->idleclock = BRCMF_IDLE_ACTIVE;
3816
3817 /* Query the F2 block size, set roundup accordingly */
3818 bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
3819 bus->roundup = min(max_roundup, bus->blocksize);
3820
3821 /* SR state */
3822 bus->sleeping = false;
3823 bus->sr_enabled = false;
3824
3825 return true;
3826}
3827
3828static int 3841static int
3829brcmf_sdbrcm_watchdog_thread(void *data) 3842brcmf_sdio_watchdog_thread(void *data)
3830{ 3843{
3831 struct brcmf_sdio *bus = (struct brcmf_sdio *)data; 3844 struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
3832 3845
@@ -3836,7 +3849,7 @@ brcmf_sdbrcm_watchdog_thread(void *data)
3836 if (kthread_should_stop()) 3849 if (kthread_should_stop())
3837 break; 3850 break;
3838 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { 3851 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
3839 brcmf_sdbrcm_bus_watchdog(bus); 3852 brcmf_sdio_bus_watchdog(bus);
3840 /* Count the tick for reference */ 3853 /* Count the tick for reference */
3841 bus->sdcnt.tickcnt++; 3854 bus->sdcnt.tickcnt++;
3842 } else 3855 } else
@@ -3846,7 +3859,7 @@ brcmf_sdbrcm_watchdog_thread(void *data)
3846} 3859}
3847 3860
3848static void 3861static void
3849brcmf_sdbrcm_watchdog(unsigned long data) 3862brcmf_sdio_watchdog(unsigned long data)
3850{ 3863{
3851 struct brcmf_sdio *bus = (struct brcmf_sdio *)data; 3864 struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
3852 3865
@@ -3859,73 +3872,23 @@ brcmf_sdbrcm_watchdog(unsigned long data)
3859 } 3872 }
3860} 3873}
3861 3874
3862static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
3863{
3864 brcmf_dbg(TRACE, "Enter\n");
3865
3866 if (bus->ci) {
3867 sdio_claim_host(bus->sdiodev->func[1]);
3868 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3869 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3870 sdio_release_host(bus->sdiodev->func[1]);
3871 brcmf_sdio_chip_detach(&bus->ci);
3872 if (bus->vars && bus->varsz)
3873 kfree(bus->vars);
3874 bus->vars = NULL;
3875 }
3876
3877 brcmf_dbg(TRACE, "Disconnected\n");
3878}
3879
3880/* Detach and free everything */
3881static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3882{
3883 brcmf_dbg(TRACE, "Enter\n");
3884
3885 if (bus) {
3886 /* De-register interrupt handler */
3887 brcmf_sdio_intr_unregister(bus->sdiodev);
3888
3889 cancel_work_sync(&bus->datawork);
3890 if (bus->brcmf_wq)
3891 destroy_workqueue(bus->brcmf_wq);
3892
3893 if (bus->sdiodev->bus_if->drvr) {
3894 brcmf_detach(bus->sdiodev->dev);
3895 brcmf_sdbrcm_release_dongle(bus);
3896 }
3897
3898 brcmf_sdbrcm_release_malloc(bus);
3899
3900 kfree(bus);
3901 }
3902
3903 brcmf_dbg(TRACE, "Disconnected\n");
3904}
3905
3906static struct brcmf_bus_ops brcmf_sdio_bus_ops = { 3875static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3907 .stop = brcmf_sdbrcm_bus_stop, 3876 .stop = brcmf_sdio_bus_stop,
3908 .init = brcmf_sdbrcm_bus_init, 3877 .preinit = brcmf_sdio_bus_preinit,
3909 .txdata = brcmf_sdbrcm_bus_txdata, 3878 .init = brcmf_sdio_bus_init,
3910 .txctl = brcmf_sdbrcm_bus_txctl, 3879 .txdata = brcmf_sdio_bus_txdata,
3911 .rxctl = brcmf_sdbrcm_bus_rxctl, 3880 .txctl = brcmf_sdio_bus_txctl,
3912 .gettxq = brcmf_sdbrcm_bus_gettxq, 3881 .rxctl = brcmf_sdio_bus_rxctl,
3882 .gettxq = brcmf_sdio_bus_gettxq,
3913}; 3883};
3914 3884
3915void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) 3885struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
3916{ 3886{
3917 int ret; 3887 int ret;
3918 struct brcmf_sdio *bus; 3888 struct brcmf_sdio *bus;
3919 struct brcmf_bus_dcmd *dlst;
3920 u32 dngl_txglom;
3921 u32 txglomalign = 0;
3922 u8 idx;
3923 3889
3924 brcmf_dbg(TRACE, "Enter\n"); 3890 brcmf_dbg(TRACE, "Enter\n");
3925 3891
3926 /* We make an assumption about address window mappings:
3927 * regsva == SI_ENUM_BASE*/
3928
3929 /* Allocate private bus interface state */ 3892 /* Allocate private bus interface state */
3930 bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC); 3893 bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
3931 if (!bus) 3894 if (!bus)
@@ -3939,6 +3902,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3939 bus->txminmax = BRCMF_TXMINMAX; 3902 bus->txminmax = BRCMF_TXMINMAX;
3940 bus->tx_seq = SDPCM_SEQ_WRAP - 1; 3903 bus->tx_seq = SDPCM_SEQ_WRAP - 1;
3941 3904
3905 /* platform specific configuration:
3906 * alignments must be at least 4 bytes for ADMA
3907 */
3908 bus->head_align = ALIGNMENT;
3909 bus->sgentry_align = ALIGNMENT;
3910 if (sdiodev->pdata) {
3911 if (sdiodev->pdata->sd_head_align > ALIGNMENT)
3912 bus->head_align = sdiodev->pdata->sd_head_align;
3913 if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
3914 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
3915 }
3916
3942 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 3917 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3943 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 3918 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
3944 if (bus->brcmf_wq == NULL) { 3919 if (bus->brcmf_wq == NULL) {
@@ -3947,8 +3922,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3947 } 3922 }
3948 3923
3949 /* attempt to attach to the dongle */ 3924 /* attempt to attach to the dongle */
3950 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { 3925 if (!(brcmf_sdio_probe_attach(bus))) {
3951 brcmf_err("brcmf_sdbrcm_probe_attach failed\n"); 3926 brcmf_err("brcmf_sdio_probe_attach failed\n");
3952 goto fail; 3927 goto fail;
3953 } 3928 }
3954 3929
@@ -3960,11 +3935,11 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3960 /* Set up the watchdog timer */ 3935 /* Set up the watchdog timer */
3961 init_timer(&bus->timer); 3936 init_timer(&bus->timer);
3962 bus->timer.data = (unsigned long)bus; 3937 bus->timer.data = (unsigned long)bus;
3963 bus->timer.function = brcmf_sdbrcm_watchdog; 3938 bus->timer.function = brcmf_sdio_watchdog;
3964 3939
3965 /* Initialize watchdog thread */ 3940 /* Initialize watchdog thread */
3966 init_completion(&bus->watchdog_wait); 3941 init_completion(&bus->watchdog_wait);
3967 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, 3942 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread,
3968 bus, "brcmf_watchdog"); 3943 bus, "brcmf_watchdog");
3969 if (IS_ERR(bus->watchdog_tsk)) { 3944 if (IS_ERR(bus->watchdog_tsk)) {
3970 pr_warn("brcmf_watchdog thread failed to start\n"); 3945 pr_warn("brcmf_watchdog thread failed to start\n");
@@ -3983,50 +3958,52 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3983 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; 3958 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
3984 3959
3985 /* Attach to the common layer, reserve hdr space */ 3960 /* Attach to the common layer, reserve hdr space */
3986 ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev); 3961 ret = brcmf_attach(bus->sdiodev->dev);
3987 if (ret != 0) { 3962 if (ret != 0) {
3988 brcmf_err("brcmf_attach failed\n"); 3963 brcmf_err("brcmf_attach failed\n");
3989 goto fail; 3964 goto fail;
3990 } 3965 }
3991 3966
3992 /* Allocate buffers */ 3967 /* Allocate buffers */
3993 if (!(brcmf_sdbrcm_probe_malloc(bus))) { 3968 if (bus->sdiodev->bus_if->maxctl) {
3994 brcmf_err("brcmf_sdbrcm_probe_malloc failed\n"); 3969 bus->rxblen =
3995 goto fail; 3970 roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
3971 ALIGNMENT) + bus->head_align;
3972 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
3973 if (!(bus->rxbuf)) {
3974 brcmf_err("rxbuf allocation failed\n");
3975 goto fail;
3976 }
3996 } 3977 }
3997 3978
3998 if (!(brcmf_sdbrcm_probe_init(bus))) { 3979 sdio_claim_host(bus->sdiodev->func[1]);
3999 brcmf_err("brcmf_sdbrcm_probe_init failed\n"); 3980
4000 goto fail; 3981 /* Disable F2 to clear any intermediate frame state on the dongle */
4001 } 3982 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
3983
3984 bus->rxflow = false;
3985
3986 /* Done with backplane-dependent accesses, can drop clock... */
3987 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
3988
3989 sdio_release_host(bus->sdiodev->func[1]);
3990
3991 /* ...and initialize clock/power states */
3992 bus->clkstate = CLK_SDONLY;
3993 bus->idletime = BRCMF_IDLE_INTERVAL;
3994 bus->idleclock = BRCMF_IDLE_ACTIVE;
3995
3996 /* Query the F2 block size, set roundup accordingly */
3997 bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
3998 bus->roundup = min(max_roundup, bus->blocksize);
3999
4000 /* SR state */
4001 bus->sleeping = false;
4002 bus->sr_enabled = false;
4002 4003
4003 brcmf_sdio_debugfs_create(bus); 4004 brcmf_sdio_debugfs_create(bus);
4004 brcmf_dbg(INFO, "completed!!\n"); 4005 brcmf_dbg(INFO, "completed!!\n");
4005 4006
4006 /* sdio bus core specific dcmd */
4007 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
4008 dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
4009 if (dlst) {
4010 if (bus->ci->c_inf[idx].rev < 12) {
4011 /* for sdio core rev < 12, disable txgloming */
4012 dngl_txglom = 0;
4013 dlst->name = "bus:txglom";
4014 dlst->param = (char *)&dngl_txglom;
4015 dlst->param_len = sizeof(u32);
4016 } else {
4017 /* otherwise, set txglomalign */
4018 if (sdiodev->pdata)
4019 txglomalign = sdiodev->pdata->sd_sgentry_align;
4020 /* SDIO ADMA requires at least 32 bit alignment */
4021 if (txglomalign < 4)
4022 txglomalign = 4;
4023 dlst->name = "bus:txglomalign";
4024 dlst->param = (char *)&txglomalign;
4025 dlst->param_len = sizeof(u32);
4026 }
4027 list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
4028 }
4029
4030 /* if firmware path present try to download and bring up bus */ 4007 /* if firmware path present try to download and bring up bus */
4031 ret = brcmf_bus_start(bus->sdiodev->dev); 4008 ret = brcmf_bus_start(bus->sdiodev->dev);
4032 if (ret != 0) { 4009 if (ret != 0) {
@@ -4037,24 +4014,55 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4037 return bus; 4014 return bus;
4038 4015
4039fail: 4016fail:
4040 brcmf_sdbrcm_release(bus); 4017 brcmf_sdio_remove(bus);
4041 return NULL; 4018 return NULL;
4042} 4019}
4043 4020
4044void brcmf_sdbrcm_disconnect(void *ptr) 4021/* Detach and free everything */
4022void brcmf_sdio_remove(struct brcmf_sdio *bus)
4045{ 4023{
4046 struct brcmf_sdio *bus = (struct brcmf_sdio *)ptr;
4047
4048 brcmf_dbg(TRACE, "Enter\n"); 4024 brcmf_dbg(TRACE, "Enter\n");
4049 4025
4050 if (bus) 4026 if (bus) {
4051 brcmf_sdbrcm_release(bus); 4027 /* De-register interrupt handler */
4028 brcmf_sdiod_intr_unregister(bus->sdiodev);
4029
4030 cancel_work_sync(&bus->datawork);
4031 if (bus->brcmf_wq)
4032 destroy_workqueue(bus->brcmf_wq);
4033
4034 if (bus->sdiodev->bus_if->drvr) {
4035 brcmf_detach(bus->sdiodev->dev);
4036 }
4037
4038 if (bus->ci) {
4039 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
4040 sdio_claim_host(bus->sdiodev->func[1]);
4041 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4042 /* Leave the device in state where it is
4043 * 'quiet'. This is done by putting it in
4044 * download_state which essentially resets
4045 * all necessary cores.
4046 */
4047 msleep(20);
4048 brcmf_sdio_chip_enter_download(bus->sdiodev,
4049 bus->ci);
4050 brcmf_sdio_clkctl(bus, CLK_NONE, false);
4051 sdio_release_host(bus->sdiodev->func[1]);
4052 }
4053 brcmf_sdio_chip_detach(&bus->ci);
4054 }
4055
4056 brcmu_pkt_buf_free_skb(bus->txglom_sgpad);
4057 kfree(bus->rxbuf);
4058 kfree(bus->hdrbuf);
4059 kfree(bus);
4060 }
4052 4061
4053 brcmf_dbg(TRACE, "Disconnected\n"); 4062 brcmf_dbg(TRACE, "Disconnected\n");
4054} 4063}
4055 4064
4056void 4065void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4057brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4058{ 4066{
4059 /* Totally stop the timer */ 4067 /* Totally stop the timer */
4060 if (!wdtick && bus->wd_timer_valid) { 4068 if (!wdtick && bus->wd_timer_valid) {
@@ -4065,7 +4073,7 @@ brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4065 } 4073 }
4066 4074
4067 /* don't start the wd until fw is loaded */ 4075 /* don't start the wd until fw is loaded */
4068 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) 4076 if (bus->sdiodev->bus_if->state != BRCMF_BUS_DATA)
4069 return; 4077 return;
4070 4078
4071 if (wdtick) { 4079 if (wdtick) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 14bc24dc5bae..51b53a73d074 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -122,6 +122,52 @@ enum brcmf_fweh_event_code {
122#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 122#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
123#define BRCMF_EVENT_MSG_GROUP 0x04 123#define BRCMF_EVENT_MSG_GROUP 0x04
124 124
125/* status field values in struct brcmf_event_msg */
126#define BRCMF_E_STATUS_SUCCESS 0
127#define BRCMF_E_STATUS_FAIL 1
128#define BRCMF_E_STATUS_TIMEOUT 2
129#define BRCMF_E_STATUS_NO_NETWORKS 3
130#define BRCMF_E_STATUS_ABORT 4
131#define BRCMF_E_STATUS_NO_ACK 5
132#define BRCMF_E_STATUS_UNSOLICITED 6
133#define BRCMF_E_STATUS_ATTEMPT 7
134#define BRCMF_E_STATUS_PARTIAL 8
135#define BRCMF_E_STATUS_NEWSCAN 9
136#define BRCMF_E_STATUS_NEWASSOC 10
137#define BRCMF_E_STATUS_11HQUIET 11
138#define BRCMF_E_STATUS_SUPPRESS 12
139#define BRCMF_E_STATUS_NOCHANS 13
140#define BRCMF_E_STATUS_CS_ABORT 15
141#define BRCMF_E_STATUS_ERROR 16
142
143/* reason field values in struct brcmf_event_msg */
144#define BRCMF_E_REASON_INITIAL_ASSOC 0
145#define BRCMF_E_REASON_LOW_RSSI 1
146#define BRCMF_E_REASON_DEAUTH 2
147#define BRCMF_E_REASON_DISASSOC 3
148#define BRCMF_E_REASON_BCNS_LOST 4
149#define BRCMF_E_REASON_MINTXRATE 9
150#define BRCMF_E_REASON_TXFAIL 10
151
152#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
153#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
154#define BRCMF_E_REASON_DIRECTED_ROAM 6
155#define BRCMF_E_REASON_TSPEC_REJECTED 7
156#define BRCMF_E_REASON_BETTER_AP 8
157
158/* action field values for brcmf_ifevent */
159#define BRCMF_E_IF_ADD 1
160#define BRCMF_E_IF_DEL 2
161#define BRCMF_E_IF_CHANGE 3
162
163/* flag field values for brcmf_ifevent */
164#define BRCMF_E_IF_FLAG_NOIF 1
165
166/* role field values for brcmf_ifevent */
167#define BRCMF_E_IF_ROLE_STA 0
168#define BRCMF_E_IF_ROLE_AP 1
169#define BRCMF_E_IF_ROLE_WDS 2
170
125/** 171/**
126 * definitions for event packet validation. 172 * definitions for event packet validation.
127 */ 173 */
@@ -160,6 +206,14 @@ struct brcmf_event_msg {
160 u8 bsscfgidx; 206 u8 bsscfgidx;
161}; 207};
162 208
209struct brcmf_if_event {
210 u8 ifidx;
211 u8 action;
212 u8 flags;
213 u8 bssidx;
214 u8 role;
215};
216
163typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, 217typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
164 const struct brcmf_event_msg *evtmsg, 218 const struct brcmf_event_msg *evtmsg,
165 void *data); 219 void *data);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 04f395930d86..22adbe311d20 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -27,6 +27,7 @@
27#include "dhd_dbg.h" 27#include "dhd_dbg.h"
28#include "tracepoint.h" 28#include "tracepoint.h"
29#include "fwil.h" 29#include "fwil.h"
30#include "proto.h"
30 31
31 32
32#define MAX_HEX_DUMP_LEN 64 33#define MAX_HEX_DUMP_LEN 64
@@ -46,11 +47,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
46 if (data != NULL) 47 if (data != NULL)
47 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 48 len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
48 if (set) 49 if (set)
49 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data, 50 err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
50 len);
51 else 51 else
52 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data, 52 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
53 len);
54 53
55 if (err >= 0) 54 if (err >= 0)
56 err = 0; 55 err = 0;
@@ -69,7 +68,7 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
69 68
70 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); 69 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
71 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 70 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
72 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 71 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
73 72
74 err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); 73 err = brcmf_fil_cmd_data(ifp, cmd, data, len, true);
75 mutex_unlock(&ifp->drvr->proto_block); 74 mutex_unlock(&ifp->drvr->proto_block);
@@ -87,7 +86,7 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
87 86
88 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); 87 brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
89 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 88 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
90 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 89 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
91 90
92 mutex_unlock(&ifp->drvr->proto_block); 91 mutex_unlock(&ifp->drvr->proto_block);
93 92
@@ -156,7 +155,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
156 155
157 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); 156 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
158 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 157 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
159 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 158 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
160 159
161 buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, 160 buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf,
162 sizeof(drvr->proto_buf)); 161 sizeof(drvr->proto_buf));
@@ -196,7 +195,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
196 195
197 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); 196 brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
198 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 197 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
199 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 198 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
200 199
201 mutex_unlock(&drvr->proto_block); 200 mutex_unlock(&drvr->proto_block);
202 return err; 201 return err;
@@ -279,7 +278,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name,
279 278
280 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); 279 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
281 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 280 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
282 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 281 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
283 282
284 buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, 283 buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
285 drvr->proto_buf, sizeof(drvr->proto_buf)); 284 drvr->proto_buf, sizeof(drvr->proto_buf));
@@ -318,7 +317,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
318 } 317 }
319 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); 318 brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
320 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, 319 brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
321 min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); 320 min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
322 321
323 mutex_unlock(&drvr->proto_block); 322 mutex_unlock(&drvr->proto_block);
324 return err; 323 return err;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index 16eb8202fb1e..77eae86e55c2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -17,6 +17,67 @@
17#ifndef _fwil_h_ 17#ifndef _fwil_h_
18#define _fwil_h_ 18#define _fwil_h_
19 19
20/*******************************************************************************
21 * Dongle command codes that are interpreted by firmware
22 ******************************************************************************/
23#define BRCMF_C_GET_VERSION 1
24#define BRCMF_C_UP 2
25#define BRCMF_C_DOWN 3
26#define BRCMF_C_SET_PROMISC 10
27#define BRCMF_C_GET_RATE 12
28#define BRCMF_C_GET_INFRA 19
29#define BRCMF_C_SET_INFRA 20
30#define BRCMF_C_GET_AUTH 21
31#define BRCMF_C_SET_AUTH 22
32#define BRCMF_C_GET_BSSID 23
33#define BRCMF_C_GET_SSID 25
34#define BRCMF_C_SET_SSID 26
35#define BRCMF_C_TERMINATED 28
36#define BRCMF_C_GET_CHANNEL 29
37#define BRCMF_C_SET_CHANNEL 30
38#define BRCMF_C_GET_SRL 31
39#define BRCMF_C_SET_SRL 32
40#define BRCMF_C_GET_LRL 33
41#define BRCMF_C_SET_LRL 34
42#define BRCMF_C_GET_RADIO 37
43#define BRCMF_C_SET_RADIO 38
44#define BRCMF_C_GET_PHYTYPE 39
45#define BRCMF_C_SET_KEY 45
46#define BRCMF_C_SET_PASSIVE_SCAN 49
47#define BRCMF_C_SCAN 50
48#define BRCMF_C_SCAN_RESULTS 51
49#define BRCMF_C_DISASSOC 52
50#define BRCMF_C_REASSOC 53
51#define BRCMF_C_SET_ROAM_TRIGGER 55
52#define BRCMF_C_SET_ROAM_DELTA 57
53#define BRCMF_C_GET_BCNPRD 75
54#define BRCMF_C_SET_BCNPRD 76
55#define BRCMF_C_GET_DTIMPRD 77
56#define BRCMF_C_SET_DTIMPRD 78
57#define BRCMF_C_SET_COUNTRY 84
58#define BRCMF_C_GET_PM 85
59#define BRCMF_C_SET_PM 86
60#define BRCMF_C_GET_CURR_RATESET 114
61#define BRCMF_C_GET_AP 117
62#define BRCMF_C_SET_AP 118
63#define BRCMF_C_GET_RSSI 127
64#define BRCMF_C_GET_WSEC 133
65#define BRCMF_C_SET_WSEC 134
66#define BRCMF_C_GET_PHY_NOISE 135
67#define BRCMF_C_GET_BSS_INFO 136
68#define BRCMF_C_GET_BANDLIST 140
69#define BRCMF_C_SET_SCB_TIMEOUT 158
70#define BRCMF_C_GET_PHYLIST 180
71#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
72#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
73#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
74#define BRCMF_C_GET_VALID_CHANNELS 217
75#define BRCMF_C_GET_KEY_PRIMARY 235
76#define BRCMF_C_SET_KEY_PRIMARY 236
77#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
78#define BRCMF_C_GET_VAR 262
79#define BRCMF_C_SET_VAR 263
80
20s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 81s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
21s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 82s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
22s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); 83s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index ecabb04f33c3..af17a5bc8b83 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -29,6 +29,24 @@
29#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 29#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004
30#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 30#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
31 31
32#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
33#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
34
35#define BRCMF_STA_ASSOC 0x10 /* Associated */
36
37/* size of brcmf_scan_params not including variable length array */
38#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
39
40/* masks for channel and ssid count */
41#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
42#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
43
44/* primary (ie tx) key */
45#define BRCMF_PRIMARY_KEY (1 << 1)
46#define DOT11_BSSTYPE_ANY 2
47#define BRCMF_ESCAN_REQ_VERSION 1
48
49#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
32 50
33enum brcmf_fil_p2p_if_types { 51enum brcmf_fil_p2p_if_types {
34 BRCMF_FIL_P2P_IF_CLIENT, 52 BRCMF_FIL_P2P_IF_CLIENT,
@@ -90,4 +108,290 @@ enum brcmf_tdls_manual_ep_ops {
90 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6 108 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6
91}; 109};
92 110
111/* Pattern matching filter. Specifies an offset within received packets to
112 * start matching, the pattern to match, the size of the pattern, and a bitmask
113 * that indicates which bits within the pattern should be matched.
114 */
115struct brcmf_pkt_filter_pattern_le {
116 /*
117 * Offset within received packet to start pattern matching.
118 * Offset '0' is the first byte of the ethernet header.
119 */
120 __le32 offset;
121 /* Size of the pattern. Bitmask must be the same size.*/
122 __le32 size_bytes;
123 /*
124 * Variable length mask and pattern data. mask starts at offset 0.
125 * Pattern immediately follows mask.
126 */
127 u8 mask_and_pattern[1];
128};
129
130/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
131struct brcmf_pkt_filter_le {
132 __le32 id; /* Unique filter id, specified by app. */
133 __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
134 __le32 negate_match; /* Negate the result of filter matches */
135 union { /* Filter definitions */
136 struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
137 } u;
138};
139
140/* IOVAR "pkt_filter_enable" parameter. */
141struct brcmf_pkt_filter_enable_le {
142 __le32 id; /* Unique filter id */
143 __le32 enable; /* Enable/disable bool */
144};
145
146/* BSS info structure
147 * Applications MUST CHECK ie_offset field and length field to access IEs and
148 * next bss_info structure in a vector (in struct brcmf_scan_results)
149 */
150struct brcmf_bss_info_le {
151 __le32 version; /* version field */
152 __le32 length; /* byte length of data in this record,
153 * starting at version and including IEs
154 */
155 u8 BSSID[ETH_ALEN];
156 __le16 beacon_period; /* units are Kusec */
157 __le16 capability; /* Capability information */
158 u8 SSID_len;
159 u8 SSID[32];
160 struct {
161 __le32 count; /* # rates in this set */
162 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
163 } rateset; /* supported rates */
164 __le16 chanspec; /* chanspec for bss */
165 __le16 atim_window; /* units are Kusec */
166 u8 dtim_period; /* DTIM period */
167 __le16 RSSI; /* receive signal strength (in dBm) */
168 s8 phy_noise; /* noise (in dBm) */
169
170 u8 n_cap; /* BSS is 802.11N Capable */
171 /* 802.11N BSS Capabilities (based on HT_CAP_*): */
172 __le32 nbss_cap;
173 u8 ctl_ch; /* 802.11N BSS control channel number */
174 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
175 u8 flags; /* flags */
176 u8 reserved[3]; /* Reserved for expansion of BSS properties */
177 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
178
179 __le16 ie_offset; /* offset at which IEs start, from beginning */
180 __le32 ie_length; /* byte length of Information Elements */
181 __le16 SNR; /* average SNR of during frame reception */
182 /* Add new fields here */
183 /* variable length Information Elements */
184};
185
186struct brcm_rateset_le {
187 /* # rates in this set */
188 __le32 count;
189 /* rates in 500kbps units w/hi bit set if basic */
190 u8 rates[BRCMF_MAXRATES_IN_SET];
191};
192
193struct brcmf_ssid {
194 u32 SSID_len;
195 unsigned char SSID[32];
196};
197
198struct brcmf_ssid_le {
199 __le32 SSID_len;
200 unsigned char SSID[32];
201};
202
203struct brcmf_scan_params_le {
204 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
205 u8 bssid[ETH_ALEN]; /* default: bcast */
206 s8 bss_type; /* default: any,
207 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
208 */
209 u8 scan_type; /* flags, 0 use default */
210 __le32 nprobes; /* -1 use default, number of probes per channel */
211 __le32 active_time; /* -1 use default, dwell time per channel for
212 * active scanning
213 */
214 __le32 passive_time; /* -1 use default, dwell time per channel
215 * for passive scanning
216 */
217 __le32 home_time; /* -1 use default, dwell time for the
218 * home channel between channel scans
219 */
220 __le32 channel_num; /* count of channels and ssids that follow
221 *
222 * low half is count of channels in
223 * channel_list, 0 means default (use all
224 * available channels)
225 *
226 * high half is entries in struct brcmf_ssid
227 * array that follows channel_list, aligned for
228 * s32 (4 bytes) meaning an odd channel count
229 * implies a 2-byte pad between end of
230 * channel_list and first ssid
231 *
232 * if ssid count is zero, single ssid in the
233 * fixed parameter portion is assumed, otherwise
234 * ssid in the fixed portion is ignored
235 */
236 __le16 channel_list[1]; /* list of chanspecs */
237};
238
239struct brcmf_scan_results {
240 u32 buflen;
241 u32 version;
242 u32 count;
243 struct brcmf_bss_info_le bss_info_le[];
244};
245
246struct brcmf_escan_params_le {
247 __le32 version;
248 __le16 action;
249 __le16 sync_id;
250 struct brcmf_scan_params_le params_le;
251};
252
253struct brcmf_escan_result_le {
254 __le32 buflen;
255 __le32 version;
256 __le16 sync_id;
257 __le16 bss_count;
258 struct brcmf_bss_info_le bss_info_le;
259};
260
261#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
262 sizeof(struct brcmf_bss_info_le))
263
264/* used for association with a specific BSSID and chanspec list */
265struct brcmf_assoc_params_le {
266 /* 00:00:00:00:00:00: broadcast scan */
267 u8 bssid[ETH_ALEN];
268 /* 0: all available channels, otherwise count of chanspecs in
269 * chanspec_list */
270 __le32 chanspec_num;
271 /* list of chanspecs */
272 __le16 chanspec_list[1];
273};
274
275/* used for join with or without a specific bssid and channel list */
276struct brcmf_join_params {
277 struct brcmf_ssid_le ssid_le;
278 struct brcmf_assoc_params_le params_le;
279};
280
281/* scan params for extended join */
282struct brcmf_join_scan_params_le {
283 u8 scan_type; /* 0 use default, active or passive scan */
284 __le32 nprobes; /* -1 use default, nr of probes per channel */
285 __le32 active_time; /* -1 use default, dwell time per channel for
286 * active scanning
287 */
288 __le32 passive_time; /* -1 use default, dwell time per channel
289 * for passive scanning
290 */
291 __le32 home_time; /* -1 use default, dwell time for the home
292 * channel between channel scans
293 */
294};
295
296/* extended join params */
297struct brcmf_ext_join_params_le {
298 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
299 struct brcmf_join_scan_params_le scan_le;
300 struct brcmf_assoc_params_le assoc_le;
301};
302
303struct brcmf_wsec_key {
304 u32 index; /* key index */
305 u32 len; /* key length */
306 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
307 u32 pad_1[18];
308 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
309 u32 flags; /* misc flags */
310 u32 pad_2[3];
311 u32 iv_initialized; /* has IV been initialized already? */
312 u32 pad_3;
313 /* Rx IV */
314 struct {
315 u32 hi; /* upper 32 bits of IV */
316 u16 lo; /* lower 16 bits of IV */
317 } rxiv;
318 u32 pad_4[2];
319 u8 ea[ETH_ALEN]; /* per station */
320};
321
322/*
323 * dongle requires same struct as above but with fields in little endian order
324 */
325struct brcmf_wsec_key_le {
326 __le32 index; /* key index */
327 __le32 len; /* key length */
328 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
329 __le32 pad_1[18];
330 __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
331 __le32 flags; /* misc flags */
332 __le32 pad_2[3];
333 __le32 iv_initialized; /* has IV been initialized already? */
334 __le32 pad_3;
335 /* Rx IV */
336 struct {
337 __le32 hi; /* upper 32 bits of IV */
338 __le16 lo; /* lower 16 bits of IV */
339 } rxiv;
340 __le32 pad_4[2];
341 u8 ea[ETH_ALEN]; /* per station */
342};
343
344/* Used to get specific STA parameters */
345struct brcmf_scb_val_le {
346 __le32 val;
347 u8 ea[ETH_ALEN];
348};
349
350/* channel encoding */
351struct brcmf_channel_info_le {
352 __le32 hw_channel;
353 __le32 target_channel;
354 __le32 scan_channel;
355};
356
357struct brcmf_sta_info_le {
358 __le16 ver; /* version of this struct */
359 __le16 len; /* length in bytes of this structure */
360 __le16 cap; /* sta's advertised capabilities */
361 __le32 flags; /* flags defined below */
362 __le32 idle; /* time since data pkt rx'd from sta */
363 u8 ea[ETH_ALEN]; /* Station address */
364 __le32 count; /* # rates in this set */
365 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
366 /* w/hi bit set if basic */
367 __le32 in; /* seconds elapsed since associated */
368 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
369 __le32 tx_pkts; /* # of packets transmitted */
370 __le32 tx_failures; /* # of packets failed */
371 __le32 rx_ucast_pkts; /* # of unicast packets received */
372 __le32 rx_mcast_pkts; /* # of multicast packets received */
373 __le32 tx_rate; /* Rate of last successful tx frame */
374 __le32 rx_rate; /* Rate of last successful rx frame */
375 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
376 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
377};
378
379struct brcmf_chanspec_list {
380 __le32 count; /* # of entries */
381 __le32 element[1]; /* variable length uint32 list */
382};
383
384/*
385 * WLC_E_PROBRESP_MSG
386 * WLC_E_P2P_PROBREQ_MSG
387 * WLC_E_ACTION_FRAME_RX
388 */
389struct brcmf_rx_mgmt_data {
390 __be16 version;
391 __be16 chanspec;
392 __be32 rssi;
393 __be32 mactime;
394 __be32 rate;
395};
396
93#endif /* FWIL_TYPES_H_ */ 397#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index d0cd0bf95c5a..c3e7d76dbf35 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -27,7 +27,6 @@
27#include <brcmu_utils.h> 27#include <brcmu_utils.h>
28#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
29#include "dhd.h" 29#include "dhd.h"
30#include "dhd_proto.h"
31#include "dhd_dbg.h" 30#include "dhd_dbg.h"
32#include "dhd_bus.h" 31#include "dhd_bus.h"
33#include "fwil.h" 32#include "fwil.h"
@@ -36,6 +35,7 @@
36#include "fwsignal.h" 35#include "fwsignal.h"
37#include "p2p.h" 36#include "p2p.h"
38#include "wl_cfg80211.h" 37#include "wl_cfg80211.h"
38#include "proto.h"
39 39
40/** 40/**
41 * DOC: Firmware Signalling 41 * DOC: Firmware Signalling
@@ -105,6 +105,7 @@ static struct {
105}; 105};
106#undef BRCMF_FWS_TLV_DEF 106#undef BRCMF_FWS_TLV_DEF
107 107
108
108static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) 109static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
109{ 110{
110 int i; 111 int i;
@@ -123,6 +124,12 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
123#endif /* DEBUG */ 124#endif /* DEBUG */
124 125
125/* 126/*
127 * The PKTTAG tlv has additional bytes when firmware-signalling
128 * mode has REUSESEQ flag set.
129 */
130#define BRCMF_FWS_TYPE_SEQ_LEN 2
131
132/*
126 * flags used to enable tlv signalling from firmware. 133 * flags used to enable tlv signalling from firmware.
127 */ 134 */
128#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001 135#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001
@@ -147,8 +154,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
147#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 154#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
148#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 155#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02
149 156
150#define BRCMF_FWS_RET_OK_NOSCHEDULE 0 157#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
151#define BRCMF_FWS_RET_OK_SCHEDULE 1 158#define BRCMF_FWS_RET_OK_SCHEDULE 1
159
160#define BRCMF_FWS_MODE_REUSESEQ_SHIFT 3 /* seq reuse */
161#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val) ((x) = \
162 ((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \
163 (((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT))
164#define BRCMF_FWS_MODE_GET_REUSESEQ(x) \
165 (((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1)
152 166
153/** 167/**
154 * enum brcmf_fws_skb_state - indicates processing state of skb. 168 * enum brcmf_fws_skb_state - indicates processing state of skb.
@@ -171,6 +185,7 @@ enum brcmf_fws_skb_state {
171 * @bus_flags: 2 bytes reserved for bus specific parameters 185 * @bus_flags: 2 bytes reserved for bus specific parameters
172 * @if_flags: holds interface index and packet related flags. 186 * @if_flags: holds interface index and packet related flags.
173 * @htod: host to device packet identifier (used in PKTTAG tlv). 187 * @htod: host to device packet identifier (used in PKTTAG tlv).
188 * @htod_seq: this 16-bit is original seq number for every suppress packet.
174 * @state: transmit state of the packet. 189 * @state: transmit state of the packet.
175 * @mac: descriptor related to destination for this packet. 190 * @mac: descriptor related to destination for this packet.
176 * 191 *
@@ -181,6 +196,7 @@ struct brcmf_skbuff_cb {
181 u16 bus_flags; 196 u16 bus_flags;
182 u16 if_flags; 197 u16 if_flags;
183 u32 htod; 198 u32 htod;
199 u16 htod_seq;
184 enum brcmf_fws_skb_state state; 200 enum brcmf_fws_skb_state state;
185 struct brcmf_fws_mac_descriptor *mac; 201 struct brcmf_fws_mac_descriptor *mac;
186}; 202};
@@ -257,6 +273,22 @@ struct brcmf_skbuff_cb {
257 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ 273 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
258 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) 274 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
259 275
276#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK 0x2000
277#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT 13
278#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK 0x1000
279#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT 12
280#define BRCMF_SKB_HTOD_SEQ_NR_MASK 0x0fff
281#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT 0
282
283#define brcmf_skb_htod_seq_set_field(skb, field, value) \
284 brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \
285 BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
286 BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value))
287#define brcmf_skb_htod_seq_get_field(skb, field) \
288 brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \
289 BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
290 BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT)
291
260#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000 292#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000
261#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31 293#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31
262#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000 294#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000
@@ -265,8 +297,8 @@ struct brcmf_skbuff_cb {
265#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24 297#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24
266#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00 298#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00
267#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8 299#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8
268#define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF 300#define BRCMF_FWS_TXSTAT_FREERUN_MASK 0x000000FF
269#define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0 301#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT 0
270 302
271#define brcmf_txstatus_get_field(txs, field) \ 303#define brcmf_txstatus_get_field(txs, field) \
272 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ 304 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
@@ -443,6 +475,7 @@ struct brcmf_fws_info {
443 unsigned long borrow_defer_timestamp; 475 unsigned long borrow_defer_timestamp;
444 bool bus_flow_blocked; 476 bool bus_flow_blocked;
445 bool creditmap_received; 477 bool creditmap_received;
478 u8 mode;
446}; 479};
447 480
448/* 481/*
@@ -805,20 +838,23 @@ static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
805 brcmf_fws_hanger_cleanup(fws, matchfn, ifidx); 838 brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
806} 839}
807 840
808static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) 841static u8 brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
809{ 842{
810 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 843 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
811 u8 *wlh; 844 u8 *wlh;
812 u16 data_offset = 0; 845 u16 data_offset = 0;
813 u8 fillers; 846 u8 fillers;
814 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); 847 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
848 __le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq);
815 849
816 brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n", 850 brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n",
817 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX), 851 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
818 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); 852 (le32_to_cpu(pkttag) >> 8) & 0xffff,
853 brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq);
819 if (entry->send_tim_signal) 854 if (entry->send_tim_signal)
820 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 855 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
821 856 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
857 data_offset += BRCMF_FWS_TYPE_SEQ_LEN;
822 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ 858 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
823 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN; 859 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
824 fillers = round_up(data_offset, 4) - data_offset; 860 fillers = round_up(data_offset, 4) - data_offset;
@@ -830,7 +866,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
830 wlh[0] = BRCMF_FWS_TYPE_PKTTAG; 866 wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
831 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN; 867 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
832 memcpy(&wlh[2], &pkttag, sizeof(pkttag)); 868 memcpy(&wlh[2], &pkttag, sizeof(pkttag));
833 wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2; 869 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
870 wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN;
871 memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq,
872 sizeof(pktseq));
873 }
874 wlh += wlh[1] + 2;
834 875
835 if (entry->send_tim_signal) { 876 if (entry->send_tim_signal) {
836 entry->send_tim_signal = 0; 877 entry->send_tim_signal = 0;
@@ -846,9 +887,7 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
846 if (fillers) 887 if (fillers)
847 memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers); 888 memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
848 889
849 brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX), 890 return (u8)(data_offset >> 2);
850 data_offset >> 2, skb);
851 return 0;
852} 891}
853 892
854static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, 893static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
@@ -856,10 +895,11 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
856 int fifo, bool send_immediately) 895 int fifo, bool send_immediately)
857{ 896{
858 struct sk_buff *skb; 897 struct sk_buff *skb;
859 struct brcmf_bus *bus;
860 struct brcmf_skbuff_cb *skcb; 898 struct brcmf_skbuff_cb *skcb;
861 s32 err; 899 s32 err;
862 u32 len; 900 u32 len;
901 u8 data_offset;
902 int ifidx;
863 903
864 /* check delayedQ and suppressQ in one call using bitmap */ 904 /* check delayedQ and suppressQ in one call using bitmap */
865 if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0) 905 if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0)
@@ -875,6 +915,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
875 /* create a dummy packet and sent that. The traffic */ 915 /* create a dummy packet and sent that. The traffic */
876 /* bitmap info will automatically be attached to that packet */ 916 /* bitmap info will automatically be attached to that packet */
877 len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 + 917 len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
918 BRCMF_FWS_TYPE_SEQ_LEN +
878 BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 + 919 BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
879 4 + fws->drvr->hdrlen; 920 4 + fws->drvr->hdrlen;
880 skb = brcmu_pkt_buf_get_skb(len); 921 skb = brcmu_pkt_buf_get_skb(len);
@@ -884,13 +925,13 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
884 skcb = brcmf_skbcb(skb); 925 skcb = brcmf_skbcb(skb);
885 skcb->mac = entry; 926 skcb->mac = entry;
886 skcb->state = BRCMF_FWS_SKBSTATE_TIM; 927 skcb->state = BRCMF_FWS_SKBSTATE_TIM;
887 bus = fws->drvr->bus_if; 928 skcb->htod = 0;
888 err = brcmf_fws_hdrpush(fws, skb); 929 skcb->htod_seq = 0;
889 if (err == 0) { 930 data_offset = brcmf_fws_hdrpush(fws, skb);
890 brcmf_fws_unlock(fws); 931 ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
891 err = brcmf_bus_txdata(bus, skb); 932 brcmf_fws_unlock(fws);
892 brcmf_fws_lock(fws); 933 err = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb);
893 } 934 brcmf_fws_lock(fws);
894 if (err) 935 if (err)
895 brcmu_pkt_buf_free_skb(skb); 936 brcmu_pkt_buf_free_skb(skb);
896 return true; 937 return true;
@@ -1172,8 +1213,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
1172{ 1213{
1173 int prec = 2 * fifo; 1214 int prec = 2 * fifo;
1174 u32 *qfull_stat = &fws->stats.delayq_full_error; 1215 u32 *qfull_stat = &fws->stats.delayq_full_error;
1175
1176 struct brcmf_fws_mac_descriptor *entry; 1216 struct brcmf_fws_mac_descriptor *entry;
1217 struct pktq *pq;
1218 struct sk_buff_head *queue;
1219 struct sk_buff *p_head;
1220 struct sk_buff *p_tail;
1221 u32 fr_new;
1222 u32 fr_compare;
1177 1223
1178 entry = brcmf_skbcb(p)->mac; 1224 entry = brcmf_skbcb(p)->mac;
1179 if (entry == NULL) { 1225 if (entry == NULL) {
@@ -1185,9 +1231,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
1185 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { 1231 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
1186 prec += 1; 1232 prec += 1;
1187 qfull_stat = &fws->stats.supprq_full_error; 1233 qfull_stat = &fws->stats.supprq_full_error;
1188 }
1189 1234
1190 if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { 1235 /* Fix out of order delivery of frames. Dont assume frame */
1236 /* can be inserted at the end, but look for correct position */
1237 pq = &entry->psq;
1238 if (pktq_full(pq) || pktq_pfull(pq, prec)) {
1239 *qfull_stat += 1;
1240 return -ENFILE;
1241 }
1242 queue = &pq->q[prec].skblist;
1243
1244 p_head = skb_peek(queue);
1245 p_tail = skb_peek_tail(queue);
1246 fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN);
1247
1248 while (p_head != p_tail) {
1249 fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
1250 FREERUN);
1251 /* be sure to handle wrap of 256 */
1252 if (((fr_new > fr_compare) &&
1253 ((fr_new - fr_compare) < 128)) ||
1254 ((fr_new < fr_compare) &&
1255 ((fr_compare - fr_new) > 128)))
1256 break;
1257 p_tail = skb_queue_prev(queue, p_tail);
1258 }
1259 /* Position found. Determine what to do */
1260 if (p_tail == NULL) {
1261 /* empty list */
1262 __skb_queue_tail(queue, p);
1263 } else {
1264 fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
1265 FREERUN);
1266 if (((fr_new > fr_compare) &&
1267 ((fr_new - fr_compare) < 128)) ||
1268 ((fr_new < fr_compare) &&
1269 ((fr_compare - fr_new) > 128))) {
1270 /* After tail */
1271 __skb_queue_after(queue, p_tail, p);
1272 } else {
1273 /* Before tail */
1274 __skb_insert(p, p_tail->prev, p_tail, queue);
1275 }
1276 }
1277
1278 /* Complete the counters and statistics */
1279 pq->len++;
1280 if (pq->hi_prec < prec)
1281 pq->hi_prec = (u8) prec;
1282 } else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
1191 *qfull_stat += 1; 1283 *qfull_stat += 1;
1192 return -ENFILE; 1284 return -ENFILE;
1193 } 1285 }
@@ -1277,7 +1369,8 @@ done:
1277} 1369}
1278 1370
1279static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, 1371static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1280 struct sk_buff *skb, u32 genbit) 1372 struct sk_buff *skb, u32 genbit,
1373 u16 seq)
1281{ 1374{
1282 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 1375 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1283 u32 hslot; 1376 u32 hslot;
@@ -1297,9 +1390,19 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1297 entry->generation = genbit; 1390 entry->generation = genbit;
1298 1391
1299 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1392 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1300 if (ret == 0) 1393 if (ret == 0) {
1394 brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
1395 brcmf_skbcb(skb)->htod_seq = seq;
1396 if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
1397 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
1398 brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
1399 } else {
1400 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
1401 }
1301 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, 1402 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
1302 skb); 1403 skb);
1404 }
1405
1303 if (ret != 0) { 1406 if (ret != 0) {
1304 /* suppress q is full or hdrpull failed, drop this packet */ 1407 /* suppress q is full or hdrpull failed, drop this packet */
1305 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, 1408 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
@@ -1317,7 +1420,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1317 1420
1318static int 1421static int
1319brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, 1422brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1320 u32 genbit) 1423 u32 genbit, u16 seq)
1321{ 1424{
1322 u32 fifo; 1425 u32 fifo;
1323 int ret; 1426 int ret;
@@ -1360,8 +1463,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1360 if (entry->suppressed && entry->suppr_transit_count) 1463 if (entry->suppressed && entry->suppr_transit_count)
1361 entry->suppr_transit_count--; 1464 entry->suppr_transit_count--;
1362 1465
1363 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, 1466 brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
1364 skcb->htod); 1467 skcb->htod, seq);
1365 1468
1366 /* pick up the implicit credit from this packet */ 1469 /* pick up the implicit credit from this packet */
1367 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO); 1470 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
@@ -1374,7 +1477,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1374 brcmf_fws_macdesc_return_req_credit(skb); 1477 brcmf_fws_macdesc_return_req_credit(skb);
1375 1478
1376 if (!remove_from_hanger) 1479 if (!remove_from_hanger)
1377 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit); 1480 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
1481 seq);
1378 1482
1379 if (remove_from_hanger || ret) 1483 if (remove_from_hanger || ret)
1380 brcmf_txfinalize(fws->drvr, skb, true); 1484 brcmf_txfinalize(fws->drvr, skb, true);
@@ -1406,10 +1510,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1406static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1510static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1407{ 1511{
1408 __le32 status_le; 1512 __le32 status_le;
1513 __le16 seq_le;
1409 u32 status; 1514 u32 status;
1410 u32 hslot; 1515 u32 hslot;
1411 u32 genbit; 1516 u32 genbit;
1412 u8 flags; 1517 u8 flags;
1518 u16 seq;
1413 1519
1414 fws->stats.txs_indicate++; 1520 fws->stats.txs_indicate++;
1415 memcpy(&status_le, data, sizeof(status_le)); 1521 memcpy(&status_le, data, sizeof(status_le));
@@ -1417,9 +1523,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1417 flags = brcmf_txstatus_get_field(status, FLAGS); 1523 flags = brcmf_txstatus_get_field(status, FLAGS);
1418 hslot = brcmf_txstatus_get_field(status, HSLOT); 1524 hslot = brcmf_txstatus_get_field(status, HSLOT);
1419 genbit = brcmf_txstatus_get_field(status, GENERATION); 1525 genbit = brcmf_txstatus_get_field(status, GENERATION);
1526 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
1527 memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
1528 sizeof(seq_le));
1529 seq = le16_to_cpu(seq_le);
1530 } else {
1531 seq = 0;
1532 }
1420 1533
1421 brcmf_fws_lock(fws); 1534 brcmf_fws_lock(fws);
1422 brcmf_fws_txs_process(fws, flags, hslot, genbit); 1535 brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
1423 brcmf_fws_unlock(fws); 1536 brcmf_fws_unlock(fws);
1424 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1537 return BRCMF_FWS_RET_OK_NOSCHEDULE;
1425} 1538}
@@ -1603,15 +1716,15 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1603 return 0; 1716 return 0;
1604} 1717}
1605 1718
1606static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, 1719static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1607 struct sk_buff *p) 1720 struct sk_buff *p)
1608{ 1721{
1609 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1722 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1610 struct brcmf_fws_mac_descriptor *entry = skcb->mac; 1723 struct brcmf_fws_mac_descriptor *entry = skcb->mac;
1611 u8 flags; 1724 u8 flags;
1612 1725
1613 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1726 if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED)
1614 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1727 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
1615 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; 1728 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
1616 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { 1729 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
1617 /* 1730 /*
@@ -1621,7 +1734,7 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1621 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; 1734 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
1622 } 1735 }
1623 brcmf_skb_htod_tag_set_field(p, FLAGS, flags); 1736 brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
1624 brcmf_fws_hdrpush(fws, p); 1737 return brcmf_fws_hdrpush(fws, p);
1625} 1738}
1626 1739
1627static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, 1740static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
@@ -1652,7 +1765,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1652 fws->stats.rollback_failed++; 1765 fws->stats.rollback_failed++;
1653 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1766 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1654 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, 1767 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
1655 hslot, 0); 1768 hslot, 0, 0);
1656 } else { 1769 } else {
1657 fws->stats.rollback_success++; 1770 fws->stats.rollback_success++;
1658 brcmf_fws_return_credits(fws, fifo, 1); 1771 brcmf_fws_return_credits(fws, fifo, 1);
@@ -1689,20 +1802,21 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1689{ 1802{
1690 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); 1803 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
1691 struct brcmf_fws_mac_descriptor *entry; 1804 struct brcmf_fws_mac_descriptor *entry;
1692 struct brcmf_bus *bus = fws->drvr->bus_if;
1693 int rc; 1805 int rc;
1694 u8 ifidx; 1806 u8 ifidx;
1807 u8 data_offset;
1695 1808
1696 entry = skcb->mac; 1809 entry = skcb->mac;
1697 if (IS_ERR(entry)) 1810 if (IS_ERR(entry))
1698 return PTR_ERR(entry); 1811 return PTR_ERR(entry);
1699 1812
1700 brcmf_fws_precommit_skb(fws, fifo, skb); 1813 data_offset = brcmf_fws_precommit_skb(fws, fifo, skb);
1701 entry->transit_count++; 1814 entry->transit_count++;
1702 if (entry->suppressed) 1815 if (entry->suppressed)
1703 entry->suppr_transit_count++; 1816 entry->suppr_transit_count++;
1817 ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
1704 brcmf_fws_unlock(fws); 1818 brcmf_fws_unlock(fws);
1705 rc = brcmf_bus_txdata(bus, skb); 1819 rc = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb);
1706 brcmf_fws_lock(fws); 1820 brcmf_fws_lock(fws);
1707 brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name, 1821 brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
1708 skcb->if_flags, skcb->htod, rc); 1822 skcb->if_flags, skcb->htod, rc);
@@ -1732,6 +1846,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
1732 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1846 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1733 int rc, hslot; 1847 int rc, hslot;
1734 1848
1849 skcb->htod = 0;
1850 skcb->htod_seq = 0;
1735 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); 1851 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1736 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); 1852 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1737 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]); 1853 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
@@ -1757,7 +1873,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1757 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); 1873 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
1758 /* determine the priority */ 1874 /* determine the priority */
1759 if (!skb->priority) 1875 if (!skb->priority)
1760 skb->priority = cfg80211_classify8021d(skb); 1876 skb->priority = cfg80211_classify8021d(skb, NULL);
1761 1877
1762 drvr->tx_multicast += !!multicast; 1878 drvr->tx_multicast += !!multicast;
1763 if (pae) 1879 if (pae)
@@ -1861,10 +1977,9 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
1861 &skb, true); 1977 &skb, true);
1862 ifidx = brcmf_skb_if_flags_get_field(skb, 1978 ifidx = brcmf_skb_if_flags_get_field(skb,
1863 INDEX); 1979 INDEX);
1864 brcmf_proto_hdrpush(drvr, ifidx, 0, skb); 1980 /* Use proto layer to send data frame */
1865 /* Use bus module to send data frame */
1866 brcmf_fws_unlock(fws); 1981 brcmf_fws_unlock(fws);
1867 ret = brcmf_bus_txdata(drvr->bus_if, skb); 1982 ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
1868 brcmf_fws_lock(fws); 1983 brcmf_fws_lock(fws);
1869 if (ret < 0) 1984 if (ret < 0)
1870 brcmf_txfinalize(drvr, skb, false); 1985 brcmf_txfinalize(drvr, skb, false);
@@ -1908,6 +2023,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
1908 struct brcmf_fws_info *fws; 2023 struct brcmf_fws_info *fws;
1909 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; 2024 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
1910 int rc; 2025 int rc;
2026 u32 mode;
1911 2027
1912 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); 2028 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
1913 if (!drvr->fws) { 2029 if (!drvr->fws) {
@@ -1966,6 +2082,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
1966 if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) 2082 if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
1967 brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); 2083 brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
1968 2084
2085 /* Enable seq number reuse, if supported */
2086 if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
2087 if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
2088 mode = 0;
2089 BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
2090 if (brcmf_fil_iovar_int_set(drvr->iflist[0],
2091 "wlfc_mode", mode) == 0) {
2092 BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
2093 }
2094 }
2095 }
2096
1969 brcmf_fws_hanger_init(&fws->hanger); 2097 brcmf_fws_hanger_init(&fws->hanger);
1970 brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0); 2098 brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0);
1971 brcmf_fws_macdesc_set_name(fws, &fws->desc.other); 2099 brcmf_fws_macdesc_set_name(fws, &fws->desc.other);
@@ -2022,7 +2150,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
2022 } 2150 }
2023 brcmf_fws_lock(fws); 2151 brcmf_fws_lock(fws);
2024 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 2152 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
2025 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0); 2153 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
2026 brcmf_fws_unlock(fws); 2154 brcmf_fws_unlock(fws);
2027} 2155}
2028 2156
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
new file mode 100644
index 000000000000..d5ef86db631b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/slab.h>
19#include <linux/firmware.h>
20
21#include "nvram.h"
22
23/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
24 * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
25 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
26 * End of buffer is completed with token identifying length of buffer.
27 */
28void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
29{
30 u8 *nvram;
31 u32 i;
32 u32 len;
33 u32 column;
34 u8 val;
35 bool comment;
36 u32 token;
37 __le32 token_le;
38
39 /* Alloc for extra 0 byte + roundup by 4 + length field */
40 nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
41 if (!nvram)
42 return NULL;
43
44 len = 0;
45 column = 0;
46 comment = false;
47 for (i = 0; i < nv->size; i++) {
48 val = nv->data[i];
49 if (val == 0)
50 break;
51 if (val == '\r')
52 continue;
53 if (comment && (val != '\n'))
54 continue;
55 comment = false;
56 if (val == '#') {
57 comment = true;
58 continue;
59 }
60 if (val == '\n') {
61 if (column == 0)
62 continue;
63 nvram[len] = 0;
64 len++;
65 column = 0;
66 continue;
67 }
68 nvram[len] = val;
69 len++;
70 column++;
71 }
72 column = len;
73 *new_length = roundup(len + 1, 4);
74 while (column != *new_length) {
75 nvram[column] = 0;
76 column++;
77 }
78
79 token = *new_length / 4;
80 token = (~token << 16) | (token & 0x0000FFFF);
81 token_le = cpu_to_le32(token);
82
83 memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
84 *new_length += sizeof(token_le);
85
86 return nvram;
87}
88
89void brcmf_nvram_free(void *nvram)
90{
91 kfree(nvram);
92}
93
94
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.h b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
new file mode 100644
index 000000000000..d454580928c9
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef BRCMFMAC_NVRAM_H
17#define BRCMFMAC_NVRAM_H
18
19
20void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);
21void brcmf_nvram_free(void *nvram);
22
23
24#endif /* BRCMFMAC_NVRAM_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 4a2293041821..fc4f98b275d7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
812 struct ieee80211_channel *chan = request->channels[i]; 812 struct ieee80211_channel *chan = request->channels[i];
813 813
814 if (chan->flags & (IEEE80211_CHAN_RADAR | 814 if (chan->flags & (IEEE80211_CHAN_RADAR |
815 IEEE80211_CHAN_PASSIVE_SCAN)) 815 IEEE80211_CHAN_NO_IR))
816 continue; 816 continue;
817 817
818 chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, 818 chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf,
@@ -1243,7 +1243,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
1243 IEEE80211_P2P_ATTR_DEVICE_ID, 1243 IEEE80211_P2P_ATTR_DEVICE_ID,
1244 p2p_dev_addr, sizeof(p2p_dev_addr)); 1244 p2p_dev_addr, sizeof(p2p_dev_addr));
1245 if ((err >= 0) && 1245 if ((err >= 0) &&
1246 (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) { 1246 (ether_addr_equal(p2p_dev_addr, afx_hdl->tx_dst_addr))) {
1247 if (!bi->ctl_ch) { 1247 if (!bi->ctl_ch) {
1248 ch.chspec = le16_to_cpu(bi->chanspec); 1248 ch.chspec = le16_to_cpu(bi->chanspec);
1249 cfg->d11inf.decchspec(&ch); 1249 cfg->d11inf.decchspec(&ch);
@@ -1380,8 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1380 (brcmf_p2p_gon_req_collision(p2p, (u8 *)e->addr))) { 1380 (brcmf_p2p_gon_req_collision(p2p, (u8 *)e->addr))) {
1381 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, 1381 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
1382 &p2p->status) && 1382 &p2p->status) &&
1383 (memcmp(afx_hdl->tx_dst_addr, e->addr, 1383 (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
1384 ETH_ALEN) == 0)) {
1385 afx_hdl->peer_chan = ch.chnum; 1384 afx_hdl->peer_chan = ch.chnum;
1386 brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", 1385 brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
1387 afx_hdl->peer_chan); 1386 afx_hdl->peer_chan);
@@ -1865,7 +1864,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1865 cfg->d11inf.decchspec(&ch); 1864 cfg->d11inf.decchspec(&ch);
1866 1865
1867 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && 1866 if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
1868 (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { 1867 (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
1869 afx_hdl->peer_chan = ch.chnum; 1868 afx_hdl->peer_chan = ch.chnum;
1870 brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", 1869 brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
1871 afx_hdl->peer_chan); 1870 afx_hdl->peer_chan);
@@ -1956,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1956 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); 1955 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
1957 if (err < 0) { 1956 if (err < 0) {
1958 brcmf_err("set p2p_disc error\n"); 1957 brcmf_err("set p2p_disc error\n");
1959 brcmf_free_vif(cfg, p2p_vif); 1958 brcmf_free_vif(p2p_vif);
1960 goto exit; 1959 goto exit;
1961 } 1960 }
1962 /* obtain bsscfg index for P2P discovery */ 1961 /* obtain bsscfg index for P2P discovery */
1963 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); 1962 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
1964 if (err < 0) { 1963 if (err < 0) {
1965 brcmf_err("retrieving discover bsscfg index failed\n"); 1964 brcmf_err("retrieving discover bsscfg index failed\n");
1966 brcmf_free_vif(cfg, p2p_vif); 1965 brcmf_free_vif(p2p_vif);
1967 goto exit; 1966 goto exit;
1968 } 1967 }
1969 /* Verify that firmware uses same bssidx as driver !! */ 1968 /* Verify that firmware uses same bssidx as driver !! */
1970 if (p2p_ifp->bssidx != bssidx) { 1969 if (p2p_ifp->bssidx != bssidx) {
1971 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", 1970 brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
1972 bssidx, p2p_ifp->bssidx); 1971 bssidx, p2p_ifp->bssidx);
1973 brcmf_free_vif(cfg, p2p_vif); 1972 brcmf_free_vif(p2p_vif);
1974 goto exit; 1973 goto exit;
1975 } 1974 }
1976 1975
@@ -1998,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
1998 brcmf_p2p_cancel_remain_on_channel(vif->ifp); 1997 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
1999 brcmf_p2p_deinit_discovery(p2p); 1998 brcmf_p2p_deinit_discovery(p2p);
2000 /* remove discovery interface */ 1999 /* remove discovery interface */
2001 brcmf_free_vif(p2p->cfg, vif); 2000 brcmf_free_vif(vif);
2002 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; 2001 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2003 } 2002 }
2004 /* just set it all to zero */ 2003 /* just set it all to zero */
@@ -2223,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
2223 return &p2p_vif->wdev; 2222 return &p2p_vif->wdev;
2224 2223
2225fail: 2224fail:
2226 brcmf_free_vif(p2p->cfg, p2p_vif); 2225 brcmf_free_vif(p2p_vif);
2227 return ERR_PTR(err); 2226 return ERR_PTR(err);
2228} 2227}
2229 2228
@@ -2232,31 +2231,12 @@ fail:
2232 * 2231 *
2233 * @vif: virtual interface object to delete. 2232 * @vif: virtual interface object to delete.
2234 */ 2233 */
2235static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg, 2234static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p,
2236 struct brcmf_cfg80211_vif *vif) 2235 struct brcmf_cfg80211_vif *vif)
2237{ 2236{
2238 cfg80211_unregister_wdev(&vif->wdev); 2237 cfg80211_unregister_wdev(&vif->wdev);
2239 cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; 2238 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2240 brcmf_free_vif(cfg, vif); 2239 brcmf_free_vif(vif);
2241}
2242
2243/**
2244 * brcmf_p2p_free_p2p_if() - free up net device related data.
2245 *
2246 * @ndev: net device that needs to be freed.
2247 */
2248static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
2249{
2250 struct brcmf_cfg80211_info *cfg;
2251 struct brcmf_cfg80211_vif *vif;
2252 struct brcmf_if *ifp;
2253
2254 ifp = netdev_priv(ndev);
2255 cfg = ifp->drvr->config;
2256 vif = ifp->vif;
2257
2258 brcmf_free_vif(cfg, vif);
2259 free_netdev(ifp->ndev);
2260} 2240}
2261 2241
2262/** 2242/**
@@ -2336,8 +2316,6 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2336 brcmf_err("Registering netdevice failed\n"); 2316 brcmf_err("Registering netdevice failed\n");
2337 goto fail; 2317 goto fail;
2338 } 2318 }
2339 /* override destructor */
2340 ifp->ndev->destructor = brcmf_p2p_free_p2p_if;
2341 2319
2342 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; 2320 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
2343 /* Disable firmware roaming for P2P interface */ 2321 /* Disable firmware roaming for P2P interface */
@@ -2350,7 +2328,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2350 return &ifp->vif->wdev; 2328 return &ifp->vif->wdev;
2351 2329
2352fail: 2330fail:
2353 brcmf_free_vif(cfg, vif); 2331 brcmf_free_vif(vif);
2354 return ERR_PTR(err); 2332 return ERR_PTR(err);
2355} 2333}
2356 2334
@@ -2359,8 +2337,6 @@ fail:
2359 * 2337 *
2360 * @wiphy: wiphy device of interface. 2338 * @wiphy: wiphy device of interface.
2361 * @wdev: wireless device of interface. 2339 * @wdev: wireless device of interface.
2362 *
2363 * TODO: not yet supported.
2364 */ 2340 */
2365int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) 2341int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2366{ 2342{
@@ -2386,7 +2362,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2386 break; 2362 break;
2387 2363
2388 case NL80211_IFTYPE_P2P_DEVICE: 2364 case NL80211_IFTYPE_P2P_DEVICE:
2389 brcmf_p2p_delete_p2pdev(cfg, vif); 2365 brcmf_p2p_delete_p2pdev(p2p, vif);
2390 return 0; 2366 return 0;
2391 default: 2367 default:
2392 return -ENOTSUPP; 2368 return -ENOTSUPP;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
new file mode 100644
index 000000000000..b6b464184946
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18 #include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/netdevice.h>
21
22#include <brcmu_wifi.h>
23#include "dhd.h"
24#include "dhd_dbg.h"
25#include "proto.h"
26#include "bcdc.h"
27
28
29int brcmf_proto_attach(struct brcmf_pub *drvr)
30{
31 struct brcmf_proto *proto;
32
33 proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
34 if (!proto)
35 goto fail;
36
37 drvr->proto = proto;
38 /* BCDC protocol is only protocol supported for the moment */
39 if (brcmf_proto_bcdc_attach(drvr))
40 goto fail;
41
42 if ((proto->txdata == NULL) || (proto->hdrpull == NULL) ||
43 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) {
44 brcmf_err("Not all proto handlers have been installed\n");
45 goto fail;
46 }
47 return 0;
48
49fail:
50 kfree(proto);
51 drvr->proto = NULL;
52 return -ENOMEM;
53}
54
55void brcmf_proto_detach(struct brcmf_pub *drvr)
56{
57 if (drvr->proto) {
58 brcmf_proto_bcdc_detach(drvr);
59 kfree(drvr->proto);
60 drvr->proto = NULL;
61 }
62}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
new file mode 100644
index 000000000000..482fb0ba4a30
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef BRCMFMAC_PROTO_H
17#define BRCMFMAC_PROTO_H
18
19struct brcmf_proto {
20 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
21 struct sk_buff *skb);
22 int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
23 void *buf, uint len);
24 int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
25 uint len);
26 int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
27 struct sk_buff *skb);
28 void *pd;
29};
30
31
32int brcmf_proto_attach(struct brcmf_pub *drvr);
33void brcmf_proto_detach(struct brcmf_pub *drvr);
34
35static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
36 u8 *ifidx, struct sk_buff *skb)
37{
38 return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
39}
40static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
41 uint cmd, void *buf, uint len)
42{
43 return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
44}
45static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
46 uint cmd, void *buf, uint len)
47{
48 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
49}
50static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx,
51 u8 offset, struct sk_buff *skb)
52{
53 return drvr->proto->txdata(drvr, ifidx, offset, skb);
54}
55
56
57#endif /* BRCMFMAC_PROTO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 2096a14ef1fb..82bf3c5d3cdc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -19,6 +19,7 @@
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/mmc/card.h> 20#include <linux/mmc/card.h>
21#include <linux/mmc/sdio_func.h> 21#include <linux/mmc/sdio_func.h>
22#include <linux/mmc/sdio_ids.h>
22#include <linux/ssb/ssb_regs.h> 23#include <linux/ssb/ssb_regs.h>
23#include <linux/bcma/bcma.h> 24#include <linux/bcma/bcma.h>
24 25
@@ -50,6 +51,9 @@
50#define BCM43143_CORE_ARM_BASE 0x18003000 51#define BCM43143_CORE_ARM_BASE 0x18003000
51#define BCM43143_RAMSIZE 0x70000 52#define BCM43143_RAMSIZE 0x70000
52 53
54/* All D11 cores, ID 0x812 */
55#define BCM43xx_CORE_D11_BASE 0x18001000
56
53#define SBCOREREV(sbidh) \ 57#define SBCOREREV(sbidh) \
54 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ 58 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
55 ((sbidh) & SSB_IDHIGH_RCLO)) 59 ((sbidh) & SSB_IDHIGH_RCLO))
@@ -65,6 +69,10 @@
65/* ARM CR4 core specific control flag bits */ 69/* ARM CR4 core specific control flag bits */
66#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 70#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
67 71
72/* D11 core specific control flag bits */
73#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
74#define D11_BCMA_IOCTL_PHYRESET 0x0008
75
68#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) 76#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
69/* SDIO Pad drive strength to select value mappings */ 77/* SDIO Pad drive strength to select value mappings */
70struct sdiod_drive_str { 78struct sdiod_drive_str {
@@ -83,6 +91,24 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
83 {0, 0x1} 91 {0, 0x1}
84}; 92};
85 93
94/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
95static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
96 {6, 0x7},
97 {5, 0x6},
98 {4, 0x5},
99 {3, 0x4},
100 {2, 0x2},
101 {1, 0x1},
102 {0, 0x0}
103};
104
105/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
106static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
107 {3, 0x3},
108 {2, 0x2},
109 {1, 0x1},
110 {0, 0x0} };
111
86/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ 112/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
87static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { 113static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
88 {16, 0x7}, 114 {16, 0x7},
@@ -92,7 +118,7 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
92}; 118};
93 119
94u8 120u8
95brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) 121brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
96{ 122{
97 u8 idx; 123 u8 idx;
98 124
@@ -105,22 +131,22 @@ brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
105 131
106static u32 132static u32
107brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, 133brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
108 struct chip_info *ci, u16 coreid) 134 struct brcmf_chip *ci, u16 coreid)
109{ 135{
110 u32 regdata; 136 u32 regdata;
111 u8 idx; 137 u8 idx;
112 138
113 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 139 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
114 140
115 regdata = brcmf_sdio_regrl(sdiodev, 141 regdata = brcmf_sdiod_regrl(sdiodev,
116 CORE_SB(ci->c_inf[idx].base, sbidhigh), 142 CORE_SB(ci->c_inf[idx].base, sbidhigh),
117 NULL); 143 NULL);
118 return SBCOREREV(regdata); 144 return SBCOREREV(regdata);
119} 145}
120 146
121static u32 147static u32
122brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, 148brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
123 struct chip_info *ci, u16 coreid) 149 struct brcmf_chip *ci, u16 coreid)
124{ 150{
125 u8 idx; 151 u8 idx;
126 152
@@ -131,7 +157,7 @@ brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
131 157
132static bool 158static bool
133brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, 159brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
134 struct chip_info *ci, u16 coreid) 160 struct brcmf_chip *ci, u16 coreid)
135{ 161{
136 u32 regdata; 162 u32 regdata;
137 u8 idx; 163 u8 idx;
@@ -140,9 +166,9 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
140 if (idx == BRCMF_MAX_CORENUM) 166 if (idx == BRCMF_MAX_CORENUM)
141 return false; 167 return false;
142 168
143 regdata = brcmf_sdio_regrl(sdiodev, 169 regdata = brcmf_sdiod_regrl(sdiodev,
144 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 170 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
145 NULL); 171 NULL);
146 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | 172 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
147 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); 173 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
148 return (SSB_TMSLOW_CLOCK == regdata); 174 return (SSB_TMSLOW_CLOCK == regdata);
@@ -150,7 +176,7 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
150 176
151static bool 177static bool
152brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, 178brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
153 struct chip_info *ci, u16 coreid) 179 struct brcmf_chip *ci, u16 coreid)
154{ 180{
155 u32 regdata; 181 u32 regdata;
156 u8 idx; 182 u8 idx;
@@ -160,13 +186,13 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
160 if (idx == BRCMF_MAX_CORENUM) 186 if (idx == BRCMF_MAX_CORENUM)
161 return false; 187 return false;
162 188
163 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 189 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
164 NULL); 190 NULL);
165 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; 191 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
166 192
167 regdata = brcmf_sdio_regrl(sdiodev, 193 regdata = brcmf_sdiod_regrl(sdiodev,
168 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, 194 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
169 NULL); 195 NULL);
170 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); 196 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
171 197
172 return ret; 198 return ret;
@@ -174,7 +200,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
174 200
175static void 201static void
176brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, 202brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
177 struct chip_info *ci, u16 coreid, u32 core_bits) 203 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
204 u32 in_resetbits)
178{ 205{
179 u32 regdata, base; 206 u32 regdata, base;
180 u8 idx; 207 u8 idx;
@@ -182,130 +209,126 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
182 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 209 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
183 base = ci->c_inf[idx].base; 210 base = ci->c_inf[idx].base;
184 211
185 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); 212 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
186 if (regdata & SSB_TMSLOW_RESET) 213 if (regdata & SSB_TMSLOW_RESET)
187 return; 214 return;
188 215
189 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); 216 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
190 if ((regdata & SSB_TMSLOW_CLOCK) != 0) { 217 if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
191 /* 218 /*
192 * set target reject and spin until busy is clear 219 * set target reject and spin until busy is clear
193 * (preserve core-specific bits) 220 * (preserve core-specific bits)
194 */ 221 */
195 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), 222 regdata = brcmf_sdiod_regrl(sdiodev,
196 NULL); 223 CORE_SB(base, sbtmstatelow), NULL);
197 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), 224 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
198 regdata | SSB_TMSLOW_REJECT, NULL); 225 regdata | SSB_TMSLOW_REJECT, NULL);
199 226
200 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), 227 regdata = brcmf_sdiod_regrl(sdiodev,
201 NULL); 228 CORE_SB(base, sbtmstatelow), NULL);
202 udelay(1); 229 udelay(1);
203 SPINWAIT((brcmf_sdio_regrl(sdiodev, 230 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
204 CORE_SB(base, sbtmstatehigh), 231 CORE_SB(base, sbtmstatehigh),
205 NULL) & 232 NULL) &
206 SSB_TMSHIGH_BUSY), 100000); 233 SSB_TMSHIGH_BUSY), 100000);
207 234
208 regdata = brcmf_sdio_regrl(sdiodev, 235 regdata = brcmf_sdiod_regrl(sdiodev,
209 CORE_SB(base, sbtmstatehigh), 236 CORE_SB(base, sbtmstatehigh),
210 NULL); 237 NULL);
211 if (regdata & SSB_TMSHIGH_BUSY) 238 if (regdata & SSB_TMSHIGH_BUSY)
212 brcmf_err("core state still busy\n"); 239 brcmf_err("core state still busy\n");
213 240
214 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), 241 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
215 NULL); 242 NULL);
216 if (regdata & SSB_IDLOW_INITIATOR) { 243 if (regdata & SSB_IDLOW_INITIATOR) {
217 regdata = brcmf_sdio_regrl(sdiodev, 244 regdata = brcmf_sdiod_regrl(sdiodev,
218 CORE_SB(base, sbimstate), 245 CORE_SB(base, sbimstate),
219 NULL); 246 NULL);
220 regdata |= SSB_IMSTATE_REJECT; 247 regdata |= SSB_IMSTATE_REJECT;
221 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), 248 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
222 regdata, NULL); 249 regdata, NULL);
223 regdata = brcmf_sdio_regrl(sdiodev, 250 regdata = brcmf_sdiod_regrl(sdiodev,
224 CORE_SB(base, sbimstate), 251 CORE_SB(base, sbimstate),
225 NULL); 252 NULL);
226 udelay(1); 253 udelay(1);
227 SPINWAIT((brcmf_sdio_regrl(sdiodev, 254 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
228 CORE_SB(base, sbimstate), 255 CORE_SB(base, sbimstate),
229 NULL) & 256 NULL) &
230 SSB_IMSTATE_BUSY), 100000); 257 SSB_IMSTATE_BUSY), 100000);
231 } 258 }
232 259
233 /* set reset and reject while enabling the clocks */ 260 /* set reset and reject while enabling the clocks */
234 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | 261 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
235 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET; 262 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
236 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), 263 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
237 regdata, NULL); 264 regdata, NULL);
238 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), 265 regdata = brcmf_sdiod_regrl(sdiodev,
239 NULL); 266 CORE_SB(base, sbtmstatelow), NULL);
240 udelay(10); 267 udelay(10);
241 268
242 /* clear the initiator reject bit */ 269 /* clear the initiator reject bit */
243 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), 270 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
244 NULL); 271 NULL);
245 if (regdata & SSB_IDLOW_INITIATOR) { 272 if (regdata & SSB_IDLOW_INITIATOR) {
246 regdata = brcmf_sdio_regrl(sdiodev, 273 regdata = brcmf_sdiod_regrl(sdiodev,
247 CORE_SB(base, sbimstate), 274 CORE_SB(base, sbimstate),
248 NULL); 275 NULL);
249 regdata &= ~SSB_IMSTATE_REJECT; 276 regdata &= ~SSB_IMSTATE_REJECT;
250 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), 277 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
251 regdata, NULL); 278 regdata, NULL);
252 } 279 }
253 } 280 }
254 281
255 /* leave reset and reject asserted */ 282 /* leave reset and reject asserted */
256 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), 283 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
257 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL); 284 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
258 udelay(1); 285 udelay(1);
259} 286}
260 287
261static void 288static void
262brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, 289brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
263 struct chip_info *ci, u16 coreid, u32 core_bits) 290 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
291 u32 in_resetbits)
264{ 292{
265 u8 idx; 293 u8 idx;
266 u32 regdata; 294 u32 regdata;
295 u32 wrapbase;
267 296
268 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 297 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
269 if (idx == BRCMF_MAX_CORENUM) 298 if (idx == BRCMF_MAX_CORENUM)
270 return; 299 return;
271 300
301 wrapbase = ci->c_inf[idx].wrapbase;
302
272 /* if core is already in reset, just return */ 303 /* if core is already in reset, just return */
273 regdata = brcmf_sdio_regrl(sdiodev, 304 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
274 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
275 NULL);
276 if ((regdata & BCMA_RESET_CTL_RESET) != 0) 305 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
277 return; 306 return;
278 307
279 /* ensure no pending backplane operation 308 /* configure reset */
280 * 300uc should be sufficient for backplane ops to be finish 309 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
281 * extra 10ms is taken into account for firmware load stage 310 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
282 * after 10300us carry on disabling the core anyway 311 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
283 */
284 SPINWAIT(brcmf_sdio_regrl(sdiodev,
285 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
286 NULL), 10300);
287 regdata = brcmf_sdio_regrl(sdiodev,
288 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
289 NULL);
290 if (regdata)
291 brcmf_err("disabling core 0x%x with reset status %x\n",
292 coreid, regdata);
293
294 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
295 BCMA_RESET_CTL_RESET, NULL);
296 udelay(1);
297 312
298 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 313 /* put in reset */
299 core_bits, NULL); 314 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
300 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 315 BCMA_RESET_CTL_RESET, NULL);
301 NULL);
302 usleep_range(10, 20); 316 usleep_range(10, 20);
303 317
318 /* wait till reset is 1 */
319 SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
320 BCMA_RESET_CTL_RESET, 300);
321
322 /* post reset configure */
323 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
324 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
325 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
304} 326}
305 327
306static void 328static void
307brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, 329brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
308 struct chip_info *ci, u16 coreid, u32 core_bits) 330 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
331 u32 in_resetbits, u32 post_resetbits)
309{ 332{
310 u32 regdata; 333 u32 regdata;
311 u8 idx; 334 u8 idx;
@@ -318,93 +341,91 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
318 * Must do the disable sequence first to work for 341 * Must do the disable sequence first to work for
319 * arbitrary current core state. 342 * arbitrary current core state.
320 */ 343 */
321 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); 344 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
345 in_resetbits);
322 346
323 /* 347 /*
324 * Now do the initialization sequence. 348 * Now do the initialization sequence.
325 * set reset while enabling the clock and 349 * set reset while enabling the clock and
326 * forcing them on throughout the core 350 * forcing them on throughout the core
327 */ 351 */
328 brcmf_sdio_regwl(sdiodev, 352 brcmf_sdiod_regwl(sdiodev,
329 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 353 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
330 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET, 354 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
331 NULL); 355 NULL);
332 regdata = brcmf_sdio_regrl(sdiodev, 356 regdata = brcmf_sdiod_regrl(sdiodev,
333 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 357 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
334 NULL); 358 NULL);
335 udelay(1); 359 udelay(1);
336 360
337 /* clear any serror */ 361 /* clear any serror */
338 regdata = brcmf_sdio_regrl(sdiodev, 362 regdata = brcmf_sdiod_regrl(sdiodev,
339 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 363 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
340 NULL); 364 NULL);
341 if (regdata & SSB_TMSHIGH_SERR) 365 if (regdata & SSB_TMSHIGH_SERR)
342 brcmf_sdio_regwl(sdiodev, 366 brcmf_sdiod_regwl(sdiodev,
343 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 367 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
344 0, NULL); 368 0, NULL);
345 369
346 regdata = brcmf_sdio_regrl(sdiodev, 370 regdata = brcmf_sdiod_regrl(sdiodev,
347 CORE_SB(ci->c_inf[idx].base, sbimstate), 371 CORE_SB(ci->c_inf[idx].base, sbimstate),
348 NULL); 372 NULL);
349 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) 373 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
350 brcmf_sdio_regwl(sdiodev, 374 brcmf_sdiod_regwl(sdiodev,
351 CORE_SB(ci->c_inf[idx].base, sbimstate), 375 CORE_SB(ci->c_inf[idx].base, sbimstate),
352 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO), 376 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
353 NULL); 377 NULL);
354 378
355 /* clear reset and allow it to propagate throughout the core */ 379 /* clear reset and allow it to propagate throughout the core */
356 brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 380 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
357 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL); 381 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
358 regdata = brcmf_sdio_regrl(sdiodev, 382 regdata = brcmf_sdiod_regrl(sdiodev,
359 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 383 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
360 NULL); 384 NULL);
361 udelay(1); 385 udelay(1);
362 386
363 /* leave clock enabled */ 387 /* leave clock enabled */
364 brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 388 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
365 SSB_TMSLOW_CLOCK, NULL); 389 SSB_TMSLOW_CLOCK, NULL);
366 regdata = brcmf_sdio_regrl(sdiodev, 390 regdata = brcmf_sdiod_regrl(sdiodev,
367 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 391 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
368 NULL); 392 NULL);
369 udelay(1); 393 udelay(1);
370} 394}
371 395
372static void 396static void
373brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, 397brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
374 struct chip_info *ci, u16 coreid, u32 core_bits) 398 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
399 u32 in_resetbits, u32 post_resetbits)
375{ 400{
376 u8 idx; 401 u8 idx;
377 u32 regdata; 402 u32 regdata;
403 u32 wrapbase;
378 404
379 idx = brcmf_sdio_chip_getinfidx(ci, coreid); 405 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
380 if (idx == BRCMF_MAX_CORENUM) 406 if (idx == BRCMF_MAX_CORENUM)
381 return; 407 return;
382 408
409 wrapbase = ci->c_inf[idx].wrapbase;
410
383 /* must disable first to work for arbitrary current core state */ 411 /* must disable first to work for arbitrary current core state */
384 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); 412 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
385 413 in_resetbits);
386 /* now do initialization sequence */
387 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
388 core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
389 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
390 NULL);
391 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
392 0, NULL);
393 regdata = brcmf_sdio_regrl(sdiodev,
394 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
395 NULL);
396 udelay(1);
397 414
398 brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 415 while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
399 core_bits | BCMA_IOCTL_CLK, NULL); 416 BCMA_RESET_CTL_RESET) {
400 regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 417 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
401 NULL); 418 usleep_range(40, 60);
402 udelay(1); 419 }
420
421 brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
422 BCMA_IOCTL_CLK, NULL);
423 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
403} 424}
404 425
405#ifdef DEBUG 426#ifdef DEBUG
406/* safety check for chipinfo */ 427/* safety check for chipinfo */
407static int brcmf_sdio_chip_cichk(struct chip_info *ci) 428static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
408{ 429{
409 u8 core_idx; 430 u8 core_idx;
410 431
@@ -431,172 +452,213 @@ static int brcmf_sdio_chip_cichk(struct chip_info *ci)
431 return 0; 452 return 0;
432} 453}
433#else /* DEBUG */ 454#else /* DEBUG */
434static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) 455static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
435{ 456{
436 return 0; 457 return 0;
437} 458}
438#endif 459#endif
439 460
440static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, 461static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
441 struct chip_info *ci, u32 regs) 462 struct brcmf_chip *ci)
442{ 463{
443 u32 regdata; 464 u32 regdata;
444 int ret; 465 u32 socitype;
445 466
446 /* Get CC core rev 467 /* Get CC core rev
447 * Chipid is assume to be at offset 0 from regs arg 468 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
448 * For different chiptypes or old sdio hosts w/o chipcommon, 469 * For different chiptypes or old sdio hosts w/o chipcommon,
449 * other ways of recognition should be added here. 470 * other ways of recognition should be added here.
450 */ 471 */
451 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; 472 regdata = brcmf_sdiod_regrl(sdiodev,
452 ci->c_inf[0].base = regs; 473 CORE_CC_REG(SI_ENUM_BASE, chipid),
453 regdata = brcmf_sdio_regrl(sdiodev, 474 NULL);
454 CORE_CC_REG(ci->c_inf[0].base, chipid),
455 NULL);
456 ci->chip = regdata & CID_ID_MASK; 475 ci->chip = regdata & CID_ID_MASK;
457 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; 476 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
458 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && 477 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
459 ci->chiprev >= 2) 478 ci->chiprev >= 2)
460 ci->chip = BCM4339_CHIP_ID; 479 ci->chip = BCM4339_CHIP_ID;
461 ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; 480 socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
462 481
463 brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); 482 brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
483 socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
464 484
465 /* Address of cores for new chips should be added here */ 485 if (socitype == SOCI_SB) {
466 switch (ci->chip) { 486 if (ci->chip != BCM4329_CHIP_ID) {
467 case BCM43143_CHIP_ID: 487 brcmf_err("SB chip is not supported\n");
468 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; 488 return -ENODEV;
469 ci->c_inf[0].cib = 0x2b000000; 489 }
470 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; 490 ci->iscoreup = brcmf_sdio_sb_iscoreup;
471 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; 491 ci->corerev = brcmf_sdio_sb_corerev;
472 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; 492 ci->coredisable = brcmf_sdio_sb_coredisable;
473 ci->c_inf[1].cib = 0x18000000; 493 ci->resetcore = brcmf_sdio_sb_resetcore;
474 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; 494
475 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; 495 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
476 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; 496 ci->c_inf[0].base = SI_ENUM_BASE;
477 ci->c_inf[2].cib = 0x14000000;
478 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
479 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
480 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
481 ci->c_inf[3].cib = 0x07000000;
482 ci->ramsize = BCM43143_RAMSIZE;
483 break;
484 case BCM43241_CHIP_ID:
485 ci->c_inf[0].wrapbase = 0x18100000;
486 ci->c_inf[0].cib = 0x2a084411;
487 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
488 ci->c_inf[1].base = 0x18002000;
489 ci->c_inf[1].wrapbase = 0x18102000;
490 ci->c_inf[1].cib = 0x0e004211;
491 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
492 ci->c_inf[2].base = 0x18004000;
493 ci->c_inf[2].wrapbase = 0x18104000;
494 ci->c_inf[2].cib = 0x14080401;
495 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
496 ci->c_inf[3].base = 0x18003000;
497 ci->c_inf[3].wrapbase = 0x18103000;
498 ci->c_inf[3].cib = 0x07004211;
499 ci->ramsize = 0x90000;
500 break;
501 case BCM4329_CHIP_ID:
502 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; 497 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
503 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; 498 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
504 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; 499 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
505 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; 500 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
506 ci->c_inf[3].id = BCMA_CORE_ARM_CM3; 501 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
507 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; 502 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
503 ci->c_inf[4].id = BCMA_CORE_80211;
504 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
508 ci->ramsize = BCM4329_RAMSIZE; 505 ci->ramsize = BCM4329_RAMSIZE;
509 break; 506 } else if (socitype == SOCI_AI) {
510 case BCM4330_CHIP_ID:
511 ci->c_inf[0].wrapbase = 0x18100000;
512 ci->c_inf[0].cib = 0x27004211;
513 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
514 ci->c_inf[1].base = 0x18002000;
515 ci->c_inf[1].wrapbase = 0x18102000;
516 ci->c_inf[1].cib = 0x07004211;
517 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
518 ci->c_inf[2].base = 0x18004000;
519 ci->c_inf[2].wrapbase = 0x18104000;
520 ci->c_inf[2].cib = 0x0d080401;
521 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
522 ci->c_inf[3].base = 0x18003000;
523 ci->c_inf[3].wrapbase = 0x18103000;
524 ci->c_inf[3].cib = 0x03004211;
525 ci->ramsize = 0x48000;
526 break;
527 case BCM4334_CHIP_ID:
528 ci->c_inf[0].wrapbase = 0x18100000;
529 ci->c_inf[0].cib = 0x29004211;
530 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
531 ci->c_inf[1].base = 0x18002000;
532 ci->c_inf[1].wrapbase = 0x18102000;
533 ci->c_inf[1].cib = 0x0d004211;
534 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
535 ci->c_inf[2].base = 0x18004000;
536 ci->c_inf[2].wrapbase = 0x18104000;
537 ci->c_inf[2].cib = 0x13080401;
538 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
539 ci->c_inf[3].base = 0x18003000;
540 ci->c_inf[3].wrapbase = 0x18103000;
541 ci->c_inf[3].cib = 0x07004211;
542 ci->ramsize = 0x80000;
543 break;
544 case BCM4335_CHIP_ID:
545 ci->c_inf[0].wrapbase = 0x18100000;
546 ci->c_inf[0].cib = 0x2b084411;
547 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
548 ci->c_inf[1].base = 0x18005000;
549 ci->c_inf[1].wrapbase = 0x18105000;
550 ci->c_inf[1].cib = 0x0f004211;
551 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
552 ci->c_inf[2].base = 0x18002000;
553 ci->c_inf[2].wrapbase = 0x18102000;
554 ci->c_inf[2].cib = 0x01084411;
555 ci->ramsize = 0xc0000;
556 ci->rambase = 0x180000;
557 break;
558 case BCM4339_CHIP_ID:
559 ci->c_inf[0].wrapbase = 0x18100000;
560 ci->c_inf[0].cib = 0x2e084411;
561 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
562 ci->c_inf[1].base = 0x18005000;
563 ci->c_inf[1].wrapbase = 0x18105000;
564 ci->c_inf[1].cib = 0x15004211;
565 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
566 ci->c_inf[2].base = 0x18002000;
567 ci->c_inf[2].wrapbase = 0x18102000;
568 ci->c_inf[2].cib = 0x04084411;
569 ci->ramsize = 0xc0000;
570 ci->rambase = 0x180000;
571 break;
572 default:
573 brcmf_err("chipid 0x%x is not supported\n", ci->chip);
574 return -ENODEV;
575 }
576
577 ret = brcmf_sdio_chip_cichk(ci);
578 if (ret)
579 return ret;
580
581 switch (ci->socitype) {
582 case SOCI_SB:
583 ci->iscoreup = brcmf_sdio_sb_iscoreup;
584 ci->corerev = brcmf_sdio_sb_corerev;
585 ci->coredisable = brcmf_sdio_sb_coredisable;
586 ci->resetcore = brcmf_sdio_sb_resetcore;
587 break;
588 case SOCI_AI:
589 ci->iscoreup = brcmf_sdio_ai_iscoreup; 507 ci->iscoreup = brcmf_sdio_ai_iscoreup;
590 ci->corerev = brcmf_sdio_ai_corerev; 508 ci->corerev = brcmf_sdio_ai_corerev;
591 ci->coredisable = brcmf_sdio_ai_coredisable; 509 ci->coredisable = brcmf_sdio_ai_coredisable;
592 ci->resetcore = brcmf_sdio_ai_resetcore; 510 ci->resetcore = brcmf_sdio_ai_resetcore;
593 break; 511
594 default: 512 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
595 brcmf_err("socitype %u not supported\n", ci->socitype); 513 ci->c_inf[0].base = SI_ENUM_BASE;
514
515 /* Address of cores for new chips should be added here */
516 switch (ci->chip) {
517 case BCM43143_CHIP_ID:
518 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
519 ci->c_inf[0].cib = 0x2b000000;
520 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
521 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
522 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
523 ci->c_inf[1].cib = 0x18000000;
524 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
525 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
526 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
527 ci->c_inf[2].cib = 0x14000000;
528 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
529 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
530 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
531 ci->c_inf[3].cib = 0x07000000;
532 ci->c_inf[4].id = BCMA_CORE_80211;
533 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
534 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
535 ci->ramsize = BCM43143_RAMSIZE;
536 break;
537 case BCM43241_CHIP_ID:
538 ci->c_inf[0].wrapbase = 0x18100000;
539 ci->c_inf[0].cib = 0x2a084411;
540 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
541 ci->c_inf[1].base = 0x18002000;
542 ci->c_inf[1].wrapbase = 0x18102000;
543 ci->c_inf[1].cib = 0x0e004211;
544 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
545 ci->c_inf[2].base = 0x18004000;
546 ci->c_inf[2].wrapbase = 0x18104000;
547 ci->c_inf[2].cib = 0x14080401;
548 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
549 ci->c_inf[3].base = 0x18003000;
550 ci->c_inf[3].wrapbase = 0x18103000;
551 ci->c_inf[3].cib = 0x07004211;
552 ci->c_inf[4].id = BCMA_CORE_80211;
553 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
554 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
555 ci->ramsize = 0x90000;
556 break;
557 case BCM4330_CHIP_ID:
558 ci->c_inf[0].wrapbase = 0x18100000;
559 ci->c_inf[0].cib = 0x27004211;
560 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
561 ci->c_inf[1].base = 0x18002000;
562 ci->c_inf[1].wrapbase = 0x18102000;
563 ci->c_inf[1].cib = 0x07004211;
564 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
565 ci->c_inf[2].base = 0x18004000;
566 ci->c_inf[2].wrapbase = 0x18104000;
567 ci->c_inf[2].cib = 0x0d080401;
568 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
569 ci->c_inf[3].base = 0x18003000;
570 ci->c_inf[3].wrapbase = 0x18103000;
571 ci->c_inf[3].cib = 0x03004211;
572 ci->c_inf[4].id = BCMA_CORE_80211;
573 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
574 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
575 ci->ramsize = 0x48000;
576 break;
577 case BCM4334_CHIP_ID:
578 ci->c_inf[0].wrapbase = 0x18100000;
579 ci->c_inf[0].cib = 0x29004211;
580 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
581 ci->c_inf[1].base = 0x18002000;
582 ci->c_inf[1].wrapbase = 0x18102000;
583 ci->c_inf[1].cib = 0x0d004211;
584 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
585 ci->c_inf[2].base = 0x18004000;
586 ci->c_inf[2].wrapbase = 0x18104000;
587 ci->c_inf[2].cib = 0x13080401;
588 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
589 ci->c_inf[3].base = 0x18003000;
590 ci->c_inf[3].wrapbase = 0x18103000;
591 ci->c_inf[3].cib = 0x07004211;
592 ci->c_inf[4].id = BCMA_CORE_80211;
593 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
594 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
595 ci->ramsize = 0x80000;
596 break;
597 case BCM4335_CHIP_ID:
598 ci->c_inf[0].wrapbase = 0x18100000;
599 ci->c_inf[0].cib = 0x2b084411;
600 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
601 ci->c_inf[1].base = 0x18005000;
602 ci->c_inf[1].wrapbase = 0x18105000;
603 ci->c_inf[1].cib = 0x0f004211;
604 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
605 ci->c_inf[2].base = 0x18002000;
606 ci->c_inf[2].wrapbase = 0x18102000;
607 ci->c_inf[2].cib = 0x01084411;
608 ci->c_inf[3].id = BCMA_CORE_80211;
609 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
610 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
611 ci->ramsize = 0xc0000;
612 ci->rambase = 0x180000;
613 break;
614 case BCM43362_CHIP_ID:
615 ci->c_inf[0].wrapbase = 0x18100000;
616 ci->c_inf[0].cib = 0x27004211;
617 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
618 ci->c_inf[1].base = 0x18002000;
619 ci->c_inf[1].wrapbase = 0x18102000;
620 ci->c_inf[1].cib = 0x0a004211;
621 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
622 ci->c_inf[2].base = 0x18004000;
623 ci->c_inf[2].wrapbase = 0x18104000;
624 ci->c_inf[2].cib = 0x08080401;
625 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
626 ci->c_inf[3].base = 0x18003000;
627 ci->c_inf[3].wrapbase = 0x18103000;
628 ci->c_inf[3].cib = 0x03004211;
629 ci->c_inf[4].id = BCMA_CORE_80211;
630 ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
631 ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
632 ci->ramsize = 0x3C000;
633 break;
634 case BCM4339_CHIP_ID:
635 ci->c_inf[0].wrapbase = 0x18100000;
636 ci->c_inf[0].cib = 0x2e084411;
637 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
638 ci->c_inf[1].base = 0x18005000;
639 ci->c_inf[1].wrapbase = 0x18105000;
640 ci->c_inf[1].cib = 0x15004211;
641 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
642 ci->c_inf[2].base = 0x18002000;
643 ci->c_inf[2].wrapbase = 0x18102000;
644 ci->c_inf[2].cib = 0x04084411;
645 ci->c_inf[3].id = BCMA_CORE_80211;
646 ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
647 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
648 ci->ramsize = 0xc0000;
649 ci->rambase = 0x180000;
650 break;
651 default:
652 brcmf_err("AXI chip is not supported\n");
653 return -ENODEV;
654 }
655 } else {
656 brcmf_err("chip backplane type %u is not supported\n",
657 socitype);
596 return -ENODEV; 658 return -ENODEV;
597 } 659 }
598 660
599 return 0; 661 return brcmf_sdio_chip_cichk(ci);
600} 662}
601 663
602static int 664static int
@@ -607,7 +669,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
607 669
608 /* Try forcing SDIO core to do ALPAvail request only */ 670 /* Try forcing SDIO core to do ALPAvail request only */
609 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; 671 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
610 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); 672 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
611 if (err) { 673 if (err) {
612 brcmf_err("error writing for HT off\n"); 674 brcmf_err("error writing for HT off\n");
613 return err; 675 return err;
@@ -615,8 +677,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
615 677
616 /* If register supported, wait for ALPAvail and then force ALP */ 678 /* If register supported, wait for ALPAvail and then force ALP */
617 /* This may take up to 15 milliseconds */ 679 /* This may take up to 15 milliseconds */
618 clkval = brcmf_sdio_regrb(sdiodev, 680 clkval = brcmf_sdiod_regrb(sdiodev,
619 SBSDIO_FUNC1_CHIPCLKCSR, NULL); 681 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
620 682
621 if ((clkval & ~SBSDIO_AVBITS) != clkset) { 683 if ((clkval & ~SBSDIO_AVBITS) != clkset) {
622 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n", 684 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
@@ -624,8 +686,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
624 return -EACCES; 686 return -EACCES;
625 } 687 }
626 688
627 SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev, 689 SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
628 SBSDIO_FUNC1_CHIPCLKCSR, NULL)), 690 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
629 !SBSDIO_ALPAV(clkval)), 691 !SBSDIO_ALPAV(clkval)),
630 PMU_MAX_TRANSITION_DLY); 692 PMU_MAX_TRANSITION_DLY);
631 if (!SBSDIO_ALPAV(clkval)) { 693 if (!SBSDIO_ALPAV(clkval)) {
@@ -635,18 +697,18 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
635 } 697 }
636 698
637 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; 699 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
638 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); 700 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
639 udelay(65); 701 udelay(65);
640 702
641 /* Also, disable the extra SDIO pull-ups */ 703 /* Also, disable the extra SDIO pull-ups */
642 brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); 704 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
643 705
644 return 0; 706 return 0;
645} 707}
646 708
647static void 709static void
648brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, 710brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
649 struct chip_info *ci) 711 struct brcmf_chip *ci)
650{ 712{
651 u32 base = ci->c_inf[0].base; 713 u32 base = ci->c_inf[0].base;
652 714
@@ -654,16 +716,16 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
654 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); 716 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
655 717
656 /* get chipcommon capabilites */ 718 /* get chipcommon capabilites */
657 ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev, 719 ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
658 CORE_CC_REG(base, capabilities), 720 CORE_CC_REG(base, capabilities),
659 NULL); 721 NULL);
660 722
661 /* get pmu caps & rev */ 723 /* get pmu caps & rev */
662 if (ci->c_inf[0].caps & CC_CAP_PMU) { 724 if (ci->c_inf[0].caps & CC_CAP_PMU) {
663 ci->pmucaps = 725 ci->pmucaps =
664 brcmf_sdio_regrl(sdiodev, 726 brcmf_sdiod_regrl(sdiodev,
665 CORE_CC_REG(base, pmucapabilities), 727 CORE_CC_REG(base, pmucapabilities),
666 NULL); 728 NULL);
667 ci->pmurev = ci->pmucaps & PCAP_REV_MASK; 729 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
668 } 730 }
669 731
@@ -677,19 +739,18 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
677 * Make sure any on-chip ARM is off (in case strapping is wrong), 739 * Make sure any on-chip ARM is off (in case strapping is wrong),
678 * or downloaded code was already running. 740 * or downloaded code was already running.
679 */ 741 */
680 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 742 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
681} 743}
682 744
683int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 745int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
684 struct chip_info **ci_ptr, u32 regs) 746 struct brcmf_chip **ci_ptr)
685{ 747{
686 int ret; 748 int ret;
687 struct chip_info *ci; 749 struct brcmf_chip *ci;
688 750
689 brcmf_dbg(TRACE, "Enter\n"); 751 brcmf_dbg(TRACE, "Enter\n");
690 752
691 /* alloc chip_info_t */ 753 ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
692 ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
693 if (!ci) 754 if (!ci)
694 return -ENOMEM; 755 return -ENOMEM;
695 756
@@ -697,16 +758,16 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
697 if (ret != 0) 758 if (ret != 0)
698 goto err; 759 goto err;
699 760
700 ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs); 761 ret = brcmf_sdio_chip_recognition(sdiodev, ci);
701 if (ret != 0) 762 if (ret != 0)
702 goto err; 763 goto err;
703 764
704 brcmf_sdio_chip_buscoresetup(sdiodev, ci); 765 brcmf_sdio_chip_buscoresetup(sdiodev, ci);
705 766
706 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 767 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
707 0, NULL); 768 0, NULL);
708 brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 769 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
709 0, NULL); 770 0, NULL);
710 771
711 *ci_ptr = ci; 772 *ci_ptr = ci;
712 return 0; 773 return 0;
@@ -717,7 +778,7 @@ err:
717} 778}
718 779
719void 780void
720brcmf_sdio_chip_detach(struct chip_info **ci_ptr) 781brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
721{ 782{
722 brcmf_dbg(TRACE, "Enter\n"); 783 brcmf_dbg(TRACE, "Enter\n");
723 784
@@ -736,7 +797,7 @@ static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
736 797
737void 798void
738brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, 799brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
739 struct chip_info *ci, u32 drivestrength) 800 struct brcmf_chip *ci, u32 drivestrength)
740{ 801{
741 const struct sdiod_drive_str *str_tab = NULL; 802 const struct sdiod_drive_str *str_tab = NULL;
742 u32 str_mask; 803 u32 str_mask;
@@ -757,6 +818,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
757 str_mask = 0x00003800; 818 str_mask = 0x00003800;
758 str_shift = 11; 819 str_shift = 11;
759 break; 820 break;
821 case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
822 str_tab = sdiod_drvstr_tab6_1v8;
823 str_mask = 0x00001800;
824 str_shift = 11;
825 break;
760 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): 826 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
761 /* note: 43143 does not support tristate */ 827 /* note: 43143 does not support tristate */
762 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; 828 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
@@ -769,6 +835,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
769 brcmf_sdio_chip_name(ci->chip, chn, 8), 835 brcmf_sdio_chip_name(ci->chip, chn, 8),
770 drivestrength); 836 drivestrength);
771 break; 837 break;
838 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
839 str_tab = sdiod_drive_strength_tab5_1v8;
840 str_mask = 0x00003800;
841 str_shift = 11;
842 break;
772 default: 843 default:
773 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", 844 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
774 brcmf_sdio_chip_name(ci->chip, chn, 8), 845 brcmf_sdio_chip_name(ci->chip, chn, 8),
@@ -784,119 +855,31 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
784 } 855 }
785 } 856 }
786 addr = CORE_CC_REG(base, chipcontrol_addr); 857 addr = CORE_CC_REG(base, chipcontrol_addr);
787 brcmf_sdio_regwl(sdiodev, addr, 1, NULL); 858 brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
788 cc_data_temp = brcmf_sdio_regrl(sdiodev, addr, NULL); 859 cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
789 cc_data_temp &= ~str_mask; 860 cc_data_temp &= ~str_mask;
790 drivestrength_sel <<= str_shift; 861 drivestrength_sel <<= str_shift;
791 cc_data_temp |= drivestrength_sel; 862 cc_data_temp |= drivestrength_sel;
792 brcmf_sdio_regwl(sdiodev, addr, cc_data_temp, NULL); 863 brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
793 864
794 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", 865 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
795 str_tab[i].strength, drivestrength, cc_data_temp); 866 str_tab[i].strength, drivestrength, cc_data_temp);
796 } 867 }
797} 868}
798 869
799#ifdef DEBUG
800static bool
801brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
802 char *nvram_dat, uint nvram_sz)
803{
804 char *nvram_ularray;
805 int err;
806 bool ret = true;
807
808 /* read back and verify */
809 brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz);
810 nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL);
811 /* do not proceed while no memory but */
812 if (!nvram_ularray)
813 return true;
814
815 /* Upload image to verify downloaded contents. */
816 memset(nvram_ularray, 0xaa, nvram_sz);
817
818 /* Read the vars list to temp buffer for comparison */
819 err = brcmf_sdio_ramrw(sdiodev, false, nvram_addr, nvram_ularray,
820 nvram_sz);
821 if (err) {
822 brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
823 err, nvram_sz, nvram_addr);
824 } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) {
825 brcmf_err("Downloaded NVRAM image is corrupted\n");
826 ret = false;
827 }
828 kfree(nvram_ularray);
829
830 return ret;
831}
832#else /* DEBUG */
833static inline bool
834brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
835 char *nvram_dat, uint nvram_sz)
836{
837 return true;
838}
839#endif /* DEBUG */
840
841static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev,
842 struct chip_info *ci,
843 char *nvram_dat, uint nvram_sz)
844{
845 int err;
846 u32 nvram_addr;
847 u32 token;
848 __le32 token_le;
849
850 nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase;
851
852 /* Write the vars list */
853 err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz);
854 if (err) {
855 brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",
856 err, nvram_sz, nvram_addr);
857 return false;
858 }
859
860 if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr,
861 nvram_dat, nvram_sz))
862 return false;
863
864 /* generate token:
865 * nvram size, converted to words, in lower 16-bits, checksum
866 * in upper 16-bits.
867 */
868 token = nvram_sz / 4;
869 token = (~token << 16) | (token & 0x0000FFFF);
870 token_le = cpu_to_le32(token);
871
872 brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize);
873 brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n",
874 nvram_addr, nvram_sz, token);
875
876 /* Write the length token to the last word */
877 if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase),
878 (u8 *)&token_le, 4))
879 return false;
880
881 return true;
882}
883
884static void 870static void
885brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, 871brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
886 struct chip_info *ci) 872 struct brcmf_chip *ci)
887{ 873{
888 u32 zeros = 0; 874 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
889 875 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
890 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 876 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
891 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); 877 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
892 878 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
893 /* clear length token */
894 brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4);
895} 879}
896 880
897static bool 881static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
898brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 882 struct brcmf_chip *ci)
899 char *nvram_dat, uint nvram_sz)
900{ 883{
901 u8 core_idx; 884 u8 core_idx;
902 u32 reg_addr; 885 u32 reg_addr;
@@ -906,56 +889,64 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
906 return false; 889 return false;
907 } 890 }
908 891
909 if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
910 return false;
911
912 /* clear all interrupts */ 892 /* clear all interrupts */
913 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); 893 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
914 reg_addr = ci->c_inf[core_idx].base; 894 reg_addr = ci->c_inf[core_idx].base;
915 reg_addr += offsetof(struct sdpcmd_regs, intstatus); 895 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
916 brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); 896 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
917 897
918 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); 898 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
919 899
920 return true; 900 return true;
921} 901}
922 902
923static inline void 903static inline void
924brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, 904brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
925 struct chip_info *ci) 905 struct brcmf_chip *ci)
926{ 906{
927 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 907 u8 idx;
928 ARMCR4_BCMA_IOCTL_CPUHALT); 908 u32 regdata;
909 u32 wrapbase;
910 idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
911
912 if (idx == BRCMF_MAX_CORENUM)
913 return;
914
915 wrapbase = ci->c_inf[idx].wrapbase;
916 regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
917 regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
918 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
919 ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
920 ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
921 D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
922 D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
929} 923}
930 924
931static bool 925static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
932brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 926 struct brcmf_chip *ci, u32 rstvec)
933 char *nvram_dat, uint nvram_sz)
934{ 927{
935 u8 core_idx; 928 u8 core_idx;
936 u32 reg_addr; 929 u32 reg_addr;
937 930
938 if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
939 return false;
940
941 /* clear all interrupts */ 931 /* clear all interrupts */
942 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); 932 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
943 reg_addr = ci->c_inf[core_idx].base; 933 reg_addr = ci->c_inf[core_idx].base;
944 reg_addr += offsetof(struct sdpcmd_regs, intstatus); 934 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
945 brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); 935 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
946 936
947 /* Write reset vector to address 0 */ 937 /* Write reset vector to address 0 */
948 brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, 938 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
949 sizeof(ci->rst_vec)); 939 sizeof(rstvec));
950 940
951 /* restore ARM */ 941 /* restore ARM */
952 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); 942 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
943 0, 0);
953 944
954 return true; 945 return true;
955} 946}
956 947
957void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, 948void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
958 struct chip_info *ci) 949 struct brcmf_chip *ci)
959{ 950{
960 u8 arm_core_idx; 951 u8 arm_core_idx;
961 952
@@ -969,15 +960,13 @@ void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
969} 960}
970 961
971bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, 962bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
972 struct chip_info *ci, char *nvram_dat, 963 struct brcmf_chip *ci, u32 rstvec)
973 uint nvram_sz)
974{ 964{
975 u8 arm_core_idx; 965 u8 arm_core_idx;
976 966
977 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); 967 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
978 if (BRCMF_MAX_CORENUM != arm_core_idx) 968 if (BRCMF_MAX_CORENUM != arm_core_idx)
979 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, 969 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
980 nvram_sz);
981 970
982 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); 971 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
983} 972}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
index 507c61c991fa..fb0614329ede 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
@@ -54,15 +54,7 @@
54 54
55#define BRCMF_MAX_CORENUM 6 55#define BRCMF_MAX_CORENUM 6
56 56
57/* SDIO device ID */ 57struct brcmf_core {
58#define SDIO_DEVICE_ID_BROADCOM_43143 43143
59#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
60#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
61#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
62#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
63#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
64
65struct chip_core_info {
66 u16 id; 58 u16 id;
67 u16 rev; 59 u16 rev;
68 u32 base; 60 u32 base;
@@ -71,27 +63,28 @@ struct chip_core_info {
71 u32 cib; 63 u32 cib;
72}; 64};
73 65
74struct chip_info { 66struct brcmf_chip {
75 u32 chip; 67 u32 chip;
76 u32 chiprev; 68 u32 chiprev;
77 u32 socitype;
78 /* core info */ 69 /* core info */
79 /* always put chipcommon core at 0, bus core at 1 */ 70 /* always put chipcommon core at 0, bus core at 1 */
80 struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; 71 struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
81 u32 pmurev; 72 u32 pmurev;
82 u32 pmucaps; 73 u32 pmucaps;
83 u32 ramsize; 74 u32 ramsize;
84 u32 rambase; 75 u32 rambase;
85 u32 rst_vec; /* reset vertor for ARM CR4 core */ 76 u32 rst_vec; /* reset vertor for ARM CR4 core */
86 77
87 bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 78 bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
88 u16 coreid); 79 u16 coreid);
89 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, 80 u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
90 u16 coreid); 81 u16 coreid);
91 void (*coredisable)(struct brcmf_sdio_dev *sdiodev, 82 void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
92 struct chip_info *ci, u16 coreid, u32 core_bits); 83 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
84 u32 in_resetbits);
93 void (*resetcore)(struct brcmf_sdio_dev *sdiodev, 85 void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
94 struct chip_info *ci, u16 coreid, u32 core_bits); 86 struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
87 u32 in_resetbits, u32 post_resetbits);
95}; 88};
96 89
97struct sbconfig { 90struct sbconfig {
@@ -224,15 +217,15 @@ struct sdpcmd_regs {
224}; 217};
225 218
226int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 219int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
227 struct chip_info **ci_ptr, u32 regs); 220 struct brcmf_chip **ci_ptr);
228void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); 221void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
229void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, 222void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
230 struct chip_info *ci, u32 drivestrength); 223 struct brcmf_chip *ci,
231u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); 224 u32 drivestrength);
225u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
232void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, 226void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
233 struct chip_info *ci); 227 struct brcmf_chip *ci);
234bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, 228bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
235 struct chip_info *ci, char *nvram_dat, 229 struct brcmf_chip *ci, u32 rstvec);
236 uint nvram_sz);
237 230
238#endif /* _BRCMFMAC_SDIO_CHIP_H_ */ 231#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index fc0d4f0129db..092e9c824992 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -164,11 +164,9 @@ struct brcmf_sdio;
164struct brcmf_sdio_dev { 164struct brcmf_sdio_dev {
165 struct sdio_func *func[SDIO_MAX_FUNCS]; 165 struct sdio_func *func[SDIO_MAX_FUNCS];
166 u8 num_funcs; /* Supported funcs on client */ 166 u8 num_funcs; /* Supported funcs on client */
167 u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
168 u32 sbwad; /* Save backplane window address */ 167 u32 sbwad; /* Save backplane window address */
169 void *bus; 168 struct brcmf_sdio *bus;
170 atomic_t suspend; /* suspend flag */ 169 atomic_t suspend; /* suspend flag */
171 wait_queue_head_t request_byte_wait;
172 wait_queue_head_t request_word_wait; 170 wait_queue_head_t request_word_wait;
173 wait_queue_head_t request_buffer_wait; 171 wait_queue_head_t request_buffer_wait;
174 struct device *dev; 172 struct device *dev;
@@ -185,22 +183,19 @@ struct brcmf_sdio_dev {
185}; 183};
186 184
187/* Register/deregister interrupt handler. */ 185/* Register/deregister interrupt handler. */
188int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); 186int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
189int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); 187int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
190 188
191/* sdio device register access interface */ 189/* sdio device register access interface */
192u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); 190u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
193u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); 191u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
194void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, 192void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data,
195 int *ret); 193 int *ret);
196void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, 194void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data,
197 int *ret); 195 int *ret);
198int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
199 void *data, bool write);
200 196
201/* Buffer transfer to/from device (client) core via cmd53. 197/* Buffer transfer to/from device (client) core via cmd53.
202 * fn: function number 198 * fn: function number
203 * addr: backplane address (i.e. >= regsva from attach)
204 * flags: backplane width, address increment, sync/async 199 * flags: backplane width, address increment, sync/async
205 * buf: pointer to memory data buffer 200 * buf: pointer to memory data buffer
206 * nbytes: number of bytes to transfer to/from buf 201 * nbytes: number of bytes to transfer to/from buf
@@ -210,17 +205,14 @@ int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
210 * Returns 0 or error code. 205 * Returns 0 or error code.
211 * NOTE: Async operation is not currently supported. 206 * NOTE: Async operation is not currently supported.
212 */ 207 */
213int brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 208int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
214 uint flags, struct sk_buff_head *pktq); 209 struct sk_buff_head *pktq);
215int brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 210int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes);
216 uint flags, u8 *buf, uint nbytes); 211
217 212int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt);
218int brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 213int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes);
219 uint flags, struct sk_buff *pkt); 214int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
220int brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, 215 struct sk_buff_head *pktq, uint totlen);
221 uint flags, u8 *buf, uint nbytes);
222int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
223 uint flags, struct sk_buff_head *pktq, uint totlen);
224 216
225/* Flags bits */ 217/* Flags bits */
226 218
@@ -236,43 +228,16 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
236 * nbytes: number of bytes to transfer to/from buf 228 * nbytes: number of bytes to transfer to/from buf
237 * Returns 0 or error code. 229 * Returns 0 or error code.
238 */ 230 */
239int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, 231int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
240 u8 *buf, uint nbytes); 232 u8 *data, uint size);
241int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
242 u8 *data, uint size);
243 233
244/* Issue an abort to the specified function */ 234/* Issue an abort to the specified function */
245int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); 235int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
246
247/* platform specific/high level functions */
248int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
249int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
250
251/* attach, return handler on success, NULL if failed.
252 * The handler shall be provided by all subsequent calls. No local cache
253 * cfghdl points to the starting address of pci device mapped memory
254 */
255int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
256void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
257
258/* read or write one byte using cmd52 */
259int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc,
260 uint addr, u8 *byte);
261
262/* read or write 2/4 bytes using cmd53 */
263int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc,
264 uint addr, u32 *word, uint nbyte);
265
266/* Watchdog timer interface for pm ops */
267void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable);
268 236
269void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); 237struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
270void brcmf_sdbrcm_disconnect(void *ptr); 238void brcmf_sdio_remove(struct brcmf_sdio *bus);
271void brcmf_sdbrcm_isr(void *arg); 239void brcmf_sdio_isr(struct brcmf_sdio *bus);
272 240
273void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); 241void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
274 242
275void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
276 wait_queue_head_t *wq);
277bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev);
278#endif /* _BRCM_SDH_H_ */ 243#endif /* _BRCM_SDH_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
index 3c67529b9074..4d7d51f95716 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -89,7 +89,7 @@ TRACE_EVENT(brcmf_hexdump,
89 TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len) 89 TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len)
90); 90);
91 91
92TRACE_EVENT(brcmf_bdchdr, 92TRACE_EVENT(brcmf_bcdchdr,
93 TP_PROTO(void *data), 93 TP_PROTO(void *data),
94 TP_ARGS(data), 94 TP_ARGS(data),
95 TP_STRUCT__entry( 95 TP_STRUCT__entry(
@@ -107,24 +107,35 @@ TRACE_EVENT(brcmf_bdchdr,
107 memcpy(__get_dynamic_array(signal), 107 memcpy(__get_dynamic_array(signal),
108 (u8 *)data + 4, __entry->siglen); 108 (u8 *)data + 4, __entry->siglen);
109 ), 109 ),
110 TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) 110 TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
111); 111);
112 112
113#ifndef SDPCM_RX
114#define SDPCM_RX 0
115#endif
116#ifndef SDPCM_TX
117#define SDPCM_TX 1
118#endif
119#ifndef SDPCM_GLOM
120#define SDPCM_GLOM 2
121#endif
122
113TRACE_EVENT(brcmf_sdpcm_hdr, 123TRACE_EVENT(brcmf_sdpcm_hdr,
114 TP_PROTO(bool tx, void *data), 124 TP_PROTO(u8 dir, void *data),
115 TP_ARGS(tx, data), 125 TP_ARGS(dir, data),
116 TP_STRUCT__entry( 126 TP_STRUCT__entry(
117 __field(u8, tx) 127 __field(u8, dir)
118 __field(u16, len) 128 __field(u16, len)
119 __array(u8, hdr, 12) 129 __dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12)
120 ), 130 ),
121 TP_fast_assign( 131 TP_fast_assign(
122 memcpy(__entry->hdr, data, 12); 132 memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12);
123 __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8); 133 __entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8);
124 __entry->tx = tx ? 1 : 0; 134 __entry->dir = dir;
125 ), 135 ),
126 TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX", 136 TP_printk("sdpcm: %s len %u, seq %d",
127 __entry->len, __entry->hdr[4]) 137 __entry->dir == SDPCM_RX ? "RX" : "TX",
138 __entry->len, ((u8 *)__get_dynamic_array(hdr))[4])
128); 139);
129 140
130#ifdef CONFIG_BRCM_TRACING 141#ifdef CONFIG_BRCM_TRACING
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 422f44c63175..24f65cd53859 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -522,10 +522,10 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
522 /* update state of upper layer */ 522 /* update state of upper layer */
523 if (state == BRCMFMAC_USB_STATE_DOWN) { 523 if (state == BRCMFMAC_USB_STATE_DOWN) {
524 brcmf_dbg(USB, "DBUS is down\n"); 524 brcmf_dbg(USB, "DBUS is down\n");
525 bcmf_bus->state = BRCMF_BUS_DOWN; 525 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN);
526 } else if (state == BRCMFMAC_USB_STATE_UP) { 526 } else if (state == BRCMFMAC_USB_STATE_UP) {
527 brcmf_dbg(USB, "DBUS is up\n"); 527 brcmf_dbg(USB, "DBUS is up\n");
528 bcmf_bus->state = BRCMF_BUS_DATA; 528 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DATA);
529 } else { 529 } else {
530 brcmf_dbg(USB, "DBUS current state=%d\n", state); 530 brcmf_dbg(USB, "DBUS current state=%d\n", state);
531 } 531 }
@@ -1253,9 +1253,10 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1253 bus->ops = &brcmf_usb_bus_ops; 1253 bus->ops = &brcmf_usb_bus_ops;
1254 bus->chip = bus_pub->devid; 1254 bus->chip = bus_pub->devid;
1255 bus->chiprev = bus_pub->chiprev; 1255 bus->chiprev = bus_pub->chiprev;
1256 bus->proto_type = BRCMF_PROTO_BCDC;
1256 1257
1257 /* Attach to the common driver interface */ 1258 /* Attach to the common driver interface */
1258 ret = brcmf_attach(0, dev); 1259 ret = brcmf_attach(dev);
1259 if (ret) { 1260 if (ret) {
1260 brcmf_err("brcmf_attach failed\n"); 1261 brcmf_err("brcmf_attach failed\n");
1261 goto fail; 1262 goto fail;
@@ -1454,7 +1455,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
1454 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1455 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1455 1456
1456 brcmf_dbg(USB, "Enter\n"); 1457 brcmf_dbg(USB, "Enter\n");
1457 if (!brcmf_attach(0, devinfo->dev)) 1458 if (!brcmf_attach(devinfo->dev))
1458 return brcmf_bus_start(&usb->dev); 1459 return brcmf_bus_start(&usb->dev);
1459 1460
1460 return 0; 1461 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 571f013cebbb..d7718a5fa2f0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -202,9 +202,9 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
202 202
203/* This is to override regulatory domains defined in cfg80211 module (reg.c) 203/* This is to override regulatory domains defined in cfg80211 module (reg.c)
204 * By default world regulatory domain defined in reg.c puts the flags 204 * By default world regulatory domain defined in reg.c puts the flags
205 * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for 205 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206 * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't 206 * With respect to these flags, wpa_supplicant doesn't * start p2p
207 * start p2p operations on 5GHz channels. All the changes in world regulatory 207 * operations on 5GHz channels. All the changes in world regulatory
208 * domain are to be done here. 208 * domain are to be done here.
209 */ 209 */
210static const struct ieee80211_regdomain brcmf_regdom = { 210static const struct ieee80211_regdomain brcmf_regdom = {
@@ -1095,10 +1095,10 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1095 BRCMF_C_DISASSOC, NULL, 0); 1095 BRCMF_C_DISASSOC, NULL, 0);
1096 if (err) { 1096 if (err) {
1097 brcmf_err("WLC_DISASSOC failed (%d)\n", err); 1097 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1098 cfg80211_disconnected(vif->wdev.netdev, 0,
1099 NULL, 0, GFP_KERNEL);
1100 } 1098 }
1101 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); 1099 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1100 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1101
1102 } 1102 }
1103 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); 1103 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1104 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); 1104 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
@@ -1758,6 +1758,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1758 return -EIO; 1758 return -EIO;
1759 1759
1760 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); 1760 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1761 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1761 1762
1762 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); 1763 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1763 scbval.val = cpu_to_le32(reason_code); 1764 scbval.val = cpu_to_le32(reason_code);
@@ -2556,8 +2557,8 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2556 ch_bss.band == ch_bss_info_le.band && 2557 ch_bss.band == ch_bss_info_le.band &&
2557 bss_info_le->SSID_len == bss->SSID_len && 2558 bss_info_le->SSID_len == bss->SSID_len &&
2558 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { 2559 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2559 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == 2560 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2560 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) { 2561 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2561 s16 bss_rssi = le16_to_cpu(bss->RSSI); 2562 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2562 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI); 2563 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2563 2564
@@ -2566,13 +2567,13 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2566 */ 2567 */
2567 if (bss_info_rssi > bss_rssi) 2568 if (bss_info_rssi > bss_rssi)
2568 bss->RSSI = bss_info_le->RSSI; 2569 bss->RSSI = bss_info_le->RSSI;
2569 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) && 2570 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2570 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) { 2571 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2571 /* preserve the on-channel rssi measurement 2572 /* preserve the on-channel rssi measurement
2572 * if the new measurement is off channel 2573 * if the new measurement is off channel
2573 */ 2574 */
2574 bss->RSSI = bss_info_le->RSSI; 2575 bss->RSSI = bss_info_le->RSSI;
2575 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL; 2576 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2576 } 2577 }
2577 return 1; 2578 return 1;
2578 } 2579 }
@@ -2988,6 +2989,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2988 } 2989 }
2989 2990
2990 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2991 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2992 cfg->escan_info.run = brcmf_run_escan;
2991 err = brcmf_do_escan(cfg, wiphy, ifp, request); 2993 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2992 if (err) { 2994 if (err) {
2993 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 2995 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
@@ -3973,11 +3975,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3973 3975
3974static int 3976static int
3975brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3977brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3976 struct ieee80211_channel *chan, bool offchan, 3978 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3977 unsigned int wait, const u8 *buf, size_t len,
3978 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3979{ 3979{
3980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3981 struct ieee80211_channel *chan = params->chan;
3982 const u8 *buf = params->buf;
3983 size_t len = params->len;
3981 const struct ieee80211_mgmt *mgmt; 3984 const struct ieee80211_mgmt *mgmt;
3982 struct brcmf_cfg80211_vif *vif; 3985 struct brcmf_cfg80211_vif *vif;
3983 s32 err = 0; 3986 s32 err = 0;
@@ -4341,7 +4344,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4341 wiphy->max_remain_on_channel_duration = 5000; 4344 wiphy->max_remain_on_channel_duration = 5000;
4342 brcmf_wiphy_pno_params(wiphy); 4345 brcmf_wiphy_pno_params(wiphy);
4343 brcmf_dbg(INFO, "Registering custom regulatory\n"); 4346 brcmf_dbg(INFO, "Registering custom regulatory\n");
4344 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 4347 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4345 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 4348 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4346 err = wiphy_register(wiphy); 4349 err = wiphy_register(wiphy);
4347 if (err < 0) { 4350 if (err < 0) {
@@ -4358,9 +4361,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4358{ 4361{
4359 struct brcmf_cfg80211_vif *vif; 4362 struct brcmf_cfg80211_vif *vif;
4360 4363
4361 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4362 return ERR_PTR(-ENOSPC);
4363
4364 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", 4364 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4365 sizeof(*vif)); 4365 sizeof(*vif));
4366 vif = kzalloc(sizeof(*vif), GFP_KERNEL); 4366 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
@@ -4377,21 +4377,25 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4377 brcmf_init_prof(&vif->profile); 4377 brcmf_init_prof(&vif->profile);
4378 4378
4379 list_add_tail(&vif->list, &cfg->vif_list); 4379 list_add_tail(&vif->list, &cfg->vif_list);
4380 cfg->vif_cnt++;
4381 return vif; 4380 return vif;
4382} 4381}
4383 4382
4384void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, 4383void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4385 struct brcmf_cfg80211_vif *vif)
4386{ 4384{
4387 list_del(&vif->list); 4385 list_del(&vif->list);
4388 cfg->vif_cnt--;
4389
4390 kfree(vif); 4386 kfree(vif);
4391 if (!cfg->vif_cnt) { 4387}
4392 wiphy_unregister(cfg->wiphy); 4388
4393 wiphy_free(cfg->wiphy); 4389void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4394 } 4390{
4391 struct brcmf_cfg80211_vif *vif;
4392 struct brcmf_if *ifp;
4393
4394 ifp = netdev_priv(ndev);
4395 vif = ifp->vif;
4396
4397 brcmf_free_vif(vif);
4398 free_netdev(ndev);
4395} 4399}
4396 4400
4397static bool brcmf_is_linkup(const struct brcmf_event_msg *e) 4401static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
@@ -4978,20 +4982,20 @@ cfg80211_p2p_attach_out:
4978 wl_deinit_priv(cfg); 4982 wl_deinit_priv(cfg);
4979 4983
4980cfg80211_attach_out: 4984cfg80211_attach_out:
4981 brcmf_free_vif(cfg, vif); 4985 brcmf_free_vif(vif);
4982 return NULL; 4986 return NULL;
4983} 4987}
4984 4988
4985void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) 4989void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4986{ 4990{
4987 struct brcmf_cfg80211_vif *vif; 4991 if (!cfg)
4988 struct brcmf_cfg80211_vif *tmp; 4992 return;
4989 4993
4990 wl_deinit_priv(cfg); 4994 WARN_ON(!list_empty(&cfg->vif_list));
4995 wiphy_unregister(cfg->wiphy);
4991 brcmf_btcoex_detach(cfg); 4996 brcmf_btcoex_detach(cfg);
4992 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { 4997 wl_deinit_priv(cfg);
4993 brcmf_free_vif(cfg, vif); 4998 wiphy_free(cfg->wiphy);
4994 }
4995} 4999}
4996 5000
4997static s32 5001static s32
@@ -5086,7 +5090,8 @@ dongle_scantime_out:
5086} 5090}
5087 5091
5088 5092
5089static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) 5093static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5094 u32 bw_cap[])
5090{ 5095{
5091 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 5096 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5092 struct ieee80211_channel *band_chan_arr; 5097 struct ieee80211_channel *band_chan_arr;
@@ -5099,7 +5104,6 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5099 enum ieee80211_band band; 5104 enum ieee80211_band band;
5100 u32 channel; 5105 u32 channel;
5101 u32 *n_cnt; 5106 u32 *n_cnt;
5102 bool ht40_allowed;
5103 u32 index; 5107 u32 index;
5104 u32 ht40_flag; 5108 u32 ht40_flag;
5105 bool update; 5109 bool update;
@@ -5132,18 +5136,17 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5132 array_size = ARRAY_SIZE(__wl_2ghz_channels); 5136 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5133 n_cnt = &__wl_band_2ghz.n_channels; 5137 n_cnt = &__wl_band_2ghz.n_channels;
5134 band = IEEE80211_BAND_2GHZ; 5138 band = IEEE80211_BAND_2GHZ;
5135 ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
5136 } else if (ch.band == BRCMU_CHAN_BAND_5G) { 5139 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5137 band_chan_arr = __wl_5ghz_a_channels; 5140 band_chan_arr = __wl_5ghz_a_channels;
5138 array_size = ARRAY_SIZE(__wl_5ghz_a_channels); 5141 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5139 n_cnt = &__wl_band_5ghz_a.n_channels; 5142 n_cnt = &__wl_band_5ghz_a.n_channels;
5140 band = IEEE80211_BAND_5GHZ; 5143 band = IEEE80211_BAND_5GHZ;
5141 ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
5142 } else { 5144 } else {
5143 brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec); 5145 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5144 continue; 5146 continue;
5145 } 5147 }
5146 if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40) 5148 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5149 ch.bw == BRCMU_CHAN_BW_40)
5147 continue; 5150 continue;
5148 update = false; 5151 update = false;
5149 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { 5152 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
@@ -5161,7 +5164,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5161 ieee80211_channel_to_frequency(ch.chnum, band); 5164 ieee80211_channel_to_frequency(ch.chnum, band);
5162 band_chan_arr[index].hw_value = ch.chnum; 5165 band_chan_arr[index].hw_value = ch.chnum;
5163 5166
5164 if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) { 5167 brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5168 ch.chnum, band_chan_arr[index].center_freq,
5169 ch.bw, ch.sb);
5170 if (ch.bw == BRCMU_CHAN_BW_40) {
5165 /* assuming the order is HT20, HT40 Upper, 5171 /* assuming the order is HT20, HT40 Upper,
5166 * HT40 lower from chanspecs 5172 * HT40 lower from chanspecs
5167 */ 5173 */
@@ -5197,10 +5203,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5197 if (channel & WL_CHAN_RADAR) 5203 if (channel & WL_CHAN_RADAR)
5198 band_chan_arr[index].flags |= 5204 band_chan_arr[index].flags |=
5199 (IEEE80211_CHAN_RADAR | 5205 (IEEE80211_CHAN_RADAR |
5200 IEEE80211_CHAN_NO_IBSS); 5206 IEEE80211_CHAN_NO_IR);
5201 if (channel & WL_CHAN_PASSIVE) 5207 if (channel & WL_CHAN_PASSIVE)
5202 band_chan_arr[index].flags |= 5208 band_chan_arr[index].flags |=
5203 IEEE80211_CHAN_PASSIVE_SCAN; 5209 IEEE80211_CHAN_NO_IR;
5204 } 5210 }
5205 } 5211 }
5206 if (!update) 5212 if (!update)
@@ -5212,6 +5218,46 @@ exit:
5212 return err; 5218 return err;
5213} 5219}
5214 5220
5221static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5222{
5223 u32 band, mimo_bwcap;
5224 int err;
5225
5226 band = WLC_BAND_2G;
5227 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5228 if (!err) {
5229 bw_cap[IEEE80211_BAND_2GHZ] = band;
5230 band = WLC_BAND_5G;
5231 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5232 if (!err) {
5233 bw_cap[IEEE80211_BAND_5GHZ] = band;
5234 return;
5235 }
5236 WARN_ON(1);
5237 return;
5238 }
5239 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5240 mimo_bwcap = 0;
5241 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5242 if (err)
5243 /* assume 20MHz if firmware does not give a clue */
5244 mimo_bwcap = WLC_N_BW_20ALL;
5245
5246 switch (mimo_bwcap) {
5247 case WLC_N_BW_40ALL:
5248 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5249 /* fall-thru */
5250 case WLC_N_BW_20IN2G_40IN5G:
5251 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5252 /* fall-thru */
5253 case WLC_N_BW_20ALL:
5254 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5255 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5256 break;
5257 default:
5258 brcmf_err("invalid mimo_bw_cap value\n");
5259 }
5260}
5215 5261
5216static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) 5262static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5217{ 5263{
@@ -5220,13 +5266,13 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5220 s32 phy_list; 5266 s32 phy_list;
5221 u32 band_list[3]; 5267 u32 band_list[3];
5222 u32 nmode; 5268 u32 nmode;
5223 u32 bw_cap = 0; 5269 u32 bw_cap[2] = { 0, 0 };
5224 s8 phy; 5270 s8 phy;
5225 s32 err; 5271 s32 err;
5226 u32 nband; 5272 u32 nband;
5227 s32 i; 5273 s32 i;
5228 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; 5274 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5229 s32 index; 5275 struct ieee80211_supported_band *band;
5230 5276
5231 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, 5277 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5232 &phy_list, sizeof(phy_list)); 5278 &phy_list, sizeof(phy_list));
@@ -5252,11 +5298,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5252 if (err) { 5298 if (err) {
5253 brcmf_err("nmode error (%d)\n", err); 5299 brcmf_err("nmode error (%d)\n", err);
5254 } else { 5300 } else {
5255 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap); 5301 brcmf_get_bwcap(ifp, bw_cap);
5256 if (err)
5257 brcmf_err("mimo_bw_cap error (%d)\n", err);
5258 } 5302 }
5259 brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap); 5303 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5304 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5260 5305
5261 err = brcmf_construct_reginfo(cfg, bw_cap); 5306 err = brcmf_construct_reginfo(cfg, bw_cap);
5262 if (err) { 5307 if (err) {
@@ -5265,40 +5310,33 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5265 } 5310 }
5266 5311
5267 nband = band_list[0]; 5312 nband = band_list[0];
5268 memset(bands, 0, sizeof(bands));
5269 5313
5270 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { 5314 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5271 index = -1; 5315 band = NULL;
5272 if ((band_list[i] == WLC_BAND_5G) && 5316 if ((band_list[i] == WLC_BAND_5G) &&
5273 (__wl_band_5ghz_a.n_channels > 0)) { 5317 (__wl_band_5ghz_a.n_channels > 0))
5274 index = IEEE80211_BAND_5GHZ; 5318 band = &__wl_band_5ghz_a;
5275 bands[index] = &__wl_band_5ghz_a; 5319 else if ((band_list[i] == WLC_BAND_2G) &&
5276 if ((bw_cap == WLC_N_BW_40ALL) || 5320 (__wl_band_2ghz.n_channels > 0))
5277 (bw_cap == WLC_N_BW_20IN2G_40IN5G)) 5321 band = &__wl_band_2ghz;
5278 bands[index]->ht_cap.cap |= 5322 else
5279 IEEE80211_HT_CAP_SGI_40; 5323 continue;
5280 } else if ((band_list[i] == WLC_BAND_2G) &&
5281 (__wl_band_2ghz.n_channels > 0)) {
5282 index = IEEE80211_BAND_2GHZ;
5283 bands[index] = &__wl_band_2ghz;
5284 if (bw_cap == WLC_N_BW_40ALL)
5285 bands[index]->ht_cap.cap |=
5286 IEEE80211_HT_CAP_SGI_40;
5287 }
5288 5324
5289 if ((index >= 0) && nmode) { 5325 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5290 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; 5326 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5291 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; 5327 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5292 bands[index]->ht_cap.ht_supported = true;
5293 bands[index]->ht_cap.ampdu_factor =
5294 IEEE80211_HT_MAX_AMPDU_64K;
5295 bands[index]->ht_cap.ampdu_density =
5296 IEEE80211_HT_MPDU_DENSITY_16;
5297 /* An HT shall support all EQM rates for one spatial
5298 * stream
5299 */
5300 bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5301 } 5328 }
5329 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5330 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5331 band->ht_cap.ht_supported = true;
5332 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5333 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5334 /* An HT shall support all EQM rates for one spatial
5335 * stream
5336 */
5337 band->ht_cap.mcs.rx_mask[0] = 0xff;
5338 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5339 bands[band->band] = band;
5302 } 5340 }
5303 5341
5304 wiphy = cfg_to_wiphy(cfg); 5342 wiphy = cfg_to_wiphy(cfg);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index d9bdaf9a72d0..2dc6a074e8ed 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -412,7 +412,6 @@ struct brcmf_cfg80211_info {
412 struct work_struct escan_timeout_work; 412 struct work_struct escan_timeout_work;
413 u8 *escan_ioctl_buf; 413 u8 *escan_ioctl_buf;
414 struct list_head vif_list; 414 struct list_head vif_list;
415 u8 vif_cnt;
416 struct brcmf_cfg80211_vif_event vif_event; 415 struct brcmf_cfg80211_vif_event vif_event;
417 struct completion vif_disabled; 416 struct completion vif_disabled;
418 struct brcmu_d11inf d11inf; 417 struct brcmu_d11inf d11inf;
@@ -487,8 +486,7 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
487struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, 486struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
488 enum nl80211_iftype type, 487 enum nl80211_iftype type,
489 bool pm_block); 488 bool pm_block);
490void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, 489void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
491 struct brcmf_cfg80211_vif *vif);
492 490
493s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, 491s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
494 const u8 *vndr_ie_buf, u32 vndr_ie_len); 492 const u8 *vndr_ie_buf, u32 vndr_ie_len);
@@ -507,5 +505,6 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
507 bool fw_abort); 505 bool fw_abort);
508void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); 506void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
509void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); 507void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
508void brcmf_cfg80211_free_netdev(struct net_device *ndev);
510 509
511#endif /* _wl_cfg80211_h_ */ 510#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index cc87926f5055..635ae034c7e5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -59,23 +59,18 @@
59 59
60#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) 60#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
61#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ 61#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
62 NL80211_RRF_PASSIVE_SCAN | \ 62 NL80211_RRF_NO_IR)
63 NL80211_RRF_NO_IBSS)
64 63
65#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ 64#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
66 NL80211_RRF_PASSIVE_SCAN | \ 65 NL80211_RRF_NO_IR)
67 NL80211_RRF_NO_IBSS)
68#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ 66#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
69 NL80211_RRF_PASSIVE_SCAN | \
70 NL80211_RRF_DFS | \ 67 NL80211_RRF_DFS | \
71 NL80211_RRF_NO_IBSS) 68 NL80211_RRF_NO_IR)
72#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ 69#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
73 NL80211_RRF_PASSIVE_SCAN | \
74 NL80211_RRF_DFS | \ 70 NL80211_RRF_DFS | \
75 NL80211_RRF_NO_IBSS) 71 NL80211_RRF_NO_IR)
76#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ 72#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
77 NL80211_RRF_PASSIVE_SCAN | \ 73 NL80211_RRF_NO_IR)
78 NL80211_RRF_NO_IBSS)
79 74
80static const struct ieee80211_regdomain brcms_regdom_x2 = { 75static const struct ieee80211_regdomain brcms_regdom_x2 = {
81 .n_reg_rules = 6, 76 .n_reg_rules = 6,
@@ -395,7 +390,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
395 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); 390 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
396 391
397 brcms_b_set_chanspec(wlc->hw, chanspec, 392 brcms_b_set_chanspec(wlc->hw, chanspec,
398 !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), 393 !!(ch->flags & IEEE80211_CHAN_NO_IR),
399 &txpwr); 394 &txpwr);
400} 395}
401 396
@@ -657,8 +652,8 @@ static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
657 */ 652 */
658 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 653 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
659 ch->flags |= IEEE80211_CHAN_RADAR | 654 ch->flags |= IEEE80211_CHAN_RADAR |
660 IEEE80211_CHAN_NO_IBSS | 655 IEEE80211_CHAN_NO_IR |
661 IEEE80211_CHAN_PASSIVE_SCAN; 656 IEEE80211_CHAN_NO_IR;
662 } 657 }
663} 658}
664 659
@@ -684,18 +679,15 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
684 continue; 679 continue;
685 680
686 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 681 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
687 rule = freq_reg_info(wiphy, ch->center_freq); 682 rule = freq_reg_info(wiphy,
683 MHZ_TO_KHZ(ch->center_freq));
688 if (IS_ERR(rule)) 684 if (IS_ERR(rule))
689 continue; 685 continue;
690 686
691 if (!(rule->flags & NL80211_RRF_NO_IBSS)) 687 if (!(rule->flags & NL80211_RRF_NO_IR))
692 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 688 ch->flags &= ~IEEE80211_CHAN_NO_IR;
693 if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN))
694 ch->flags &=
695 ~IEEE80211_CHAN_PASSIVE_SCAN;
696 } else if (ch->beacon_found) { 689 } else if (ch->beacon_found) {
697 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 690 ch->flags &= ~IEEE80211_CHAN_NO_IR;
698 IEEE80211_CHAN_PASSIVE_SCAN);
699 } 691 }
700 } 692 }
701 } 693 }
@@ -775,8 +767,8 @@ void brcms_c_regd_init(struct brcms_c_info *wlc)
775 } 767 }
776 768
777 wlc->wiphy->reg_notifier = brcms_reg_notifier; 769 wlc->wiphy->reg_notifier = brcms_reg_notifier;
778 wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 770 wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
779 WIPHY_FLAG_STRICT_REGULATORY; 771 REGULATORY_STRICT_REG;
780 wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); 772 wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
781 brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); 773 brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
782} 774}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index edc5d105ff98..925034b80e9c 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -125,13 +125,13 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
125 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), 125 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
126 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), 126 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
127 CHAN2GHZ(12, 2467, 127 CHAN2GHZ(12, 2467,
128 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 128 IEEE80211_CHAN_NO_IR |
129 IEEE80211_CHAN_NO_HT40PLUS), 129 IEEE80211_CHAN_NO_HT40PLUS),
130 CHAN2GHZ(13, 2472, 130 CHAN2GHZ(13, 2472,
131 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 131 IEEE80211_CHAN_NO_IR |
132 IEEE80211_CHAN_NO_HT40PLUS), 132 IEEE80211_CHAN_NO_HT40PLUS),
133 CHAN2GHZ(14, 2484, 133 CHAN2GHZ(14, 2484,
134 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 134 IEEE80211_CHAN_NO_IR |
135 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | 135 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
136 IEEE80211_CHAN_NO_OFDM) 136 IEEE80211_CHAN_NO_OFDM)
137}; 137};
@@ -144,51 +144,51 @@ static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
144 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), 144 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
145 /* UNII-2 */ 145 /* UNII-2 */
146 CHAN5GHZ(52, 146 CHAN5GHZ(52,
147 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 147 IEEE80211_CHAN_RADAR |
148 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 148 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
149 CHAN5GHZ(56, 149 CHAN5GHZ(56,
150 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 150 IEEE80211_CHAN_RADAR |
151 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 151 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
152 CHAN5GHZ(60, 152 CHAN5GHZ(60,
153 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 153 IEEE80211_CHAN_RADAR |
154 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 154 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
155 CHAN5GHZ(64, 155 CHAN5GHZ(64,
156 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 156 IEEE80211_CHAN_RADAR |
157 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 157 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
158 /* MID */ 158 /* MID */
159 CHAN5GHZ(100, 159 CHAN5GHZ(100,
160 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 160 IEEE80211_CHAN_RADAR |
161 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 161 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
162 CHAN5GHZ(104, 162 CHAN5GHZ(104,
163 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 163 IEEE80211_CHAN_RADAR |
164 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 164 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
165 CHAN5GHZ(108, 165 CHAN5GHZ(108,
166 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 166 IEEE80211_CHAN_RADAR |
167 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 167 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
168 CHAN5GHZ(112, 168 CHAN5GHZ(112,
169 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 169 IEEE80211_CHAN_RADAR |
170 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 170 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
171 CHAN5GHZ(116, 171 CHAN5GHZ(116,
172 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 172 IEEE80211_CHAN_RADAR |
173 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 173 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
174 CHAN5GHZ(120, 174 CHAN5GHZ(120,
175 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 175 IEEE80211_CHAN_RADAR |
176 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 176 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
177 CHAN5GHZ(124, 177 CHAN5GHZ(124,
178 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 178 IEEE80211_CHAN_RADAR |
179 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 179 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
180 CHAN5GHZ(128, 180 CHAN5GHZ(128,
181 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 181 IEEE80211_CHAN_RADAR |
182 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 182 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
183 CHAN5GHZ(132, 183 CHAN5GHZ(132,
184 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 184 IEEE80211_CHAN_RADAR |
185 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 185 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
186 CHAN5GHZ(136, 186 CHAN5GHZ(136,
187 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 187 IEEE80211_CHAN_RADAR |
188 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 188 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
189 CHAN5GHZ(140, 189 CHAN5GHZ(140,
190 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 190 IEEE80211_CHAN_RADAR |
191 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | 191 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS |
192 IEEE80211_CHAN_NO_HT40MINUS), 192 IEEE80211_CHAN_NO_HT40MINUS),
193 /* UNII-3 */ 193 /* UNII-3 */
194 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), 194 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
@@ -1071,7 +1071,6 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
1071 hw->max_rates = 2; /* Primary rate and 1 fallback rate */ 1071 hw->max_rates = 2; /* Primary rate and 1 fallback rate */
1072 1072
1073 /* channel change time is dependent on chip and band */ 1073 /* channel change time is dependent on chip and band */
1074 hw->channel_change_time = 7 * 1000;
1075 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1074 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1076 BIT(NL80211_IFTYPE_AP) | 1075 BIT(NL80211_IFTYPE_AP) |
1077 BIT(NL80211_IFTYPE_ADHOC); 1076 BIT(NL80211_IFTYPE_ADHOC);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 8138f1cff4e5..9417cb5a2553 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7108,7 +7108,6 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7108 struct sk_buff *p, 7108 struct sk_buff *p,
7109 struct ieee80211_rx_status *rx_status) 7109 struct ieee80211_rx_status *rx_status)
7110{ 7110{
7111 int preamble;
7112 int channel; 7111 int channel;
7113 u32 rspec; 7112 u32 rspec;
7114 unsigned char *plcp; 7113 unsigned char *plcp;
@@ -7191,7 +7190,6 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7191 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET; 7190 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
7192 7191
7193 /* Determine short preamble and rate_idx */ 7192 /* Determine short preamble and rate_idx */
7194 preamble = 0;
7195 if (is_cck_rate(rspec)) { 7193 if (is_cck_rate(rspec)) {
7196 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) 7194 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
7197 rx_status->flag |= RX_FLAG_SHORTPRE; 7195 rx_status->flag |= RX_FLAG_SHORTPRE;
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index 84113ea16f84..6fa5d4863782 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -41,6 +41,7 @@
41#define BCM4331_CHIP_ID 0x4331 41#define BCM4331_CHIP_ID 0x4331
42#define BCM4334_CHIP_ID 0x4334 42#define BCM4334_CHIP_ID 0x4334
43#define BCM4335_CHIP_ID 0x4335 43#define BCM4335_CHIP_ID 0x4335
44#define BCM43362_CHIP_ID 43362
44#define BCM4339_CHIP_ID 0x4339 45#define BCM4339_CHIP_ID 0x4339
45 46
46#endif /* _BRCM_HW_IDS_H_ */ 47#endif /* _BRCM_HW_IDS_H_ */
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index 0505cc065e0d..7ca2aa1035b2 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -82,6 +82,20 @@
82#define WLC_N_BW_40ALL 1 82#define WLC_N_BW_40ALL 1
83#define WLC_N_BW_20IN2G_40IN5G 2 83#define WLC_N_BW_20IN2G_40IN5G 2
84 84
85#define WLC_BW_20MHZ_BIT BIT(0)
86#define WLC_BW_40MHZ_BIT BIT(1)
87#define WLC_BW_80MHZ_BIT BIT(2)
88#define WLC_BW_160MHZ_BIT BIT(3)
89
90/* Bandwidth capabilities */
91#define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT)
92#define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
93#define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT| \
94 WLC_BW_20MHZ_BIT)
95#define WLC_BW_CAP_160MHZ (WLC_BW_160MHZ_BIT|WLC_BW_80MHZ_BIT| \
96 WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
97#define WLC_BW_CAP_UNRESTRICTED 0xFF
98
85/* band types */ 99/* band types */
86#define WLC_BAND_AUTO 0 /* auto-select */ 100#define WLC_BAND_AUTO 0 /* auto-select */
87#define WLC_BAND_5G 1 /* 5 Ghz */ 101#define WLC_BAND_5G 1 /* 5 Ghz */
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index ebdcdf44f155..d3acc85932a5 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -108,9 +108,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
108 struct hwbus_priv *self = dev_id; 108 struct hwbus_priv *self = dev_id;
109 109
110 if (self->core) { 110 if (self->core) {
111 sdio_claim_host(self->func); 111 cw1200_sdio_lock(self);
112 cw1200_irq_handler(self->core); 112 cw1200_irq_handler(self->core);
113 sdio_release_host(self->func); 113 cw1200_sdio_unlock(self);
114 return IRQ_HANDLED; 114 return IRQ_HANDLED;
115 } else { 115 } else {
116 return IRQ_NONE; 116 return IRQ_NONE;
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index acdff0f7f952..5a9ffd3a6a6c 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -14,7 +14,6 @@
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 */ 15 */
16 16
17#include <linux/init.h>
18#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
19#include <linux/sched.h> 18#include <linux/sched.h>
20#include <linux/firmware.h> 19#include <linux/firmware.h>
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index 090f01577dd2..3e78cc3ccb78 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/firmware.h> 24#include <linux/firmware.h>
26#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
27#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
@@ -302,7 +301,6 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
302 301
303 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 302 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
304 303
305 hw->channel_change_time = 1000; /* TODO: find actual value */
306 hw->queues = 4; 304 hw->queues = 4;
307 305
308 priv->rts_threshold = -1; 306 priv->rts_threshold = -1;
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
index b37abb9f0453..6907c8fd4578 100644
--- a/drivers/net/wireless/cw1200/pm.c
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -225,7 +225,7 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
225 cw1200_set_pm(priv, &priv->powersave_mode); 225 cw1200_set_pm(priv, &priv->powersave_mode);
226 if (wait_event_interruptible_timeout(priv->ps_mode_switch_done, 226 if (wait_event_interruptible_timeout(priv->ps_mode_switch_done,
227 !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) { 227 !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) {
228 goto revert3; 228 goto revert4;
229 } 229 }
230 } 230 }
231 231
@@ -254,11 +254,11 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
254 254
255 /* Stop serving thread */ 255 /* Stop serving thread */
256 if (cw1200_bh_suspend(priv)) 256 if (cw1200_bh_suspend(priv))
257 goto revert4; 257 goto revert5;
258 258
259 ret = timer_pending(&priv->mcast_timeout); 259 ret = timer_pending(&priv->mcast_timeout);
260 if (ret) 260 if (ret)
261 goto revert5; 261 goto revert6;
262 262
263 /* Store suspend state */ 263 /* Store suspend state */
264 pm_state->suspend_state = state; 264 pm_state->suspend_state = state;
@@ -280,9 +280,9 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
280 280
281 return 0; 281 return 0;
282 282
283revert5: 283revert6:
284 WARN_ON(cw1200_bh_resume(priv)); 284 WARN_ON(cw1200_bh_resume(priv));
285revert4: 285revert5:
286 cw1200_resume_work(priv, &priv->bss_loss_work, 286 cw1200_resume_work(priv, &priv->bss_loss_work,
287 state->bss_loss_tmo); 287 state->bss_loss_tmo);
288 cw1200_resume_work(priv, &priv->join_timeout, 288 cw1200_resume_work(priv, &priv->join_timeout,
@@ -291,6 +291,7 @@ revert4:
291 state->direct_probe); 291 state->direct_probe);
292 cw1200_resume_work(priv, &priv->link_id_gc_work, 292 cw1200_resume_work(priv, &priv->link_id_gc_work,
293 state->link_id_gc); 293 state->link_id_gc);
294revert4:
294 kfree(state); 295 kfree(state);
295revert3: 296revert3:
296 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off); 297 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
index ee3c19037aac..9afcd4ce3368 100644
--- a/drivers/net/wireless/cw1200/scan.c
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -173,8 +173,9 @@ void cw1200_scan_work(struct work_struct *work)
173 cw1200_set_pm(priv, &priv->powersave_mode); 173 cw1200_set_pm(priv, &priv->powersave_mode);
174 174
175 if (priv->scan.status < 0) 175 if (priv->scan.status < 0)
176 wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n", 176 wiphy_warn(priv->hw->wiphy,
177 priv->scan.status); 177 "[SCAN] Scan failed (%d).\n",
178 priv->scan.status);
178 else if (priv->scan.req) 179 else if (priv->scan.req)
179 wiphy_dbg(priv->hw->wiphy, 180 wiphy_dbg(priv->hw->wiphy,
180 "[SCAN] Scan completed.\n"); 181 "[SCAN] Scan completed.\n");
@@ -197,9 +198,9 @@ void cw1200_scan_work(struct work_struct *work)
197 if ((*it)->band != first->band) 198 if ((*it)->band != first->band)
198 break; 199 break;
199 if (((*it)->flags ^ first->flags) & 200 if (((*it)->flags ^ first->flags) &
200 IEEE80211_CHAN_PASSIVE_SCAN) 201 IEEE80211_CHAN_NO_IR)
201 break; 202 break;
202 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 203 if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
203 (*it)->max_power != first->max_power) 204 (*it)->max_power != first->max_power)
204 break; 205 break;
205 } 206 }
@@ -210,7 +211,7 @@ void cw1200_scan_work(struct work_struct *work)
210 else 211 else
211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1; 212 scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
212 scan.num_probes = 213 scan.num_probes =
213 (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2; 214 (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
214 scan.num_ssids = priv->scan.n_ssids; 215 scan.num_ssids = priv->scan.n_ssids;
215 scan.ssids = &priv->scan.ssids[0]; 216 scan.ssids = &priv->scan.ssids[0];
216 scan.num_channels = it - priv->scan.curr; 217 scan.num_channels = it - priv->scan.curr;
@@ -233,7 +234,7 @@ void cw1200_scan_work(struct work_struct *work)
233 } 234 }
234 for (i = 0; i < scan.num_channels; ++i) { 235 for (i = 0; i < scan.num_channels; ++i) {
235 scan.ch[i].number = priv->scan.curr[i]->hw_value; 236 scan.ch[i].number = priv->scan.curr[i]->hw_value;
236 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 237 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) {
237 scan.ch[i].min_chan_time = 50; 238 scan.ch[i].min_chan_time = 50;
238 scan.ch[i].max_chan_time = 100; 239 scan.ch[i].max_chan_time = 100;
239 } else { 240 } else {
@@ -241,7 +242,7 @@ void cw1200_scan_work(struct work_struct *work)
241 scan.ch[i].max_chan_time = 25; 242 scan.ch[i].max_chan_time = 25;
242 } 243 }
243 } 244 }
244 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 245 if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
245 priv->scan.output_power != first->max_power) { 246 priv->scan.output_power != first->max_power) {
246 priv->scan.output_power = first->max_power; 247 priv->scan.output_power = first->max_power;
247 wsm_set_output_power(priv, 248 wsm_set_output_power(priv,
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 010b252be584..103f7bce8932 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -13,6 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/firmware.h> 14#include <linux/firmware.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/etherdevice.h>
16 17
17#include "cw1200.h" 18#include "cw1200.h"
18#include "sta.h" 19#include "sta.h"
@@ -555,8 +556,8 @@ u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
555 pr_debug("[STA] multicast: %pM\n", ha->addr); 556 pr_debug("[STA] multicast: %pM\n", ha->addr);
556 memcpy(&priv->multicast_filter.macaddrs[count], 557 memcpy(&priv->multicast_filter.macaddrs[count],
557 ha->addr, ETH_ALEN); 558 ha->addr, ETH_ALEN);
558 if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) && 559 if (!ether_addr_equal(ha->addr, broadcast_ipv4) &&
559 memcmp(ha->addr, broadcast_ipv6, ETH_ALEN)) 560 !ether_addr_equal(ha->addr, broadcast_ipv6))
560 priv->has_multicast_subscription = true; 561 priv->has_multicast_subscription = true;
561 count++; 562 count++;
562 } 563 }
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index e824d4d4a18d..0bd541175ecd 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -1166,8 +1166,7 @@ void cw1200_rx_cb(struct cw1200_common *priv,
1166 return; 1166 return;
1167 } else if (ieee80211_is_beacon(frame->frame_control) && 1167 } else if (ieee80211_is_beacon(frame->frame_control) &&
1168 !arg->status && priv->vif && 1168 !arg->status && priv->vif &&
1169 !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid, 1169 ether_addr_equal(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid)) {
1170 ETH_ALEN)) {
1171 const u8 *tim_ie; 1170 const u8 *tim_ie;
1172 u8 *ies = ((struct ieee80211_mgmt *) 1171 u8 *ies = ((struct ieee80211_mgmt *)
1173 (skb->data))->u.beacon.variable; 1172 (skb->data))->u.beacon.variable;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index d39e3e24077b..599f30f22841 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -563,7 +563,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc,
563 563
564 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS) 564 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS)
565 * or own non-standard frame with 4th address after payload */ 565 * or own non-standard frame with 4th address after payload */
566 if (memcmp(hdr->addr1, local->dev->dev_addr, ETH_ALEN) != 0 && 566 if (!ether_addr_equal(hdr->addr1, local->dev->dev_addr) &&
567 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff || 567 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff ||
568 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || 568 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
569 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { 569 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
@@ -622,12 +622,12 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
622 /* check that the frame is unicast frame to us */ 622 /* check that the frame is unicast frame to us */
623 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 623 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
624 IEEE80211_FCTL_TODS && 624 IEEE80211_FCTL_TODS &&
625 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && 625 ether_addr_equal(hdr->addr1, dev->dev_addr) &&
626 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { 626 ether_addr_equal(hdr->addr3, dev->dev_addr)) {
627 /* ToDS frame with own addr BSSID and DA */ 627 /* ToDS frame with own addr BSSID and DA */
628 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 628 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
629 IEEE80211_FCTL_FROMDS && 629 IEEE80211_FCTL_FROMDS &&
630 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { 630 ether_addr_equal(hdr->addr1, dev->dev_addr)) {
631 /* FromDS frame with own addr as DA */ 631 /* FromDS frame with own addr as DA */
632 } else 632 } else
633 return 0; 633 return 0;
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 344a981a052e..8bde77689469 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,5 +1,6 @@
1#include <linux/slab.h> 1#include <linux/slab.h>
2#include <linux/export.h> 2#include <linux/export.h>
3#include <linux/etherdevice.h>
3 4
4#include "hostap_80211.h" 5#include "hostap_80211.h"
5#include "hostap_common.h" 6#include "hostap_common.h"
@@ -103,8 +104,7 @@ netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
103 return NETDEV_TX_OK; 104 return NETDEV_TX_OK;
104 } else if (local->iw_mode == IW_MODE_INFRA && 105 } else if (local->iw_mode == IW_MODE_INFRA &&
105 (local->wds_type & HOSTAP_WDS_AP_CLIENT) && 106 (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
106 memcmp(skb->data + ETH_ALEN, dev->dev_addr, 107 !ether_addr_equal(skb->data + ETH_ALEN, dev->dev_addr)) {
107 ETH_ALEN) != 0) {
108 /* AP client mode: send frames with foreign src addr 108 /* AP client mode: send frames with foreign src addr
109 * using 4-addr WDS frames */ 109 * using 4-addr WDS frames */
110 use_wds = WDS_COMPLIANT_FRAME; 110 use_wds = WDS_COMPLIANT_FRAME;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index d6033a8e5dea..d36e252d2ccb 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/export.h> 25#include <linux/export.h>
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/etherdevice.h>
27 28
28#include "hostap_wlan.h" 29#include "hostap_wlan.h"
29#include "hostap.h" 30#include "hostap.h"
@@ -106,13 +107,12 @@ static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
106 107
107 s = ap->sta_hash[STA_HASH(sta->addr)]; 108 s = ap->sta_hash[STA_HASH(sta->addr)];
108 if (s == NULL) return; 109 if (s == NULL) return;
109 if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) { 110 if (ether_addr_equal(s->addr, sta->addr)) {
110 ap->sta_hash[STA_HASH(sta->addr)] = s->hnext; 111 ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
111 return; 112 return;
112 } 113 }
113 114
114 while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN) 115 while (s->hnext != NULL && !ether_addr_equal(s->hnext->addr, sta->addr))
115 != 0)
116 s = s->hnext; 116 s = s->hnext;
117 if (s->hnext != NULL) 117 if (s->hnext != NULL)
118 s->hnext = s->hnext->hnext; 118 s->hnext = s->hnext->hnext;
@@ -435,7 +435,7 @@ int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
435 ptr != &mac_restrictions->mac_list; ptr = ptr->next) { 435 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
436 entry = list_entry(ptr, struct mac_entry, list); 436 entry = list_entry(ptr, struct mac_entry, list);
437 437
438 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { 438 if (ether_addr_equal(entry->addr, mac)) {
439 list_del(ptr); 439 list_del(ptr);
440 kfree(entry); 440 kfree(entry);
441 mac_restrictions->entries--; 441 mac_restrictions->entries--;
@@ -459,7 +459,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
459 459
460 spin_lock_bh(&mac_restrictions->lock); 460 spin_lock_bh(&mac_restrictions->lock);
461 list_for_each_entry(entry, &mac_restrictions->mac_list, list) { 461 list_for_each_entry(entry, &mac_restrictions->mac_list, list) {
462 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { 462 if (ether_addr_equal(entry->addr, mac)) {
463 found = 1; 463 found = 1;
464 break; 464 break;
465 } 465 }
@@ -957,7 +957,7 @@ static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
957 struct sta_info *s; 957 struct sta_info *s;
958 958
959 s = ap->sta_hash[STA_HASH(sta)]; 959 s = ap->sta_hash[STA_HASH(sta)];
960 while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0) 960 while (s != NULL && !ether_addr_equal(s->addr, sta))
961 s = s->hnext; 961 s = s->hnext;
962 return s; 962 return s;
963} 963}
@@ -1391,7 +1391,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
1391 status_code = __le16_to_cpu(*pos); 1391 status_code = __le16_to_cpu(*pos);
1392 pos++; 1392 pos++;
1393 1393
1394 if (memcmp(dev->dev_addr, hdr->addr2, ETH_ALEN) == 0 || 1394 if (ether_addr_equal(dev->dev_addr, hdr->addr2) ||
1395 ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) { 1395 ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) {
1396 txt = "authentication denied"; 1396 txt = "authentication denied";
1397 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 1397 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -1935,7 +1935,7 @@ static void handle_pspoll(local_info_t *local,
1935 PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n", 1935 PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
1936 hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control)); 1936 hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control));
1937 1937
1938 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { 1938 if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
1939 PDEBUG(DEBUG_AP, 1939 PDEBUG(DEBUG_AP,
1940 "handle_pspoll - addr1(BSSID)=%pM not own MAC\n", 1940 "handle_pspoll - addr1(BSSID)=%pM not own MAC\n",
1941 hdr->addr1); 1941 hdr->addr1);
@@ -2230,7 +2230,7 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
2230 goto done; 2230 goto done;
2231 } 2231 }
2232 2232
2233 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { 2233 if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
2234 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=%pM" 2234 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=%pM"
2235 " not own MAC\n", hdr->addr1); 2235 " not own MAC\n", hdr->addr1);
2236 goto done; 2236 goto done;
@@ -2267,13 +2267,13 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
2267 goto done; 2267 goto done;
2268 } 2268 }
2269 2269
2270 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { 2270 if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
2271 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%pM" 2271 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%pM"
2272 " not own MAC\n", hdr->addr1); 2272 " not own MAC\n", hdr->addr1);
2273 goto done; 2273 goto done;
2274 } 2274 }
2275 2275
2276 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) { 2276 if (!ether_addr_equal(hdr->addr3, dev->dev_addr)) {
2277 PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%pM" 2277 PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%pM"
2278 " not own MAC\n", hdr->addr3); 2278 " not own MAC\n", hdr->addr3);
2279 goto done; 2279 goto done;
@@ -3035,7 +3035,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
3035 if (!wds) { 3035 if (!wds) {
3036 /* FromDS frame - not for us; probably 3036 /* FromDS frame - not for us; probably
3037 * broadcast/multicast in another BSS - drop */ 3037 * broadcast/multicast in another BSS - drop */
3038 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { 3038 if (ether_addr_equal(hdr->addr1, dev->dev_addr)) {
3039 printk(KERN_DEBUG "Odd.. FromDS packet " 3039 printk(KERN_DEBUG "Odd.. FromDS packet "
3040 "received with own BSSID\n"); 3040 "received with own BSSID\n");
3041 hostap_dump_rx_80211(dev->name, skb, rx_stats); 3041 hostap_dump_rx_80211(dev->name, skb, rx_stats);
@@ -3044,7 +3044,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
3044 goto out; 3044 goto out;
3045 } 3045 }
3046 } else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL && 3046 } else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL &&
3047 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { 3047 ether_addr_equal(hdr->addr1, dev->dev_addr)) {
3048 3048
3049 if (local->hostapd) { 3049 if (local->hostapd) {
3050 prism2_rx_80211(local->apdev, skb, rx_stats, 3050 prism2_rx_80211(local->apdev, skb, rx_stats,
@@ -3073,7 +3073,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
3073 /* If BSSID (Addr3) is foreign, this frame is a normal 3073 /* If BSSID (Addr3) is foreign, this frame is a normal
3074 * broadcast frame from an IBSS network. Drop it silently. 3074 * broadcast frame from an IBSS network. Drop it silently.
3075 * If BSSID is own, report the dropping of this frame. */ 3075 * If BSSID is own, report the dropping of this frame. */
3076 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { 3076 if (ether_addr_equal(hdr->addr3, dev->dev_addr)) {
3077 printk(KERN_DEBUG "%s: dropped received packet from %pM" 3077 printk(KERN_DEBUG "%s: dropped received packet from %pM"
3078 " with no ToDS flag " 3078 " with no ToDS flag "
3079 "(type=0x%02x, subtype=0x%02x)\n", dev->name, 3079 "(type=0x%02x, subtype=0x%02x)\n", dev->name,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 56cd01ca8ad0..9f825f2620da 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -1,7 +1,6 @@
1#define PRISM2_PCCARD 1#define PRISM2_PCCARD
2 2
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/init.h>
5#include <linux/if.h> 4#include <linux/if.h>
6#include <linux/slab.h> 5#include <linux/slab.h>
7#include <linux/wait.h> 6#include <linux/wait.h>
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index c275dc1623fe..6df3ee561d52 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -2175,7 +2175,7 @@ static void hostap_tx_callback(local_info_t *local,
2175 struct hostap_tx_callback_info *cb; 2175 struct hostap_tx_callback_info *cb;
2176 2176
2177 /* Make sure that frame was from us. */ 2177 /* Make sure that frame was from us. */
2178 if (memcmp(txdesc->addr2, local->dev->dev_addr, ETH_ALEN)) { 2178 if (!ether_addr_equal(txdesc->addr2, local->dev->dev_addr)) {
2179 printk(KERN_DEBUG "%s: TX callback - foreign frame\n", 2179 printk(KERN_DEBUG "%s: TX callback - foreign frame\n",
2180 local->dev->name); 2180 local->dev->name);
2181 return; 2181 return;
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index e5090309824e..3e5fa7872b64 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -655,7 +655,7 @@ static int hostap_join_ap(struct net_device *dev)
655 if (!local->last_scan_results) 655 if (!local->last_scan_results)
656 break; 656 break;
657 entry = &local->last_scan_results[i]; 657 entry = &local->last_scan_results[i];
658 if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) { 658 if (ether_addr_equal(local->preferred_ap, entry->bssid)) {
659 req.channel = entry->chid; 659 req.channel = entry->chid;
660 break; 660 break;
661 } 661 }
@@ -1978,7 +1978,7 @@ static inline int prism2_translate_scan(local_info_t *local,
1978 list_for_each(ptr, &local->bss_list) { 1978 list_for_each(ptr, &local->bss_list) {
1979 struct hostap_bss_info *bss; 1979 struct hostap_bss_info *bss;
1980 bss = list_entry(ptr, struct hostap_bss_info, list); 1980 bss = list_entry(ptr, struct hostap_bss_info, list);
1981 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { 1981 if (ether_addr_equal(bss->bssid, scan->bssid)) {
1982 bss->included = 1; 1982 bss->included = 1;
1983 current_ev = __prism2_translate_scan( 1983 current_ev = __prism2_translate_scan(
1984 local, info, scan, bss, current_ev, 1984 local, info, scan, bss, current_ev,
@@ -2567,7 +2567,7 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2567 local->passive_scan_interval = value; 2567 local->passive_scan_interval = value;
2568 if (timer_pending(&local->passive_scan_timer)) 2568 if (timer_pending(&local->passive_scan_timer))
2569 del_timer(&local->passive_scan_timer); 2569 del_timer(&local->passive_scan_timer);
2570 if (value > 0) { 2570 if (value > 0 && value < INT_MAX / HZ) {
2571 local->passive_scan_timer.expires = jiffies + 2571 local->passive_scan_timer.expires = jiffies +
2572 local->passive_scan_interval * HZ; 2572 local->passive_scan_interval * HZ;
2573 add_timer(&local->passive_scan_timer); 2573 add_timer(&local->passive_scan_timer);
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index a1257c92afc4..67db34e56d7e 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -155,8 +155,7 @@ int prism2_wds_add(local_info_t *local, u8 *remote_addr,
155 155
156 if (prism2_wds_special_addr(iface->u.wds.remote_addr)) 156 if (prism2_wds_special_addr(iface->u.wds.remote_addr))
157 empty = iface; 157 empty = iface;
158 else if (memcmp(iface->u.wds.remote_addr, remote_addr, 158 else if (ether_addr_equal(iface->u.wds.remote_addr, remote_addr)) {
159 ETH_ALEN) == 0) {
160 match = iface; 159 match = iface;
161 break; 160 break;
162 } 161 }
@@ -214,8 +213,7 @@ int prism2_wds_del(local_info_t *local, u8 *remote_addr,
214 if (iface->type != HOSTAP_INTERFACE_WDS) 213 if (iface->type != HOSTAP_INTERFACE_WDS)
215 continue; 214 continue;
216 215
217 if (memcmp(iface->u.wds.remote_addr, remote_addr, 216 if (ether_addr_equal(iface->u.wds.remote_addr, remote_addr)) {
218 ETH_ALEN) == 0) {
219 selected = iface; 217 selected = iface;
220 break; 218 break;
221 } 219 }
@@ -1085,7 +1083,7 @@ int prism2_sta_deauth(local_info_t *local, u16 reason)
1085 1083
1086 if (local->iw_mode != IW_MODE_INFRA || 1084 if (local->iw_mode != IW_MODE_INFRA ||
1087 is_zero_ether_addr(local->bssid) || 1085 is_zero_ether_addr(local->bssid) ||
1088 memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0) 1086 ether_addr_equal(local->bssid, "\x44\x44\x44\x44\x44\x44"))
1089 return 0; 1087 return 0;
1090 1088
1091 ret = prism2_sta_send_mgmt(local, local->bssid, IEEE80211_STYPE_DEAUTH, 1089 ret = prism2_sta_send_mgmt(local, local->bssid, IEEE80211_STYPE_DEAUTH,
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 05ca3402dca7..91158e2e961c 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
5 * Andy Warner <andyw@pobox.com> */ 5 * Andy Warner <andyw@pobox.com> */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/if.h> 8#include <linux/if.h>
10#include <linux/skbuff.h> 9#include <linux/skbuff.h>
11#include <linux/netdevice.h> 10#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index c3d067ee4db9..3bf530d9a40f 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
8 8
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/if.h> 11#include <linux/if.h>
13#include <linux/skbuff.h> 12#include <linux/skbuff.h>
14#include <linux/netdevice.h> 13#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index f8ab193009cd..3aba49259ef1 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1930,10 +1930,10 @@ static int ipw2100_wdev_init(struct net_device *dev)
1930 bg_band->channels[i].max_power = geo->bg[i].max_power; 1930 bg_band->channels[i].max_power = geo->bg[i].max_power;
1931 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 1931 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
1932 bg_band->channels[i].flags |= 1932 bg_band->channels[i].flags |=
1933 IEEE80211_CHAN_PASSIVE_SCAN; 1933 IEEE80211_CHAN_NO_IR;
1934 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 1934 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
1935 bg_band->channels[i].flags |= 1935 bg_band->channels[i].flags |=
1936 IEEE80211_CHAN_NO_IBSS; 1936 IEEE80211_CHAN_NO_IR;
1937 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 1937 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
1938 bg_band->channels[i].flags |= 1938 bg_band->channels[i].flags |=
1939 IEEE80211_CHAN_RADAR; 1939 IEEE80211_CHAN_RADAR;
@@ -6362,7 +6362,6 @@ out:
6362 &ipw2100_attribute_group); 6362 &ipw2100_attribute_group);
6363 6363
6364 free_libipw(dev, 0); 6364 free_libipw(dev, 0);
6365 pci_set_drvdata(pci_dev, NULL);
6366 } 6365 }
6367 6366
6368 pci_iounmap(pci_dev, ioaddr); 6367 pci_iounmap(pci_dev, ioaddr);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 81903e33d5b1..139326065bd9 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -3012,7 +3012,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
3012 spin_lock_irqsave(&priv->ieee->lock, flags); 3012 spin_lock_irqsave(&priv->ieee->lock, flags);
3013 list_for_each_safe(element, safe, &priv->ieee->network_list) { 3013 list_for_each_safe(element, safe, &priv->ieee->network_list) {
3014 network = list_entry(element, struct libipw_network, list); 3014 network = list_entry(element, struct libipw_network, list);
3015 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 3015 if (ether_addr_equal(network->bssid, priv->bssid)) {
3016 list_del(element); 3016 list_del(element);
3017 list_add_tail(&network->list, 3017 list_add_tail(&network->list,
3018 &priv->ieee->network_free_list); 3018 &priv->ieee->network_free_list);
@@ -3921,7 +3921,7 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
3921 int i; 3921 int i;
3922 3922
3923 for (i = 0; i < priv->num_stations; i++) { 3923 for (i = 0; i < priv->num_stations; i++) {
3924 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) { 3924 if (ether_addr_equal(priv->stations[i], bssid)) {
3925 /* Another node is active in network */ 3925 /* Another node is active in network */
3926 priv->missed_adhoc_beacons = 0; 3926 priv->missed_adhoc_beacons = 0;
3927 if (!(priv->config & CFG_STATIC_CHANNEL)) 3927 if (!(priv->config & CFG_STATIC_CHANNEL))
@@ -3953,7 +3953,7 @@ static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
3953 int i; 3953 int i;
3954 3954
3955 for (i = 0; i < priv->num_stations; i++) 3955 for (i = 0; i < priv->num_stations; i++)
3956 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) 3956 if (ether_addr_equal(priv->stations[i], bssid))
3957 return i; 3957 return i;
3958 3958
3959 return IPW_INVALID_STATION; 3959 return IPW_INVALID_STATION;
@@ -5622,7 +5622,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
5622 return 0; 5622 return 0;
5623 } 5623 }
5624 5624
5625 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5625 if (ether_addr_equal(network->bssid, priv->bssid)) {
5626 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " 5626 IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
5627 "because of the same BSSID match: %pM" 5627 "because of the same BSSID match: %pM"
5628 ".\n", print_ssid(ssid, network->ssid, 5628 ".\n", print_ssid(ssid, network->ssid,
@@ -5849,7 +5849,7 @@ static int ipw_best_network(struct ipw_priv *priv,
5849 } 5849 }
5850 5850
5851 if ((priv->config & CFG_STATIC_BSSID) && 5851 if ((priv->config & CFG_STATIC_BSSID) &&
5852 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5852 !ether_addr_equal(network->bssid, priv->bssid)) {
5853 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " 5853 IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
5854 "because of BSSID mismatch: %pM.\n", 5854 "because of BSSID mismatch: %pM.\n",
5855 print_ssid(ssid, network->ssid, 5855 print_ssid(ssid, network->ssid,
@@ -6988,7 +6988,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6988 } 6988 }
6989 if ((priv->status & STATUS_ASSOCIATED) && 6989 if ((priv->status & STATUS_ASSOCIATED) &&
6990 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) { 6990 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6991 if (memcmp(network->bssid, priv->bssid, ETH_ALEN)) 6991 if (!ether_addr_equal(network->bssid, priv->bssid))
6992 if (network->capability & WLAN_CAPABILITY_IBSS) 6992 if (network->capability & WLAN_CAPABILITY_IBSS)
6993 if ((network->ssid_len == 6993 if ((network->ssid_len ==
6994 priv->assoc_network->ssid_len) && 6994 priv->assoc_network->ssid_len) &&
@@ -8210,29 +8210,29 @@ static int is_network_packet(struct ipw_priv *priv,
8210 switch (priv->ieee->iw_mode) { 8210 switch (priv->ieee->iw_mode) {
8211 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */ 8211 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
8212 /* packets from our adapter are dropped (echo) */ 8212 /* packets from our adapter are dropped (echo) */
8213 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN)) 8213 if (ether_addr_equal(header->addr2, priv->net_dev->dev_addr))
8214 return 0; 8214 return 0;
8215 8215
8216 /* {broad,multi}cast packets to our BSSID go through */ 8216 /* {broad,multi}cast packets to our BSSID go through */
8217 if (is_multicast_ether_addr(header->addr1)) 8217 if (is_multicast_ether_addr(header->addr1))
8218 return !memcmp(header->addr3, priv->bssid, ETH_ALEN); 8218 return ether_addr_equal(header->addr3, priv->bssid);
8219 8219
8220 /* packets to our adapter go through */ 8220 /* packets to our adapter go through */
8221 return !memcmp(header->addr1, priv->net_dev->dev_addr, 8221 return ether_addr_equal(header->addr1,
8222 ETH_ALEN); 8222 priv->net_dev->dev_addr);
8223 8223
8224 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */ 8224 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
8225 /* packets from our adapter are dropped (echo) */ 8225 /* packets from our adapter are dropped (echo) */
8226 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN)) 8226 if (ether_addr_equal(header->addr3, priv->net_dev->dev_addr))
8227 return 0; 8227 return 0;
8228 8228
8229 /* {broad,multi}cast packets to our BSS go through */ 8229 /* {broad,multi}cast packets to our BSS go through */
8230 if (is_multicast_ether_addr(header->addr1)) 8230 if (is_multicast_ether_addr(header->addr1))
8231 return !memcmp(header->addr2, priv->bssid, ETH_ALEN); 8231 return ether_addr_equal(header->addr2, priv->bssid);
8232 8232
8233 /* packets to our adapter go through */ 8233 /* packets to our adapter go through */
8234 return !memcmp(header->addr1, priv->net_dev->dev_addr, 8234 return ether_addr_equal(header->addr1,
8235 ETH_ALEN); 8235 priv->net_dev->dev_addr);
8236 } 8236 }
8237 8237
8238 return 1; 8238 return 1;
@@ -8260,7 +8260,7 @@ static int is_duplicate_packet(struct ipw_priv *priv,
8260 list_for_each(p, &priv->ibss_mac_hash[index]) { 8260 list_for_each(p, &priv->ibss_mac_hash[index]) {
8261 entry = 8261 entry =
8262 list_entry(p, struct ipw_ibss_seq, list); 8262 list_entry(p, struct ipw_ibss_seq, list);
8263 if (!memcmp(entry->mac, mac, ETH_ALEN)) 8263 if (ether_addr_equal(entry->mac, mac))
8264 break; 8264 break;
8265 } 8265 }
8266 if (p == &priv->ibss_mac_hash[index]) { 8266 if (p == &priv->ibss_mac_hash[index]) {
@@ -8329,7 +8329,7 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
8329 IEEE80211_STYPE_PROBE_RESP) || 8329 IEEE80211_STYPE_PROBE_RESP) ||
8330 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) == 8330 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
8331 IEEE80211_STYPE_BEACON))) { 8331 IEEE80211_STYPE_BEACON))) {
8332 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN)) 8332 if (ether_addr_equal(header->addr3, priv->bssid))
8333 ipw_add_station(priv, header->addr2); 8333 ipw_add_station(priv, header->addr2);
8334 } 8334 }
8335 8335
@@ -9045,7 +9045,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
9045 } 9045 }
9046 9046
9047 priv->config |= CFG_STATIC_BSSID; 9047 priv->config |= CFG_STATIC_BSSID;
9048 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 9048 if (ether_addr_equal(priv->bssid, wrqu->ap_addr.sa_data)) {
9049 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 9049 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
9050 mutex_unlock(&priv->mutex); 9050 mutex_unlock(&priv->mutex);
9051 return 0; 9051 return 0;
@@ -11472,10 +11472,10 @@ static int ipw_wdev_init(struct net_device *dev)
11472 bg_band->channels[i].max_power = geo->bg[i].max_power; 11472 bg_band->channels[i].max_power = geo->bg[i].max_power;
11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11474 bg_band->channels[i].flags |= 11474 bg_band->channels[i].flags |=
11475 IEEE80211_CHAN_PASSIVE_SCAN; 11475 IEEE80211_CHAN_NO_IR;
11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11477 bg_band->channels[i].flags |= 11477 bg_band->channels[i].flags |=
11478 IEEE80211_CHAN_NO_IBSS; 11478 IEEE80211_CHAN_NO_IR;
11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11480 bg_band->channels[i].flags |= 11480 bg_band->channels[i].flags |=
11481 IEEE80211_CHAN_RADAR; 11481 IEEE80211_CHAN_RADAR;
@@ -11511,10 +11511,10 @@ static int ipw_wdev_init(struct net_device *dev)
11511 a_band->channels[i].max_power = geo->a[i].max_power; 11511 a_band->channels[i].max_power = geo->a[i].max_power;
11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11513 a_band->channels[i].flags |= 11513 a_band->channels[i].flags |=
11514 IEEE80211_CHAN_PASSIVE_SCAN; 11514 IEEE80211_CHAN_NO_IR;
11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) 11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11516 a_band->channels[i].flags |= 11516 a_band->channels[i].flags |=
11517 IEEE80211_CHAN_NO_IBSS; 11517 IEEE80211_CHAN_NO_IR;
11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) 11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11519 a_band->channels[i].flags |= 11519 a_band->channels[i].flags |=
11520 IEEE80211_CHAN_RADAR; 11520 IEEE80211_CHAN_RADAR;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 570d6fb88967..aa301d1eee3c 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -29,7 +29,6 @@
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <linux/init.h>
33#include <linux/interrupt.h> 32#include <linux/interrupt.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
35 34
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 9ffe65931b29..a586a85bfcfe 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -874,13 +874,13 @@ void libipw_rx_any(struct libipw_device *ieee,
874 switch (ieee->iw_mode) { 874 switch (ieee->iw_mode) {
875 case IW_MODE_ADHOC: 875 case IW_MODE_ADHOC:
876 /* our BSS and not from/to DS */ 876 /* our BSS and not from/to DS */
877 if (memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) == 0) 877 if (ether_addr_equal(hdr->addr3, ieee->bssid))
878 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) { 878 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
879 /* promisc: get all */ 879 /* promisc: get all */
880 if (ieee->dev->flags & IFF_PROMISC) 880 if (ieee->dev->flags & IFF_PROMISC)
881 is_packet_for_us = 1; 881 is_packet_for_us = 1;
882 /* to us */ 882 /* to us */
883 else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0) 883 else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
884 is_packet_for_us = 1; 884 is_packet_for_us = 1;
885 /* mcast */ 885 /* mcast */
886 else if (is_multicast_ether_addr(hdr->addr1)) 886 else if (is_multicast_ether_addr(hdr->addr1))
@@ -889,18 +889,18 @@ void libipw_rx_any(struct libipw_device *ieee,
889 break; 889 break;
890 case IW_MODE_INFRA: 890 case IW_MODE_INFRA:
891 /* our BSS (== from our AP) and from DS */ 891 /* our BSS (== from our AP) and from DS */
892 if (memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) == 0) 892 if (ether_addr_equal(hdr->addr2, ieee->bssid))
893 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) { 893 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
894 /* promisc: get all */ 894 /* promisc: get all */
895 if (ieee->dev->flags & IFF_PROMISC) 895 if (ieee->dev->flags & IFF_PROMISC)
896 is_packet_for_us = 1; 896 is_packet_for_us = 1;
897 /* to us */ 897 /* to us */
898 else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0) 898 else if (ether_addr_equal(hdr->addr1, ieee->dev->dev_addr))
899 is_packet_for_us = 1; 899 is_packet_for_us = 1;
900 /* mcast */ 900 /* mcast */
901 else if (is_multicast_ether_addr(hdr->addr1)) { 901 else if (is_multicast_ether_addr(hdr->addr1)) {
902 /* not our own packet bcasted from AP */ 902 /* not our own packet bcasted from AP */
903 if (memcmp(hdr->addr3, ieee->dev->dev_addr, ETH_ALEN)) 903 if (!ether_addr_equal(hdr->addr3, ieee->dev->dev_addr))
904 is_packet_for_us = 1; 904 is_packet_for_us = 1;
905 } 905 }
906 } 906 }
@@ -1468,7 +1468,7 @@ static inline int is_same_network(struct libipw_network *src,
1468 * as one network */ 1468 * as one network */
1469 return ((src->ssid_len == dst->ssid_len) && 1469 return ((src->ssid_len == dst->ssid_len) &&
1470 (src->channel == dst->channel) && 1470 (src->channel == dst->channel) &&
1471 ether_addr_equal(src->bssid, dst->bssid) && 1471 ether_addr_equal_64bits(src->bssid, dst->bssid) &&
1472 !memcmp(src->ssid, dst->ssid, src->ssid_len)); 1472 !memcmp(src->ssid, dst->ssid, src->ssid_len));
1473} 1473}
1474 1474
diff --git a/drivers/net/wireless/iwlegacy/3945-debug.c b/drivers/net/wireless/iwlegacy/3945-debug.c
index f767dd106b09..c1b4441fb8b2 100644
--- a/drivers/net/wireless/iwlegacy/3945-debug.c
+++ b/drivers/net/wireless/iwlegacy/3945-debug.c
@@ -48,7 +48,7 @@ il3945_stats_flag(struct il_priv *il, char *buf, int bufsz)
48 return p; 48 return p;
49} 49}
50 50
51ssize_t 51static ssize_t
52il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, 52il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
53 size_t count, loff_t *ppos) 53 size_t count, loff_t *ppos)
54{ 54{
@@ -313,7 +313,7 @@ il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
313 return ret; 313 return ret;
314} 314}
315 315
316ssize_t 316static ssize_t
317il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, 317il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
318 size_t count, loff_t *ppos) 318 size_t count, loff_t *ppos)
319{ 319{
@@ -403,7 +403,7 @@ il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
403 return ret; 403 return ret;
404} 404}
405 405
406ssize_t 406static ssize_t
407il3945_ucode_general_stats_read(struct file *file, char __user *user_buf, 407il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
408 size_t count, loff_t *ppos) 408 size_t count, loff_t *ppos)
409{ 409{
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index dea3b50d68b9..0487461ae4da 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -1595,7 +1595,7 @@ il3945_get_channels_for_scan(struct il_priv *il, enum ieee80211_band band,
1595 * and use long active_dwell time. 1595 * and use long active_dwell time.
1596 */ 1596 */
1597 if (!is_active || il_is_channel_passive(ch_info) || 1597 if (!is_active || il_is_channel_passive(ch_info) ||
1598 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { 1598 (chan->flags & IEEE80211_CHAN_NO_IR)) {
1599 scan_ch->type = 0; /* passive */ 1599 scan_ch->type = 0; /* passive */
1600 if (IL_UCODE_API(il->ucode_ver) == 1) 1600 if (IL_UCODE_API(il->ucode_ver) == 1)
1601 scan_ch->active_dwell = 1601 scan_ch->active_dwell =
@@ -2396,8 +2396,7 @@ __il3945_up(struct il_priv *il)
2396 clear_bit(S_RFKILL, &il->status); 2396 clear_bit(S_RFKILL, &il->status);
2397 else { 2397 else {
2398 set_bit(S_RFKILL, &il->status); 2398 set_bit(S_RFKILL, &il->status);
2399 IL_WARN("Radio disabled by HW RF Kill switch\n"); 2399 return -ERFKILL;
2400 return -ENODEV;
2401 } 2400 }
2402 2401
2403 _il_wr(il, CSR_INT, 0xFFFFFFFF); 2402 _il_wr(il, CSR_INT, 0xFFFFFFFF);
@@ -3575,9 +3574,9 @@ il3945_setup_mac(struct il_priv *il)
3575 hw->wiphy->interface_modes = 3574 hw->wiphy->interface_modes =
3576 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 3575 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
3577 3576
3578 hw->wiphy->flags |= 3577 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
3579 WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 3578 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
3580 WIPHY_FLAG_IBSS_RSN; 3579 REGULATORY_DISABLE_BEACON_HINTS;
3581 3580
3582 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 3581 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3583 3582
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index aea667b430c3..9a45f6f626f6 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -25,7 +25,6 @@
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/skbuff.h> 28#include <linux/skbuff.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
31#include <net/mac80211.h> 30#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index f09e257759d5..d37a6fd90d40 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -26,7 +26,6 @@
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
@@ -466,10 +465,10 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)
466 switch (il->iw_mode) { 465 switch (il->iw_mode) {
467 case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ 466 case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */
468 /* packets to our IBSS update information */ 467 /* packets to our IBSS update information */
469 return ether_addr_equal(header->addr3, il->bssid); 468 return ether_addr_equal_64bits(header->addr3, il->bssid);
470 case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ 469 case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */
471 /* packets to our IBSS update information */ 470 /* packets to our IBSS update information */
472 return ether_addr_equal(header->addr2, il->bssid); 471 return ether_addr_equal_64bits(header->addr2, il->bssid);
473 default: 472 default:
474 return 1; 473 return 1;
475 } 474 }
diff --git a/drivers/net/wireless/iwlegacy/4965-debug.c b/drivers/net/wireless/iwlegacy/4965-debug.c
index c8153fc64f74..e0597bfdddb8 100644
--- a/drivers/net/wireless/iwlegacy/4965-debug.c
+++ b/drivers/net/wireless/iwlegacy/4965-debug.c
@@ -55,7 +55,7 @@ il4965_stats_flag(struct il_priv *il, char *buf, int bufsz)
55 return p; 55 return p;
56} 56}
57 57
58ssize_t 58static ssize_t
59il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, 59il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
60 size_t count, loff_t *ppos) 60 size_t count, loff_t *ppos)
61{ 61{
@@ -467,7 +467,7 @@ il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
467 return ret; 467 return ret;
468} 468}
469 469
470ssize_t 470static ssize_t
471il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf, 471il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
472 size_t count, loff_t *ppos) 472 size_t count, loff_t *ppos)
473{ 473{
@@ -633,7 +633,7 @@ il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
633 return ret; 633 return ret;
634} 634}
635 635
636ssize_t 636static ssize_t
637il4965_ucode_general_stats_read(struct file *file, char __user *user_buf, 637il4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
638 size_t count, loff_t *ppos) 638 size_t count, loff_t *ppos)
639{ 639{
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 3982ab76f375..43f488a8cda2 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -805,7 +805,7 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
805 } 805 }
806 806
807 if (!is_active || il_is_channel_passive(ch_info) || 807 if (!is_active || il_is_channel_passive(ch_info) ||
808 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 808 (chan->flags & IEEE80211_CHAN_NO_IR))
809 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 809 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
810 else 810 else
811 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 811 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -5778,9 +5778,9 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
5778 hw->wiphy->interface_modes = 5778 hw->wiphy->interface_modes =
5779 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 5779 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
5780 5780
5781 hw->wiphy->flags |= 5781 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
5782 WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 5782 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
5783 WIPHY_FLAG_IBSS_RSN; 5783 REGULATORY_DISABLE_BEACON_HINTS;
5784 5784
5785 /* 5785 /*
5786 * For now, disable PS by default because it affects 5786 * For now, disable PS by default because it affects
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index 3ccbaf791b48..4d5e33259ca8 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -24,7 +24,6 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h> 27#include <linux/skbuff.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <net/mac80211.h> 29#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index 777a578294bd..fe47db9c20cd 100644
--- a/drivers/net/wireless/iwlegacy/4965.c
+++ b/drivers/net/wireless/iwlegacy/4965.c
@@ -26,7 +26,6 @@
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h> 29#include <linux/pci.h>
31#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
32#include <linux/delay.h> 31#include <linux/delay.h>
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index b03e22ef5462..02e8233ccf29 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -33,7 +33,6 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/lockdep.h> 35#include <linux/lockdep.h>
36#include <linux/init.h>
37#include <linux/pci.h> 36#include <linux/pci.h>
38#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
@@ -3445,10 +3444,10 @@ il_init_geos(struct il_priv *il)
3445 3444
3446 if (il_is_channel_valid(ch)) { 3445 if (il_is_channel_valid(ch)) {
3447 if (!(ch->flags & EEPROM_CHANNEL_IBSS)) 3446 if (!(ch->flags & EEPROM_CHANNEL_IBSS))
3448 geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; 3447 geo_ch->flags |= IEEE80211_CHAN_NO_IR;
3449 3448
3450 if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) 3449 if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
3451 geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 3450 geo_ch->flags |= IEEE80211_CHAN_NO_IR;
3452 3451
3453 if (ch->flags & EEPROM_CHANNEL_RADAR) 3452 if (ch->flags & EEPROM_CHANNEL_RADAR)
3454 geo_ch->flags |= IEEE80211_CHAN_RADAR; 3453 geo_ch->flags |= IEEE80211_CHAN_RADAR;
@@ -3746,10 +3745,10 @@ il_full_rxon_required(struct il_priv *il)
3746 3745
3747 /* These items are only settable from the full RXON command */ 3746 /* These items are only settable from the full RXON command */
3748 CHK(!il_is_associated(il)); 3747 CHK(!il_is_associated(il));
3749 CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr)); 3748 CHK(!ether_addr_equal_64bits(staging->bssid_addr, active->bssid_addr));
3750 CHK(!ether_addr_equal(staging->node_addr, active->node_addr)); 3749 CHK(!ether_addr_equal_64bits(staging->node_addr, active->node_addr));
3751 CHK(!ether_addr_equal(staging->wlap_bssid_addr, 3750 CHK(!ether_addr_equal_64bits(staging->wlap_bssid_addr,
3752 active->wlap_bssid_addr)); 3751 active->wlap_bssid_addr));
3753 CHK_NEQ(staging->dev_type, active->dev_type); 3752 CHK_NEQ(staging->dev_type, active->dev_type);
3754 CHK_NEQ(staging->channel, active->channel); 3753 CHK_NEQ(staging->channel, active->channel);
3755 CHK_NEQ(staging->air_propagation, active->air_propagation); 3754 CHK_NEQ(staging->air_propagation, active->air_propagation);
diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c
index eff26501d60a..344010153196 100644
--- a/drivers/net/wireless/iwlegacy/debug.c
+++ b/drivers/net/wireless/iwlegacy/debug.c
@@ -31,7 +31,7 @@
31 31
32#include "common.h" 32#include "common.h"
33 33
34void 34static void
35il_clear_traffic_stats(struct il_priv *il) 35il_clear_traffic_stats(struct il_priv *il)
36{ 36{
37 memset(&il->tx_stats, 0, sizeof(struct traffic_stats)); 37 memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
@@ -567,12 +567,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
567 flags & IEEE80211_CHAN_RADAR ? 567 flags & IEEE80211_CHAN_RADAR ?
568 " (IEEE 802.11h required)" : "", 568 " (IEEE 802.11h required)" : "",
569 ((channels[i]. 569 ((channels[i].
570 flags & IEEE80211_CHAN_NO_IBSS) || 570 flags & IEEE80211_CHAN_NO_IR) ||
571 (channels[i]. 571 (channels[i].
572 flags & IEEE80211_CHAN_RADAR)) ? "" : 572 flags & IEEE80211_CHAN_RADAR)) ? "" :
573 ", IBSS", 573 ", IBSS",
574 channels[i]. 574 channels[i].
575 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 575 flags & IEEE80211_CHAN_NO_IR ?
576 "passive only" : "active/passive"); 576 "passive only" : "active/passive");
577 } 577 }
578 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ); 578 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
@@ -594,12 +594,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
594 flags & IEEE80211_CHAN_RADAR ? 594 flags & IEEE80211_CHAN_RADAR ?
595 " (IEEE 802.11h required)" : "", 595 " (IEEE 802.11h required)" : "",
596 ((channels[i]. 596 ((channels[i].
597 flags & IEEE80211_CHAN_NO_IBSS) || 597 flags & IEEE80211_CHAN_NO_IR) ||
598 (channels[i]. 598 (channels[i].
599 flags & IEEE80211_CHAN_RADAR)) ? "" : 599 flags & IEEE80211_CHAN_RADAR)) ? "" :
600 ", IBSS", 600 ", IBSS",
601 channels[i]. 601 channels[i].
602 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 602 flags & IEEE80211_CHAN_NO_IR ?
603 "passive only" : "active/passive"); 603 "passive only" : "active/passive");
604 } 604 }
605 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 605 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 23d5f0275ce9..562772d85102 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index 1b0f0d502568..be1086c87157 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h
index cfddde194940..aeae4e80ea40 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.h
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index ebdac909f0cd..751ae1d10b7f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index d94f8ab15004..d2fe2596d54e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -352,12 +352,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
352 channels[i].max_power, 352 channels[i].max_power,
353 channels[i].flags & IEEE80211_CHAN_RADAR ? 353 channels[i].flags & IEEE80211_CHAN_RADAR ?
354 " (IEEE 802.11h required)" : "", 354 " (IEEE 802.11h required)" : "",
355 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 355 ((channels[i].flags & IEEE80211_CHAN_NO_IR)
356 || (channels[i].flags & 356 || (channels[i].flags &
357 IEEE80211_CHAN_RADAR)) ? "" : 357 IEEE80211_CHAN_RADAR)) ? "" :
358 ", IBSS", 358 ", IBSS",
359 channels[i].flags & 359 channels[i].flags &
360 IEEE80211_CHAN_PASSIVE_SCAN ? 360 IEEE80211_CHAN_NO_IR ?
361 "passive only" : "active/passive"); 361 "passive only" : "active/passive");
362 } 362 }
363 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 363 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
@@ -375,12 +375,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
375 channels[i].max_power, 375 channels[i].max_power,
376 channels[i].flags & IEEE80211_CHAN_RADAR ? 376 channels[i].flags & IEEE80211_CHAN_RADAR ?
377 " (IEEE 802.11h required)" : "", 377 " (IEEE 802.11h required)" : "",
378 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 378 ((channels[i].flags & IEEE80211_CHAN_NO_IR)
379 || (channels[i].flags & 379 || (channels[i].flags &
380 IEEE80211_CHAN_RADAR)) ? "" : 380 IEEE80211_CHAN_RADAR)) ? "" :
381 ", IBSS", 381 ", IBSS",
382 channels[i].flags & 382 channels[i].flags &
383 IEEE80211_CHAN_PASSIVE_SCAN ? 383 IEEE80211_CHAN_NO_IR ?
384 "passive only" : "active/passive"); 384 "passive only" : "active/passive");
385 } 385 }
386 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 386 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 7434d9edf3b7..3441f70d0ff9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index 352c6cb7b4f1..7b140e487deb 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.c b/drivers/net/wireless/iwlwifi/dvm/led.c
index 33c7e15d24f5..ca4d6692cc4e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/led.c
+++ b/drivers/net/wireless/iwlwifi/dvm/led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,6 @@
27 27
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/delay.h> 30#include <linux/delay.h>
32#include <linux/skbuff.h> 31#include <linux/skbuff.h>
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.h b/drivers/net/wireless/iwlwifi/dvm/led.h
index 8749dcfe695f..6a0817d9c4fa 100644
--- a/drivers/net/wireless/iwlwifi/dvm/led.h
+++ b/drivers/net/wireless/iwlwifi/dvm/led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 3d5bdc4217a8..576f7ee38ca5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -29,7 +29,6 @@
29#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h> 32#include <linux/sched.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35 34
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cae4d3182e33..c24d1d3d55f6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -28,7 +28,6 @@
28 *****************************************************************************/ 28 *****************************************************************************/
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
@@ -155,9 +154,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
155 ARRAY_SIZE(iwlagn_iface_combinations_dualmode); 154 ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
156 } 155 }
157 156
158 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 157 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
159 WIPHY_FLAG_DISABLE_BEACON_HINTS | 158 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
160 WIPHY_FLAG_IBSS_RSN; 159 REGULATORY_DISABLE_BEACON_HINTS;
161 160
162#ifdef CONFIG_PM_SLEEP 161#ifdef CONFIG_PM_SLEEP
163 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 162 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
@@ -322,12 +321,6 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
322 321
323 flush_workqueue(priv->workqueue); 322 flush_workqueue(priv->workqueue);
324 323
325 /* User space software may expect getting rfkill changes
326 * even if interface is down, trans->down will leave the RF
327 * kill interrupt enabled
328 */
329 iwl_trans_stop_hw(priv->trans, false);
330
331 IWL_DEBUG_MAC80211(priv, "leave\n"); 324 IWL_DEBUG_MAC80211(priv, "leave\n");
332} 325}
333 326
@@ -413,9 +406,8 @@ static bool iwl_resume_status_fn(struct iwl_notif_wait_data *notif_wait,
413{ 406{
414 struct iwl_resume_data *resume_data = data; 407 struct iwl_resume_data *resume_data = data;
415 struct iwl_priv *priv = resume_data->priv; 408 struct iwl_priv *priv = resume_data->priv;
416 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
417 409
418 if (len - 4 != sizeof(*resume_data->cmd)) { 410 if (iwl_rx_packet_payload_len(pkt) != sizeof(*resume_data->cmd)) {
419 IWL_ERR(priv, "rx wrong size data\n"); 411 IWL_ERR(priv, "rx wrong size data\n");
420 return true; 412 return true;
421 } 413 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7aad766865cf..ba1b1ea54252 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -1313,7 +1313,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1313 } 1313 }
1314 1314
1315 /* Reset chip to save power until we load uCode during "up". */ 1315 /* Reset chip to save power until we load uCode during "up". */
1316 iwl_trans_stop_hw(priv->trans, false); 1316 iwl_trans_stop_device(priv->trans);
1317 1317
1318 priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg, 1318 priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg,
1319 priv->eeprom_blob, 1319 priv->eeprom_blob,
@@ -1458,7 +1458,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1458 1458
1459 dev_kfree_skb(priv->beacon_skb); 1459 dev_kfree_skb(priv->beacon_skb);
1460 1460
1461 iwl_trans_stop_hw(priv->trans, true); 1461 iwl_trans_op_mode_leave(priv->trans);
1462 ieee80211_free_hw(priv->hw); 1462 ieee80211_free_hw(priv->hw);
1463} 1463}
1464 1464
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index 77cb59712235..b4e61417013a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -30,7 +30,6 @@
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/init.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35#include "iwl-io.h" 34#include "iwl-io.h"
36#include "iwl-debug.h" 35#include "iwl-debug.h"
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.h b/drivers/net/wireless/iwlwifi/dvm/power.h
index 7b03e1342d47..570d3a5e4670 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.h
+++ b/drivers/net/wireless/iwlwifi/dvm/power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index b647e506564c..0977d93b529d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -24,7 +24,6 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h> 27#include <linux/skbuff.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <net/mac80211.h> 29#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h
index 26fc550cd68c..bdd5644a400b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -389,13 +389,6 @@ struct iwl_lq_sta {
389 u8 last_bt_traffic; 389 u8 last_bt_traffic;
390}; 390};
391 391
392static inline u8 num_of_ant(u8 mask)
393{
394 return !!((mask) & ANT_A) +
395 !!((mask) & ANT_B) +
396 !!((mask) & ANT_C);
397}
398
399static inline u8 first_antenna(u8 mask) 392static inline u8 first_antenna(u8 mask)
400{ 393{
401 if (mask & ANT_A) 394 if (mask & ANT_A)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index d71776dd1e6a..7a1bc1c547e1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portionhelp of the ieee80211 subsystem header files. 6 * as portionhelp of the ieee80211 subsystem header files.
@@ -205,8 +205,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
205 struct iwl_device_cmd *cmd) 205 struct iwl_device_cmd *cmd)
206{ 206{
207 struct iwl_rx_packet *pkt = rxb_addr(rxb); 207 struct iwl_rx_packet *pkt = rxb_addr(rxb);
208 u32 __maybe_unused len = 208 u32 __maybe_unused len = iwl_rx_packet_len(pkt);
209 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
210 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " 209 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
211 "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len); 210 "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len);
212 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); 211 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
@@ -457,7 +456,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
457 const int reg_recalib_period = 60; 456 const int reg_recalib_period = 60;
458 int change; 457 int change;
459 struct iwl_rx_packet *pkt = rxb_addr(rxb); 458 struct iwl_rx_packet *pkt = rxb_addr(rxb);
460 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 459 u32 len = iwl_rx_packet_payload_len(pkt);
461 __le32 *flag; 460 __le32 *flag;
462 struct statistics_general_common *common; 461 struct statistics_general_common *common;
463 struct statistics_rx_non_phy *rx_non_phy; 462 struct statistics_rx_non_phy *rx_non_phy;
@@ -467,8 +466,6 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
467 struct statistics_tx *tx; 466 struct statistics_tx *tx;
468 struct statistics_bt_activity *bt_activity; 467 struct statistics_bt_activity *bt_activity;
469 468
470 len -= sizeof(struct iwl_cmd_header); /* skip header */
471
472 IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", 469 IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
473 len); 470 len);
474 471
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index d7ce2f12a907..503a81e58185 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 35e0ee8b4e5b..be98b913ed58 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -544,7 +544,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
544 channel = chan->hw_value; 544 channel = chan->hw_value;
545 scan_ch->channel = cpu_to_le16(channel); 545 scan_ch->channel = cpu_to_le16(channel);
546 546
547 if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 547 if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR))
548 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 548 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
549 else 549 else
550 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 550 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index c3c13ce96eb0..c0d070c5df5e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index fbeee081ee2f..058c5892c427 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -30,7 +30,6 @@
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/init.h>
34#include <net/mac80211.h> 33#include <net/mac80211.h>
35#include "iwl-io.h" 34#include "iwl-io.h"
36#include "iwl-modparams.h" 35#include "iwl-modparams.h"
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h
index 9356c4b908ca..507726534b84 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.h
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 1fef5240e6ad..a6839dfcb82d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -29,7 +29,6 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h> 32#include <linux/sched.h>
34#include <linux/ieee80211.h> 33#include <linux/ieee80211.h>
35#include "iwl-io.h" 34#include "iwl-io.h"
@@ -368,6 +367,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
368 goto drop_unlock_priv; 367 goto drop_unlock_priv;
369 368
370 memset(dev_cmd, 0, sizeof(*dev_cmd)); 369 memset(dev_cmd, 0, sizeof(*dev_cmd));
370 dev_cmd->hdr.cmd = REPLY_TX;
371 tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; 371 tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
372 372
373 /* Total # bytes to be transmitted */ 373 /* Total # bytes to be transmitted */
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 63637949a146..cf03ef5619d9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -28,7 +28,6 @@
28 *****************************************************************************/ 28 *****************************************************************************/
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/init.h>
32 31
33#include "iwl-io.h" 32#include "iwl-io.h"
34#include "iwl-agn-hw.h" 33#include "iwl-agn-hw.h"
@@ -389,7 +388,6 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
389{ 388{
390 struct iwl_priv *priv = data; 389 struct iwl_priv *priv = data;
391 struct iwl_calib_hdr *hdr; 390 struct iwl_calib_hdr *hdr;
392 int len;
393 391
394 if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) { 392 if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) {
395 WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION); 393 WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION);
@@ -397,12 +395,8 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
397 } 395 }
398 396
399 hdr = (struct iwl_calib_hdr *)pkt->data; 397 hdr = (struct iwl_calib_hdr *)pkt->data;
400 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
401 398
402 /* reduce the size by the length field itself */ 399 if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt)))
403 len -= sizeof(__le32);
404
405 if (iwl_calib_set(priv, hdr, len))
406 IWL_ERR(priv, "Failed to record calibration data %d\n", 400 IWL_ERR(priv, "Failed to record calibration data %d\n",
407 hdr->op_code); 401 hdr->op_code);
408 402
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 0d2afe098afc..854ba84ccb73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index c727ec7c90a6..3e63323637f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ecc01e1a61a1..6674f2c4541c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 8ac305be68f4..8048de90233f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 3c34a72a5d64..2a59da2ff87a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -108,7 +108,7 @@ static const struct iwl_base_params iwl7000_base_params = {
108}; 108};
109 109
110static const struct iwl_ht_params iwl7000_ht_params = { 110static const struct iwl_ht_params iwl7000_ht_params = {
111 .use_rts_for_aggregation = true, /* use rts/cts protection */ 111 .stbc = true,
112 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 112 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
113}; 113};
114 114
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 6d73f943cefa..7f37fb86837b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 03fd9aa8bfda..1ced525157dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -129,6 +129,12 @@ enum iwl_led_mode {
129#define ANT_BC (ANT_B | ANT_C) 129#define ANT_BC (ANT_B | ANT_C)
130#define ANT_ABC (ANT_A | ANT_B | ANT_C) 130#define ANT_ABC (ANT_A | ANT_B | ANT_C)
131 131
132static inline u8 num_of_ant(u8 mask)
133{
134 return !!((mask) & ANT_A) +
135 !!((mask) & ANT_B) +
136 !!((mask) & ANT_C);
137}
132 138
133/* 139/*
134 * @max_ll_items: max number of OTP blocks 140 * @max_ll_items: max number of OTP blocks
@@ -156,12 +162,14 @@ struct iwl_base_params {
156}; 162};
157 163
158/* 164/*
165 * @stbc: support Tx STBC and 1*SS Rx STBC
159 * @use_rts_for_aggregation: use rts/cts protection for HT traffic 166 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
160 * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 167 * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40
161 */ 168 */
162struct iwl_ht_params { 169struct iwl_ht_params {
163 enum ieee80211_smps_mode smps_mode; 170 enum ieee80211_smps_mode smps_mode;
164 const bool ht_greenfield_support; /* if used set to true */ 171 const bool ht_greenfield_support; /* if used set to true */
172 const bool stbc;
165 bool use_rts_for_aggregation; 173 bool use_rts_for_aggregation;
166 u8 ht40_bands; 174 u8 ht40_bands;
167}; 175};
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index da4eca8b3007..9d325516c42d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -198,7 +198,8 @@
198 CSR_INT_BIT_RF_KILL | \ 198 CSR_INT_BIT_RF_KILL | \
199 CSR_INT_BIT_SW_RX | \ 199 CSR_INT_BIT_SW_RX | \
200 CSR_INT_BIT_WAKEUP | \ 200 CSR_INT_BIT_WAKEUP | \
201 CSR_INT_BIT_ALIVE) 201 CSR_INT_BIT_ALIVE | \
202 CSR_INT_BIT_RX_PERIODIC)
202 203
203/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ 204/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
204#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ 205#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index b2bb32a781dd..a75aac986a23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 8f61c717f619..23e7351e02de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 684c416d3493..78bd41bf34b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2009 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index ff570027e9dd..c3728163be46 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -322,6 +322,41 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
322 pieces->img[type].sec[sec].offset = offset; 322 pieces->img[type].sec[sec].offset = offset;
323} 323}
324 324
325static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len)
326{
327 int i, j;
328 struct iwl_fw_cscheme_list *l = (struct iwl_fw_cscheme_list *)data;
329 struct iwl_fw_cipher_scheme *fwcs;
330 struct ieee80211_cipher_scheme *cs;
331 u32 cipher;
332
333 if (len < sizeof(*l) ||
334 len < sizeof(l->size) + l->size * sizeof(l->cs[0]))
335 return -EINVAL;
336
337 for (i = 0, j = 0; i < IWL_UCODE_MAX_CS && i < l->size; i++) {
338 fwcs = &l->cs[j];
339 cipher = le32_to_cpu(fwcs->cipher);
340
341 /* we skip schemes with zero cipher suite selector */
342 if (!cipher)
343 continue;
344
345 cs = &fw->cs[j++];
346 cs->cipher = cipher;
347 cs->iftype = BIT(NL80211_IFTYPE_STATION);
348 cs->hdr_len = fwcs->hdr_len;
349 cs->pn_len = fwcs->pn_len;
350 cs->pn_off = fwcs->pn_off;
351 cs->key_idx_off = fwcs->key_idx_off;
352 cs->key_idx_mask = fwcs->key_idx_mask;
353 cs->key_idx_shift = fwcs->key_idx_shift;
354 cs->mic_len = fwcs->mic_len;
355 }
356
357 return 0;
358}
359
325/* 360/*
326 * Gets uCode section from tlv. 361 * Gets uCode section from tlv.
327 */ 362 */
@@ -729,6 +764,10 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
729 return -EINVAL; 764 return -EINVAL;
730 } 765 }
731 break; 766 break;
767 case IWL_UCODE_TLV_CSCHEME:
768 if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len))
769 goto invalid_tlv_len;
770 break;
732 default: 771 default:
733 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); 772 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
734 break; 773 break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 429337a2b9a1..592c01e11013 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -67,7 +67,7 @@
67/* for all modules */ 67/* for all modules */
68#define DRV_NAME "iwlwifi" 68#define DRV_NAME "iwlwifi"
69#define IWLWIFI_VERSION "in-tree:" 69#define IWLWIFI_VERSION "in-tree:"
70#define DRV_COPYRIGHT "Copyright(c) 2003-2013 Intel Corporation" 70#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
71#define DRV_AUTHOR "<ilw@linux.intel.com>" 71#define DRV_AUTHOR "<ilw@linux.intel.com>"
72 72
73 73
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 4c887f365908..c44cf1149648 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -614,10 +614,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
614 channel->flags = IEEE80211_CHAN_NO_HT40; 614 channel->flags = IEEE80211_CHAN_NO_HT40;
615 615
616 if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) 616 if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS))
617 channel->flags |= IEEE80211_CHAN_NO_IBSS; 617 channel->flags |= IEEE80211_CHAN_NO_IR;
618 618
619 if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) 619 if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE))
620 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 620 channel->flags |= IEEE80211_CHAN_NO_IR;
621 621
622 if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) 622 if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR)
623 channel->flags |= IEEE80211_CHAN_RADAR; 623 channel->flags |= IEEE80211_CHAN_RADAR;
@@ -751,6 +751,13 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
751 ht_info->ht_supported = true; 751 ht_info->ht_supported = true;
752 ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; 752 ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40;
753 753
754 if (cfg->ht_params->stbc) {
755 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
756
757 if (tx_chains > 1)
758 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
759 }
760
754 if (iwlwifi_mod_params.amsdu_size_8K) 761 if (iwlwifi_mod_params.amsdu_size_8K)
755 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 762 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
756 763
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index d73304a23ec2..e3c7deafabe6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
index e5f2e362ab0b..25d0105741db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
index 8e941f8bd7d6..a6d3bdf82cdd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 484d318245fb..9564ae173d06 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 6c6c35c5228c..88e2d6eb569f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -125,6 +125,7 @@ enum iwl_ucode_tlv_type {
125 IWL_UCODE_TLV_SECURE_SEC_INIT = 25, 125 IWL_UCODE_TLV_SECURE_SEC_INIT = 25,
126 IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26, 126 IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26,
127 IWL_UCODE_TLV_NUM_OF_CPU = 27, 127 IWL_UCODE_TLV_NUM_OF_CPU = 27,
128 IWL_UCODE_TLV_CSCHEME = 28,
128}; 129};
129 130
130struct iwl_ucode_tlv { 131struct iwl_ucode_tlv {
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 75db087120c3..5f1493c44097 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -92,6 +92,9 @@
92 * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API 92 * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
93 * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command 93 * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
94 * containing CAM (Continuous Active Mode) indication. 94 * containing CAM (Continuous Active Mode) indication.
95 * @IWL_UCODE_TLV_FLAGS_P2P_PS: P2P client power save is supported (only on a
96 * single bound interface).
97 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
95 */ 98 */
96enum iwl_ucode_tlv_flag { 99enum iwl_ucode_tlv_flag {
97 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 100 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
@@ -113,7 +116,9 @@ enum iwl_ucode_tlv_flag {
113 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17), 116 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
114 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), 117 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
115 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20), 118 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
119 IWL_UCODE_TLV_FLAGS_P2P_PS = BIT(21),
116 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24), 120 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
121 IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
117}; 122};
118 123
119/* The default calibrate table size if not specified by firmware file */ 124/* The default calibrate table size if not specified by firmware file */
@@ -209,6 +214,44 @@ enum iwl_fw_phy_cfg {
209 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS, 214 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
210}; 215};
211 216
217#define IWL_UCODE_MAX_CS 1
218
219/**
220 * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW.
221 * @cipher: a cipher suite selector
222 * @flags: cipher scheme flags (currently reserved for a future use)
223 * @hdr_len: a size of MPDU security header
224 * @pn_len: a size of PN
225 * @pn_off: an offset of pn from the beginning of the security header
226 * @key_idx_off: an offset of key index byte in the security header
227 * @key_idx_mask: a bit mask of key_idx bits
228 * @key_idx_shift: bit shift needed to get key_idx
229 * @mic_len: mic length in bytes
230 * @hw_cipher: a HW cipher index used in host commands
231 */
232struct iwl_fw_cipher_scheme {
233 __le32 cipher;
234 u8 flags;
235 u8 hdr_len;
236 u8 pn_len;
237 u8 pn_off;
238 u8 key_idx_off;
239 u8 key_idx_mask;
240 u8 key_idx_shift;
241 u8 mic_len;
242 u8 hw_cipher;
243} __packed;
244
245/**
246 * struct iwl_fw_cscheme_list - a cipher scheme list
247 * @size: a number of entries
248 * @cs: cipher scheme entries
249 */
250struct iwl_fw_cscheme_list {
251 u8 size;
252 struct iwl_fw_cipher_scheme cs[];
253} __packed;
254
212/** 255/**
213 * struct iwl_fw - variables associated with the firmware 256 * struct iwl_fw - variables associated with the firmware
214 * 257 *
@@ -224,6 +267,7 @@ enum iwl_fw_phy_cfg {
224 * @inst_evtlog_size: event log size for runtime ucode. 267 * @inst_evtlog_size: event log size for runtime ucode.
225 * @inst_errlog_ptr: error log offfset for runtime ucode. 268 * @inst_errlog_ptr: error log offfset for runtime ucode.
226 * @mvm_fw: indicates this is MVM firmware 269 * @mvm_fw: indicates this is MVM firmware
270 * @cipher_scheme: optional external cipher scheme.
227 */ 271 */
228struct iwl_fw { 272struct iwl_fw {
229 u32 ucode_ver; 273 u32 ucode_ver;
@@ -243,6 +287,8 @@ struct iwl_fw {
243 u32 phy_config; 287 u32 phy_config;
244 288
245 bool mvm_fw; 289 bool mvm_fw;
290
291 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
246}; 292};
247 293
248static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw) 294static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index ad8e19a56eca..f98175a0d35b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 63d10ec08dbc..c339c1bed080 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index a1f580c0c6c6..0a84ade7edac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
index 940b8a9d5285..b5bc959b1dfe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
index 2e2f1c8c99f9..95af97a6c2cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index b76a9a8fc0b3..f06f4cbe1317 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -223,10 +223,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
223 channel->flags |= IEEE80211_CHAN_NO_160MHZ; 223 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
224 224
225 if (!(ch_flags & NVM_CHANNEL_IBSS)) 225 if (!(ch_flags & NVM_CHANNEL_IBSS))
226 channel->flags |= IEEE80211_CHAN_NO_IBSS; 226 channel->flags |= IEEE80211_CHAN_NO_IR;
227 227
228 if (!(ch_flags & NVM_CHANNEL_ACTIVE)) 228 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
229 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 229 channel->flags |= IEEE80211_CHAN_NO_IR;
230 230
231 if (ch_flags & NVM_CHANNEL_RADAR) 231 if (ch_flags & NVM_CHANNEL_RADAR)
232 channel->flags |= IEEE80211_CHAN_RADAR; 232 channel->flags |= IEEE80211_CHAN_RADAR;
@@ -263,13 +263,19 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
263 struct iwl_nvm_data *data, 263 struct iwl_nvm_data *data,
264 struct ieee80211_sta_vht_cap *vht_cap) 264 struct ieee80211_sta_vht_cap *vht_cap)
265{ 265{
266 int num_ants = num_of_ant(data->valid_rx_ant);
267
266 vht_cap->vht_supported = true; 268 vht_cap->vht_supported = true;
267 269
268 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | 270 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
269 IEEE80211_VHT_CAP_RXSTBC_1 | 271 IEEE80211_VHT_CAP_RXSTBC_1 |
270 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 272 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
273 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
271 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; 274 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
272 275
276 if (num_ants > 1)
277 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
278
273 if (iwlwifi_mod_params.amsdu_size_8K) 279 if (iwlwifi_mod_params.amsdu_size_8K)
274 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; 280 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
275 281
@@ -283,7 +289,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
283 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 289 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
284 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); 290 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
285 291
286 if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { 292 if (num_ants == 1 ||
293 cfg->rx_with_siso_diversity) {
287 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | 294 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
288 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; 295 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
289 /* this works because NOT_SUPPORTED == 3 */ 296 /* this works because NOT_SUPPORTED == 3 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index 3325059c52d4..0c4399aba8c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index 976448a57d02..b5be51f3cd3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -155,14 +155,12 @@ void iwl_opmode_deregister(const char *name);
155 155
156/** 156/**
157 * struct iwl_op_mode - operational mode 157 * struct iwl_op_mode - operational mode
158 * @ops - pointer to its own ops
158 * 159 *
159 * This holds an implementation of the mac80211 / fw API. 160 * This holds an implementation of the mac80211 / fw API.
160 *
161 * @ops - pointer to its own ops
162 */ 161 */
163struct iwl_op_mode { 162struct iwl_op_mode {
164 const struct iwl_op_mode_ops *ops; 163 const struct iwl_op_mode_ops *ops;
165 const struct iwl_trans *trans;
166 164
167 char op_mode_specific[0] __aligned(sizeof(void *)); 165 char op_mode_specific[0] __aligned(sizeof(void *));
168}; 166};
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index 1a405ae6a9c5..fa77d63a277a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
index ce983af79644..9ee18d0d2d01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index a70c7b9d9bad..100bd0d79681 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -102,6 +102,9 @@
102/* Device system time */ 102/* Device system time */
103#define DEVICE_SYSTEM_TIME_REG 0xA0206C 103#define DEVICE_SYSTEM_TIME_REG 0xA0206C
104 104
105/* Device NMI register */
106#define DEVICE_SET_NMI_REG 0x00a01c30
107
105/***************************************************************************** 108/*****************************************************************************
106 * 7000/3000 series SHR DTS addresses * 109 * 7000/3000 series SHR DTS addresses *
107 *****************************************************************************/ 110 *****************************************************************************/
@@ -274,4 +277,8 @@ static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
274 277
275/*********************** END TX SCHEDULER *************************************/ 278/*********************** END TX SCHEDULER *************************************/
276 279
280/* Oscillator clock */
281#define OSC_CLK (0xa04068)
282#define OSC_CLK_FORCE_CONTROL (0x8)
283
277#endif /* __iwl_prph_h__ */ 284#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 143292b4dbbf..1f065cf4a4ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,7 @@
70#include "iwl-debug.h" 70#include "iwl-debug.h"
71#include "iwl-config.h" 71#include "iwl-config.h"
72#include "iwl-fw.h" 72#include "iwl-fw.h"
73#include "iwl-op-mode.h"
73 74
74/** 75/**
75 * DOC: Transport layer - what is it ? 76 * DOC: Transport layer - what is it ?
@@ -100,8 +101,7 @@
100 * start_fw 101 * start_fw
101 * 102 *
102 * 5) Then when finished (or reset): 103 * 5) Then when finished (or reset):
103 * stop_fw (a.k.a. stop device for the moment) 104 * stop_device
104 * stop_hw
105 * 105 *
106 * 6) Eventually, the free function will be called. 106 * 6) Eventually, the free function will be called.
107 */ 107 */
@@ -176,6 +176,16 @@ struct iwl_rx_packet {
176 u8 data[]; 176 u8 data[];
177} __packed; 177} __packed;
178 178
179static inline u32 iwl_rx_packet_len(const struct iwl_rx_packet *pkt)
180{
181 return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
182}
183
184static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
185{
186 return iwl_rx_packet_len(pkt) - sizeof(pkt->hdr);
187}
188
179/** 189/**
180 * enum CMD_MODE - how to send the host commands ? 190 * enum CMD_MODE - how to send the host commands ?
181 * 191 *
@@ -318,6 +328,24 @@ enum iwl_d3_status {
318}; 328};
319 329
320/** 330/**
331 * enum iwl_trans_status: transport status flags
332 * @STATUS_SYNC_HCMD_ACTIVE: a SYNC command is being processed
333 * @STATUS_DEVICE_ENABLED: APM is enabled
334 * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up)
335 * @STATUS_INT_ENABLED: interrupts are enabled
336 * @STATUS_RFKILL: the HW RFkill switch is in KILL position
337 * @STATUS_FW_ERROR: the fw is in error state
338 */
339enum iwl_trans_status {
340 STATUS_SYNC_HCMD_ACTIVE,
341 STATUS_DEVICE_ENABLED,
342 STATUS_TPOWER_PMI,
343 STATUS_INT_ENABLED,
344 STATUS_RFKILL,
345 STATUS_FW_ERROR,
346};
347
348/**
321 * struct iwl_trans_config - transport configuration 349 * struct iwl_trans_config - transport configuration
322 * 350 *
323 * @op_mode: pointer to the upper layer. 351 * @op_mode: pointer to the upper layer.
@@ -361,9 +389,7 @@ struct iwl_trans;
361 * 389 *
362 * @start_hw: starts the HW- from that point on, the HW can send interrupts 390 * @start_hw: starts the HW- from that point on, the HW can send interrupts
363 * May sleep 391 * May sleep
364 * @stop_hw: stops the HW- from that point on, the HW will be in low power but 392 * @op_mode_leave: Turn off the HW RF kill indication if on
365 * will still issue interrupt if the HW RF kill is triggered unless
366 * op_mode_leaving is true.
367 * May sleep 393 * May sleep
368 * @start_fw: allocates and inits all the resources for the transport 394 * @start_fw: allocates and inits all the resources for the transport
369 * layer. Also kick a fw image. 395 * layer. Also kick a fw image.
@@ -371,8 +397,11 @@ struct iwl_trans;
371 * @fw_alive: called when the fw sends alive notification. If the fw provides 397 * @fw_alive: called when the fw sends alive notification. If the fw provides
372 * the SCD base address in SRAM, then provide it here, or 0 otherwise. 398 * the SCD base address in SRAM, then provide it here, or 0 otherwise.
373 * May sleep 399 * May sleep
374 * @stop_device:stops the whole device (embedded CPU put to reset) 400 * @stop_device: stops the whole device (embedded CPU put to reset) and stops
375 * May sleep 401 * the HW. From that point on, the HW will be in low power but will still
402 * issue interrupt if the HW RF kill is triggered. This callback must do
403 * the right thing and not crash even if start_hw() was called but not
404 * start_fw(). May sleep
376 * @d3_suspend: put the device into the correct mode for WoWLAN during 405 * @d3_suspend: put the device into the correct mode for WoWLAN during
377 * suspend. This is optional, if not implemented WoWLAN will not be 406 * suspend. This is optional, if not implemented WoWLAN will not be
378 * supported. This callback may sleep. 407 * supported. This callback may sleep.
@@ -418,7 +447,7 @@ struct iwl_trans;
418struct iwl_trans_ops { 447struct iwl_trans_ops {
419 448
420 int (*start_hw)(struct iwl_trans *iwl_trans); 449 int (*start_hw)(struct iwl_trans *iwl_trans);
421 void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); 450 void (*op_mode_leave)(struct iwl_trans *iwl_trans);
422 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, 451 int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
423 bool run_in_rfkill); 452 bool run_in_rfkill);
424 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); 453 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
@@ -479,6 +508,7 @@ enum iwl_trans_state {
479 * @ops - pointer to iwl_trans_ops 508 * @ops - pointer to iwl_trans_ops
480 * @op_mode - pointer to the op_mode 509 * @op_mode - pointer to the op_mode
481 * @cfg - pointer to the configuration 510 * @cfg - pointer to the configuration
511 * @status: a bit-mask of transport status flags
482 * @dev - pointer to struct device * that represents the device 512 * @dev - pointer to struct device * that represents the device
483 * @hw_id: a u32 with the ID of the device / subdevice. 513 * @hw_id: a u32 with the ID of the device / subdevice.
484 * Set during transport allocation. 514 * Set during transport allocation.
@@ -499,6 +529,7 @@ struct iwl_trans {
499 struct iwl_op_mode *op_mode; 529 struct iwl_op_mode *op_mode;
500 const struct iwl_cfg *cfg; 530 const struct iwl_cfg *cfg;
501 enum iwl_trans_state state; 531 enum iwl_trans_state state;
532 unsigned long status;
502 533
503 struct device *dev; 534 struct device *dev;
504 u32 hw_rev; 535 u32 hw_rev;
@@ -540,15 +571,14 @@ static inline int iwl_trans_start_hw(struct iwl_trans *trans)
540 return trans->ops->start_hw(trans); 571 return trans->ops->start_hw(trans);
541} 572}
542 573
543static inline void iwl_trans_stop_hw(struct iwl_trans *trans, 574static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
544 bool op_mode_leaving)
545{ 575{
546 might_sleep(); 576 might_sleep();
547 577
548 trans->ops->stop_hw(trans, op_mode_leaving); 578 if (trans->ops->op_mode_leave)
579 trans->ops->op_mode_leave(trans);
549 580
550 if (op_mode_leaving) 581 trans->op_mode = NULL;
551 trans->op_mode = NULL;
552 582
553 trans->state = IWL_TRANS_NO_FW; 583 trans->state = IWL_TRANS_NO_FW;
554} 584}
@@ -570,6 +600,7 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
570 600
571 WARN_ON_ONCE(!trans->rx_mpdu_cmd); 601 WARN_ON_ONCE(!trans->rx_mpdu_cmd);
572 602
603 clear_bit(STATUS_FW_ERROR, &trans->status);
573 return trans->ops->start_fw(trans, fw, run_in_rfkill); 604 return trans->ops->start_fw(trans, fw, run_in_rfkill);
574} 605}
575 606
@@ -601,6 +632,13 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
601{ 632{
602 int ret; 633 int ret;
603 634
635 if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) &&
636 test_bit(STATUS_RFKILL, &trans->status)))
637 return -ERFKILL;
638
639 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
640 return -EIO;
641
604 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) { 642 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
605 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); 643 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
606 return -EIO; 644 return -EIO;
@@ -640,6 +678,9 @@ static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
640static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, 678static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
641 struct iwl_device_cmd *dev_cmd, int queue) 679 struct iwl_device_cmd *dev_cmd, int queue)
642{ 680{
681 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
682 return -EIO;
683
643 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) 684 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
644 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); 685 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
645 686
@@ -657,9 +698,6 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
657 698
658static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) 699static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
659{ 700{
660 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
661 IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
662
663 trans->ops->txq_disable(trans, queue); 701 trans->ops->txq_disable(trans, queue);
664} 702}
665 703
@@ -760,7 +798,8 @@ static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr,
760 798
761static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) 799static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
762{ 800{
763 trans->ops->set_pmi(trans, state); 801 if (trans->ops->set_pmi)
802 trans->ops->set_pmi(trans, state);
764} 803}
765 804
766static inline void 805static inline void
@@ -780,6 +819,16 @@ iwl_trans_release_nic_access(struct iwl_trans *trans, unsigned long *flags)
780 __release(nic_access); 819 __release(nic_access);
781} 820}
782 821
822static inline void iwl_trans_fw_error(struct iwl_trans *trans)
823{
824 if (WARN_ON_ONCE(!trans->op_mode))
825 return;
826
827 /* prevent double restarts due to the same erroneous FW */
828 if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status))
829 iwl_op_mode_nic_error(trans->op_mode);
830}
831
783/***************************************************** 832/*****************************************************
784* driver (transport) register/unregister functions 833* driver (transport) register/unregister functions
785******************************************************/ 834******************************************************/
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 6d73817850ce..f98ec2b23898 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -1,10 +1,10 @@
1obj-$(CONFIG_IWLMVM) += iwlmvm.o 1obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o power_legacy.o bt-coex.o 5iwlmvm-y += power.o power_legacy.o bt-coex.o
6iwlmvm-y += led.o tt.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
index 93fd1457954b..a1376539d2dc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/binding.c
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -183,15 +183,29 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) 183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
184 return -EINVAL; 184 return -EINVAL;
185 185
186 /*
187 * Update SF - Disable if needed. if this fails, SF might still be on
188 * while many macs are bound, which is forbidden - so fail the binding.
189 */
190 if (iwl_mvm_sf_update(mvm, vif, false))
191 return -EINVAL;
192
186 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true); 193 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
187} 194}
188 195
189int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 196int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
190{ 197{
191 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 198 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
199 int ret;
192 200
193 if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) 201 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
194 return -EINVAL; 202 return -EINVAL;
195 203
196 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false); 204 ret = iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
205
206 if (!ret)
207 if (iwl_mvm_sf_update(mvm, vif, true))
208 IWL_ERR(mvm, "Failed to update SF state\n");
209
210 return ret;
197} 211}
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 75b72a956552..76cde6ce6551 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -294,9 +294,9 @@ static const __le64 iwl_ci_mask[][3] = {
294 cpu_to_le64(0x0) 294 cpu_to_le64(0x0)
295 }, 295 },
296 { 296 {
297 cpu_to_le64(0xFE00000000ULL), 297 cpu_to_le64(0xFFC0000000ULL),
298 cpu_to_le64(0x0ULL), 298 cpu_to_le64(0x0ULL),
299 cpu_to_le64(0x0) 299 cpu_to_le64(0x0ULL)
300 }, 300 },
301}; 301};
302 302
@@ -396,7 +396,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
396 BT_VALID_ANT_ISOLATION | 396 BT_VALID_ANT_ISOLATION |
397 BT_VALID_ANT_ISOLATION_THRS | 397 BT_VALID_ANT_ISOLATION_THRS |
398 BT_VALID_TXTX_DELTA_FREQ_THRS | 398 BT_VALID_TXTX_DELTA_FREQ_THRS |
399 BT_VALID_TXRX_MAX_FREQ_0); 399 BT_VALID_TXRX_MAX_FREQ_0 |
400 BT_VALID_SYNC_TO_SCO);
400 401
401 if (mvm->cfg->bt_shared_single_ant) 402 if (mvm->cfg->bt_shared_single_ant)
402 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, 403 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
@@ -514,7 +515,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
514 if (IS_ERR_OR_NULL(sta)) 515 if (IS_ERR_OR_NULL(sta))
515 return 0; 516 return 0;
516 517
517 mvmsta = (void *)sta->drv_priv; 518 mvmsta = iwl_mvm_sta_from_mac80211(sta);
518 519
519 /* nothing to do */ 520 /* nothing to do */
520 if (mvmsta->bt_reduced_txpower == enable) 521 if (mvmsta->bt_reduced_txpower == enable)
@@ -846,7 +847,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
846 if (IS_ERR_OR_NULL(sta)) 847 if (IS_ERR_OR_NULL(sta))
847 return; 848 return;
848 849
849 mvmsta = (void *)sta->drv_priv; 850 mvmsta = iwl_mvm_sta_from_mac80211(sta);
850 851
851 data->num_bss_ifaces++; 852 data->num_bss_ifaces++;
852 853
@@ -917,11 +918,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
917u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, 918u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
918 struct ieee80211_sta *sta) 919 struct ieee80211_sta *sta)
919{ 920{
920 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 921 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
921 enum iwl_bt_coex_lut_type lut_type; 922 enum iwl_bt_coex_lut_type lut_type;
922 923
923 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 924 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
924 BT_LOW_TRAFFIC) 925 BT_HIGH_TRAFFIC)
925 return LINK_QUAL_AGG_TIME_LIMIT_DEF; 926 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
926 927
927 lut_type = iwl_get_coex_type(mvm, mvmsta->vif); 928 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
@@ -936,7 +937,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
936bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, 937bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
937 struct ieee80211_sta *sta) 938 struct ieee80211_sta *sta)
938{ 939{
939 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 940 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
940 941
941 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 942 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
942 BT_HIGH_TRAFFIC) 943 BT_HIGH_TRAFFIC)
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 4b6d670c3509..036857698565 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index b9b81e881dd0..f36a7ee0267f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -886,8 +886,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
886 if (err) 886 if (err)
887 return err; 887 return err;
888 888
889 size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 889 size = iwl_rx_packet_payload_len(cmd.resp_pkt);
890 size -= sizeof(cmd.resp_pkt->hdr);
891 if (size < sizeof(__le16)) { 890 if (size < sizeof(__le16)) {
892 err = -EINVAL; 891 err = -EINVAL;
893 } else { 892 } else {
@@ -1211,15 +1210,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1211 if (ret) 1210 if (ret)
1212 goto out; 1211 goto out;
1213#ifdef CONFIG_IWLWIFI_DEBUGFS 1212#ifdef CONFIG_IWLWIFI_DEBUGFS
1214 len = le32_to_cpu(d3_cfg_cmd.resp_pkt->len_n_flags) & 1213 len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
1215 FH_RSCSR_FRAME_SIZE_MSK; 1214 if (len >= sizeof(u32)) {
1216 if (len >= sizeof(u32) * 2) {
1217 mvm->d3_test_pme_ptr = 1215 mvm->d3_test_pme_ptr =
1218 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data); 1216 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
1219 } else if (test) {
1220 /* in test mode we require the pointer */
1221 ret = -EIO;
1222 goto out;
1223 } 1217 }
1224#endif 1218#endif
1225 iwl_free_resp(&d3_cfg_cmd); 1219 iwl_free_resp(&d3_cfg_cmd);
@@ -1231,10 +1225,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1231 mvm->aux_sta.sta_id = old_aux_sta_id; 1225 mvm->aux_sta.sta_id = old_aux_sta_id;
1232 mvm_ap_sta->sta_id = old_ap_sta_id; 1226 mvm_ap_sta->sta_id = old_ap_sta_id;
1233 mvmvif->ap_sta_id = old_ap_sta_id; 1227 mvmvif->ap_sta_id = old_ap_sta_id;
1234 out_noreset: 1228
1235 kfree(key_data.rsc_tsc);
1236 if (ret < 0) 1229 if (ret < 0)
1237 ieee80211_restart_hw(mvm->hw); 1230 ieee80211_restart_hw(mvm->hw);
1231 out_noreset:
1232 kfree(key_data.rsc_tsc);
1238 1233
1239 mutex_unlock(&mvm->mutex); 1234 mutex_unlock(&mvm->mutex);
1240 1235
@@ -1537,10 +1532,16 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
1537 struct iwl_mvm_d3_gtk_iter_data gtkdata = { 1532 struct iwl_mvm_d3_gtk_iter_data gtkdata = {
1538 .status = status, 1533 .status = status,
1539 }; 1534 };
1535 u32 disconnection_reasons =
1536 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1537 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
1540 1538
1541 if (!status || !vif->bss_conf.bssid) 1539 if (!status || !vif->bss_conf.bssid)
1542 return false; 1540 return false;
1543 1541
1542 if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
1543 return false;
1544
1544 /* find last GTK that we used initially, if any */ 1545 /* find last GTK that we used initially, if any */
1545 gtkdata.find_phase = true; 1546 gtkdata.find_phase = true;
1546 ieee80211_iter_keys(mvm->hw, vif, 1547 ieee80211_iter_keys(mvm->hw, vif,
@@ -1665,8 +1666,8 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1665 else 1666 else
1666 status_size = sizeof(struct iwl_wowlan_status_v4); 1667 status_size = sizeof(struct iwl_wowlan_status_v4);
1667 1668
1668 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 1669 len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1669 if (len - sizeof(struct iwl_cmd_header) < status_size) { 1670 if (len < status_size) {
1670 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1671 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1671 goto out_free_resp; 1672 goto out_free_resp;
1672 } 1673 }
@@ -1701,8 +1702,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1701 status.wake_packet = status_v4->wake_packet; 1702 status.wake_packet = status_v4->wake_packet;
1702 } 1703 }
1703 1704
1704 if (len - sizeof(struct iwl_cmd_header) != 1705 if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) {
1705 status_size + ALIGN(status.wake_packet_bufsize, 4)) {
1706 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1706 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1707 goto out_free_resp; 1707 goto out_free_resp;
1708 } 1708 }
@@ -1805,6 +1805,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1805 iwl_mvm_read_d3_sram(mvm); 1805 iwl_mvm_read_d3_sram(mvm);
1806 1806
1807 keep = iwl_mvm_query_wakeup_reasons(mvm, vif); 1807 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1808#ifdef CONFIG_IWLWIFI_DEBUGFS
1809 if (keep)
1810 mvm->keep_vif = vif;
1811#endif
1808 /* has unlocked the mutex, so skip that */ 1812 /* has unlocked the mutex, so skip that */
1809 goto out; 1813 goto out;
1810 1814
@@ -1861,6 +1865,7 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
1861 return err; 1865 return err;
1862 } 1866 }
1863 mvm->d3_test_active = true; 1867 mvm->d3_test_active = true;
1868 mvm->keep_vif = NULL;
1864 return 0; 1869 return 0;
1865} 1870}
1866 1871
@@ -1871,10 +1876,14 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1871 u32 pme_asserted; 1876 u32 pme_asserted;
1872 1877
1873 while (true) { 1878 while (true) {
1874 pme_asserted = iwl_trans_read_mem32(mvm->trans, 1879 /* read pme_ptr if available */
1875 mvm->d3_test_pme_ptr); 1880 if (mvm->d3_test_pme_ptr) {
1876 if (pme_asserted) 1881 pme_asserted = iwl_trans_read_mem32(mvm->trans,
1877 break; 1882 mvm->d3_test_pme_ptr);
1883 if (pme_asserted)
1884 break;
1885 }
1886
1878 if (msleep_interruptible(100)) 1887 if (msleep_interruptible(100))
1879 break; 1888 break;
1880 } 1889 }
@@ -1885,6 +1894,10 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1885static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac, 1894static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
1886 struct ieee80211_vif *vif) 1895 struct ieee80211_vif *vif)
1887{ 1896{
1897 /* skip the one we keep connection on */
1898 if (_data == vif)
1899 return;
1900
1888 if (vif->type == NL80211_IFTYPE_STATION) 1901 if (vif->type == NL80211_IFTYPE_STATION)
1889 ieee80211_connection_loss(vif); 1902 ieee80211_connection_loss(vif);
1890} 1903}
@@ -1911,7 +1924,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
1911 1924
1912 ieee80211_iterate_active_interfaces_atomic( 1925 ieee80211_iterate_active_interfaces_atomic(
1913 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 1926 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1914 iwl_mvm_d3_test_disconn_work_iter, NULL); 1927 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
1915 1928
1916 ieee80211_wake_queues(mvm->hw); 1929 ieee80211_wake_queues(mvm->hw);
1917 1930
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
new file mode 100644
index 000000000000..0e29cd83a06a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -0,0 +1,546 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "mvm.h"
64#include "debugfs.h"
65
66static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
67 struct ieee80211_vif *vif,
68 enum iwl_dbgfs_pm_mask param, int val)
69{
70 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
71 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
72
73 dbgfs_pm->mask |= param;
74
75 switch (param) {
76 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
77 struct ieee80211_hw *hw = mvm->hw;
78 int dtimper = hw->conf.ps_dtim_period ?: 1;
79 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
80
81 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
82 if (val * MSEC_PER_SEC < 3 * dtimper_msec)
83 IWL_WARN(mvm,
84 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
85 val * MSEC_PER_SEC, 3 * dtimper_msec);
86 dbgfs_pm->keep_alive_seconds = val;
87 break;
88 }
89 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
90 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
91 val ? "enabled" : "disabled");
92 dbgfs_pm->skip_over_dtim = val;
93 break;
94 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
95 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
96 dbgfs_pm->skip_dtim_periods = val;
97 break;
98 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
99 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
100 dbgfs_pm->rx_data_timeout = val;
101 break;
102 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
103 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
104 dbgfs_pm->tx_data_timeout = val;
105 break;
106 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
107 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
108 dbgfs_pm->disable_power_off = val;
109 break;
110 case MVM_DEBUGFS_PM_LPRX_ENA:
111 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
112 dbgfs_pm->lprx_ena = val;
113 break;
114 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
115 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
116 dbgfs_pm->lprx_rssi_threshold = val;
117 break;
118 case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
119 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
120 dbgfs_pm->snooze_ena = val;
121 break;
122 case MVM_DEBUGFS_PM_UAPSD_MISBEHAVING:
123 IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
124 dbgfs_pm->uapsd_misbehaving = val;
125 break;
126 }
127}
128
129static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
130 size_t count, loff_t *ppos)
131{
132 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
133 struct iwl_mvm *mvm = mvmvif->mvm;
134 enum iwl_dbgfs_pm_mask param;
135 int val, ret;
136
137 if (!strncmp("keep_alive=", buf, 11)) {
138 if (sscanf(buf + 11, "%d", &val) != 1)
139 return -EINVAL;
140 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
141 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
142 if (sscanf(buf + 15, "%d", &val) != 1)
143 return -EINVAL;
144 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
145 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
146 if (sscanf(buf + 18, "%d", &val) != 1)
147 return -EINVAL;
148 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
149 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
150 if (sscanf(buf + 16, "%d", &val) != 1)
151 return -EINVAL;
152 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
153 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
154 if (sscanf(buf + 16, "%d", &val) != 1)
155 return -EINVAL;
156 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
157 } else if (!strncmp("disable_power_off=", buf, 18) &&
158 !(mvm->fw->ucode_capa.flags &
159 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
160 if (sscanf(buf + 18, "%d", &val) != 1)
161 return -EINVAL;
162 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
163 } else if (!strncmp("lprx=", buf, 5)) {
164 if (sscanf(buf + 5, "%d", &val) != 1)
165 return -EINVAL;
166 param = MVM_DEBUGFS_PM_LPRX_ENA;
167 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
168 if (sscanf(buf + 20, "%d", &val) != 1)
169 return -EINVAL;
170 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
171 POWER_LPRX_RSSI_THRESHOLD_MIN)
172 return -EINVAL;
173 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
174 } else if (!strncmp("snooze_enable=", buf, 14)) {
175 if (sscanf(buf + 14, "%d", &val) != 1)
176 return -EINVAL;
177 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
178 } else if (!strncmp("uapsd_misbehaving=", buf, 18)) {
179 if (sscanf(buf + 18, "%d", &val) != 1)
180 return -EINVAL;
181 param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
182 } else {
183 return -EINVAL;
184 }
185
186 mutex_lock(&mvm->mutex);
187 iwl_dbgfs_update_pm(mvm, vif, param, val);
188 ret = iwl_mvm_power_update_mode(mvm, vif);
189 mutex_unlock(&mvm->mutex);
190
191 return ret ?: count;
192}
193
194static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
195 char __user *user_buf,
196 size_t count, loff_t *ppos)
197{
198 struct ieee80211_vif *vif = file->private_data;
199 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
200 struct iwl_mvm *mvm = mvmvif->mvm;
201 char buf[512];
202 int bufsz = sizeof(buf);
203 int pos;
204
205 pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);
206
207 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
208}
209
210static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
211 char __user *user_buf,
212 size_t count, loff_t *ppos)
213{
214 struct ieee80211_vif *vif = file->private_data;
215 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
216 struct iwl_mvm *mvm = mvmvif->mvm;
217 u8 ap_sta_id;
218 struct ieee80211_chanctx_conf *chanctx_conf;
219 char buf[512];
220 int bufsz = sizeof(buf);
221 int pos = 0;
222 int i;
223
224 mutex_lock(&mvm->mutex);
225
226 ap_sta_id = mvmvif->ap_sta_id;
227
228 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
229 mvmvif->id, mvmvif->color);
230 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
231 vif->bss_conf.bssid);
232 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
233 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
234 pos += scnprintf(buf+pos, bufsz-pos,
235 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
236 i, mvmvif->queue_params[i].txop,
237 mvmvif->queue_params[i].cw_min,
238 mvmvif->queue_params[i].cw_max,
239 mvmvif->queue_params[i].aifs,
240 mvmvif->queue_params[i].uapsd);
241
242 if (vif->type == NL80211_IFTYPE_STATION &&
243 ap_sta_id != IWL_MVM_STATION_COUNT) {
244 struct ieee80211_sta *sta;
245
246 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
247 lockdep_is_held(&mvm->mutex));
248 if (!IS_ERR_OR_NULL(sta)) {
249 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
250
251 pos += scnprintf(buf+pos, bufsz-pos,
252 "ap_sta_id %d - reduced Tx power %d\n",
253 ap_sta_id,
254 mvm_sta->bt_reduced_txpower);
255 }
256 }
257
258 rcu_read_lock();
259 chanctx_conf = rcu_dereference(vif->chanctx_conf);
260 if (chanctx_conf)
261 pos += scnprintf(buf+pos, bufsz-pos,
262 "idle rx chains %d, active rx chains: %d\n",
263 chanctx_conf->rx_chains_static,
264 chanctx_conf->rx_chains_dynamic);
265 rcu_read_unlock();
266
267 mutex_unlock(&mvm->mutex);
268
269 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
270}
271
272static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
273 enum iwl_dbgfs_bf_mask param, int value)
274{
275 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
276 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
277
278 dbgfs_bf->mask |= param;
279
280 switch (param) {
281 case MVM_DEBUGFS_BF_ENERGY_DELTA:
282 dbgfs_bf->bf_energy_delta = value;
283 break;
284 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
285 dbgfs_bf->bf_roaming_energy_delta = value;
286 break;
287 case MVM_DEBUGFS_BF_ROAMING_STATE:
288 dbgfs_bf->bf_roaming_state = value;
289 break;
290 case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
291 dbgfs_bf->bf_temp_threshold = value;
292 break;
293 case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
294 dbgfs_bf->bf_temp_fast_filter = value;
295 break;
296 case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
297 dbgfs_bf->bf_temp_slow_filter = value;
298 break;
299 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
300 dbgfs_bf->bf_enable_beacon_filter = value;
301 break;
302 case MVM_DEBUGFS_BF_DEBUG_FLAG:
303 dbgfs_bf->bf_debug_flag = value;
304 break;
305 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
306 dbgfs_bf->bf_escape_timer = value;
307 break;
308 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
309 dbgfs_bf->ba_enable_beacon_abort = value;
310 break;
311 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
312 dbgfs_bf->ba_escape_timer = value;
313 break;
314 }
315}
316
317static ssize_t iwl_dbgfs_bf_params_write(struct ieee80211_vif *vif, char *buf,
318 size_t count, loff_t *ppos)
319{
320 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
321 struct iwl_mvm *mvm = mvmvif->mvm;
322 enum iwl_dbgfs_bf_mask param;
323 int value, ret = 0;
324
325 if (!strncmp("bf_energy_delta=", buf, 16)) {
326 if (sscanf(buf+16, "%d", &value) != 1)
327 return -EINVAL;
328 if (value < IWL_BF_ENERGY_DELTA_MIN ||
329 value > IWL_BF_ENERGY_DELTA_MAX)
330 return -EINVAL;
331 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
332 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
333 if (sscanf(buf+24, "%d", &value) != 1)
334 return -EINVAL;
335 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
336 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
337 return -EINVAL;
338 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
339 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
340 if (sscanf(buf+17, "%d", &value) != 1)
341 return -EINVAL;
342 if (value < IWL_BF_ROAMING_STATE_MIN ||
343 value > IWL_BF_ROAMING_STATE_MAX)
344 return -EINVAL;
345 param = MVM_DEBUGFS_BF_ROAMING_STATE;
346 } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
347 if (sscanf(buf+18, "%d", &value) != 1)
348 return -EINVAL;
349 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
350 value > IWL_BF_TEMP_THRESHOLD_MAX)
351 return -EINVAL;
352 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
353 } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
354 if (sscanf(buf+20, "%d", &value) != 1)
355 return -EINVAL;
356 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
357 value > IWL_BF_TEMP_FAST_FILTER_MAX)
358 return -EINVAL;
359 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
360 } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
361 if (sscanf(buf+20, "%d", &value) != 1)
362 return -EINVAL;
363 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
364 value > IWL_BF_TEMP_SLOW_FILTER_MAX)
365 return -EINVAL;
366 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
367 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
368 if (sscanf(buf+24, "%d", &value) != 1)
369 return -EINVAL;
370 if (value < 0 || value > 1)
371 return -EINVAL;
372 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
373 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
374 if (sscanf(buf+14, "%d", &value) != 1)
375 return -EINVAL;
376 if (value < 0 || value > 1)
377 return -EINVAL;
378 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
379 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
380 if (sscanf(buf+16, "%d", &value) != 1)
381 return -EINVAL;
382 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
383 value > IWL_BF_ESCAPE_TIMER_MAX)
384 return -EINVAL;
385 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
386 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
387 if (sscanf(buf+16, "%d", &value) != 1)
388 return -EINVAL;
389 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
390 value > IWL_BA_ESCAPE_TIMER_MAX)
391 return -EINVAL;
392 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
393 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
394 if (sscanf(buf+23, "%d", &value) != 1)
395 return -EINVAL;
396 if (value < 0 || value > 1)
397 return -EINVAL;
398 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
399 } else {
400 return -EINVAL;
401 }
402
403 mutex_lock(&mvm->mutex);
404 iwl_dbgfs_update_bf(vif, param, value);
405 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value)
406 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
407 else
408 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
409 mutex_unlock(&mvm->mutex);
410
411 return ret ?: count;
412}
413
414static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
415 char __user *user_buf,
416 size_t count, loff_t *ppos)
417{
418 struct ieee80211_vif *vif = file->private_data;
419 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
420 char buf[256];
421 int pos = 0;
422 const size_t bufsz = sizeof(buf);
423 struct iwl_beacon_filter_cmd cmd = {
424 IWL_BF_CMD_CONFIG_DEFAULTS,
425 .bf_enable_beacon_filter =
426 cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
427 .ba_enable_beacon_abort =
428 cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
429 };
430
431 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
432 if (mvmvif->bf_data.bf_enabled)
433 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
434 else
435 cmd.bf_enable_beacon_filter = 0;
436
437 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
438 le32_to_cpu(cmd.bf_energy_delta));
439 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
440 le32_to_cpu(cmd.bf_roaming_energy_delta));
441 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
442 le32_to_cpu(cmd.bf_roaming_state));
443 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
444 le32_to_cpu(cmd.bf_temp_threshold));
445 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
446 le32_to_cpu(cmd.bf_temp_fast_filter));
447 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
448 le32_to_cpu(cmd.bf_temp_slow_filter));
449 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
450 le32_to_cpu(cmd.bf_enable_beacon_filter));
451 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
452 le32_to_cpu(cmd.bf_debug_flag));
453 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
454 le32_to_cpu(cmd.bf_escape_timer));
455 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
456 le32_to_cpu(cmd.ba_escape_timer));
457 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
458 le32_to_cpu(cmd.ba_enable_beacon_abort));
459
460 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
461}
462
463#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
464 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
465#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
466 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
467#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
468 if (!debugfs_create_file(#name, mode, parent, vif, \
469 &iwl_dbgfs_##name##_ops)) \
470 goto err; \
471 } while (0)
472
473MVM_DEBUGFS_READ_FILE_OPS(mac_params);
474MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
475MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
476
477void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
478{
479 struct dentry *dbgfs_dir = vif->debugfs_dir;
480 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
481 char buf[100];
482
483 /*
484 * Check if debugfs directory already exist before creating it.
485 * This may happen when, for example, resetting hw or suspend-resume
486 */
487 if (!dbgfs_dir || mvmvif->dbgfs_dir)
488 return;
489
490 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
491 mvmvif->mvm = mvm;
492
493 if (!mvmvif->dbgfs_dir) {
494 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
495 dbgfs_dir->d_name.name);
496 return;
497 }
498
499 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
500 ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
501 (vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
502 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)))
503 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
504 S_IRUSR);
505
506 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
507 S_IRUSR);
508
509 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
510 mvmvif == mvm->bf_allowed_vif)
511 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
512 S_IRUSR | S_IWUSR);
513
514 /*
515 * Create symlink for convenience pointing to interface specific
516 * debugfs entries for the driver. For example, under
517 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
518 * find
519 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
520 */
521 snprintf(buf, 100, "../../../%s/%s/%s/%s",
522 dbgfs_dir->d_parent->d_parent->d_name.name,
523 dbgfs_dir->d_parent->d_name.name,
524 dbgfs_dir->d_name.name,
525 mvmvif->dbgfs_dir->d_name.name);
526
527 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
528 mvm->debugfs_dir, buf);
529 if (!mvmvif->dbgfs_slink)
530 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
531 dbgfs_dir->d_name.name);
532 return;
533err:
534 IWL_ERR(mvm, "Can't create debugfs entity\n");
535}
536
537void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
538{
539 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
540
541 debugfs_remove(mvmvif->dbgfs_slink);
542 mvmvif->dbgfs_slink = NULL;
543
544 debugfs_remove_recursive(mvmvif->dbgfs_dir);
545 mvmvif->dbgfs_dir = NULL;
546}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index a8fe6b41f9a3..369d4c90e669 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -63,30 +63,18 @@
63#include "mvm.h" 63#include "mvm.h"
64#include "sta.h" 64#include "sta.h"
65#include "iwl-io.h" 65#include "iwl-io.h"
66#include "iwl-prph.h"
67#include "debugfs.h"
66 68
67struct iwl_dbgfs_mvm_ctx { 69static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
68 struct iwl_mvm *mvm;
69 struct ieee80211_vif *vif;
70};
71
72static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
73 const char __user *user_buf,
74 size_t count, loff_t *ppos) 70 size_t count, loff_t *ppos)
75{ 71{
76 struct iwl_mvm *mvm = file->private_data; 72 int ret;
77
78 char buf[16];
79 int buf_size, ret;
80 u32 scd_q_msk; 73 u32 scd_q_msk;
81 74
82 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 75 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
83 return -EIO; 76 return -EIO;
84 77
85 memset(buf, 0, sizeof(buf));
86 buf_size = min(count, sizeof(buf) - 1);
87 if (copy_from_user(buf, user_buf, buf_size))
88 return -EFAULT;
89
90 if (sscanf(buf, "%x", &scd_q_msk) != 1) 78 if (sscanf(buf, "%x", &scd_q_msk) != 1)
91 return -EINVAL; 79 return -EINVAL;
92 80
@@ -99,24 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
99 return ret; 87 return ret;
100} 88}
101 89
102static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, 90static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
103 const char __user *user_buf,
104 size_t count, loff_t *ppos) 91 size_t count, loff_t *ppos)
105{ 92{
106 struct iwl_mvm *mvm = file->private_data;
107 struct ieee80211_sta *sta; 93 struct ieee80211_sta *sta;
108 94 int sta_id, drain, ret;
109 char buf[8];
110 int buf_size, sta_id, drain, ret;
111 95
112 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 96 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
113 return -EIO; 97 return -EIO;
114 98
115 memset(buf, 0, sizeof(buf));
116 buf_size = min(count, sizeof(buf) - 1);
117 if (copy_from_user(buf, user_buf, buf_size))
118 return -EFAULT;
119
120 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) 99 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
121 return -EINVAL; 100 return -EINVAL;
122 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) 101 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
@@ -144,73 +123,57 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
144{ 123{
145 struct iwl_mvm *mvm = file->private_data; 124 struct iwl_mvm *mvm = file->private_data;
146 const struct fw_img *img; 125 const struct fw_img *img;
147 int ofs, len, pos = 0; 126 unsigned int ofs, len;
148 size_t bufsz, ret; 127 size_t ret;
149 char *buf;
150 u8 *ptr; 128 u8 *ptr;
151 129
152 if (!mvm->ucode_loaded) 130 if (!mvm->ucode_loaded)
153 return -EINVAL; 131 return -EINVAL;
154 132
155 /* default is to dump the entire data segment */ 133 /* default is to dump the entire data segment */
156 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { 134 img = &mvm->fw->img[mvm->cur_ucode];
157 img = &mvm->fw->img[mvm->cur_ucode]; 135 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
158 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 136 len = img->sec[IWL_UCODE_SECTION_DATA].len;
159 len = img->sec[IWL_UCODE_SECTION_DATA].len; 137
160 } else { 138 if (mvm->dbgfs_sram_len) {
161 ofs = mvm->dbgfs_sram_offset; 139 ofs = mvm->dbgfs_sram_offset;
162 len = mvm->dbgfs_sram_len; 140 len = mvm->dbgfs_sram_len;
163 } 141 }
164 142
165 bufsz = len * 4 + 256;
166 buf = kzalloc(bufsz, GFP_KERNEL);
167 if (!buf)
168 return -ENOMEM;
169
170 ptr = kzalloc(len, GFP_KERNEL); 143 ptr = kzalloc(len, GFP_KERNEL);
171 if (!ptr) { 144 if (!ptr)
172 kfree(buf);
173 return -ENOMEM; 145 return -ENOMEM;
174 }
175
176 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
177 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
178 146
179 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); 147 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
180 for (ofs = 0; ofs < len; ofs += 16) {
181 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
182 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
183 bufsz - pos, false);
184 pos += strlen(buf + pos);
185 if (bufsz - pos > 0)
186 buf[pos++] = '\n';
187 }
188 148
189 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 149 ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len);
190 150
191 kfree(buf);
192 kfree(ptr); 151 kfree(ptr);
193 152
194 return ret; 153 return ret;
195} 154}
196 155
197static ssize_t iwl_dbgfs_sram_write(struct file *file, 156static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
198 const char __user *user_buf, size_t count, 157 size_t count, loff_t *ppos)
199 loff_t *ppos)
200{ 158{
201 struct iwl_mvm *mvm = file->private_data; 159 const struct fw_img *img;
202 char buf[64];
203 int buf_size;
204 u32 offset, len; 160 u32 offset, len;
161 u32 img_offset, img_len;
162
163 if (!mvm->ucode_loaded)
164 return -EINVAL;
205 165
206 memset(buf, 0, sizeof(buf)); 166 img = &mvm->fw->img[mvm->cur_ucode];
207 buf_size = min(count, sizeof(buf) - 1); 167 img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset;
208 if (copy_from_user(buf, user_buf, buf_size)) 168 img_len = img->sec[IWL_UCODE_SECTION_DATA].len;
209 return -EFAULT;
210 169
211 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 170 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
212 if ((offset & 0x3) || (len & 0x3)) 171 if ((offset & 0x3) || (len & 0x3))
213 return -EINVAL; 172 return -EINVAL;
173
174 if (offset + len > img_offset + img_len)
175 return -EINVAL;
176
214 mvm->dbgfs_sram_offset = offset; 177 mvm->dbgfs_sram_offset = offset;
215 mvm->dbgfs_sram_len = len; 178 mvm->dbgfs_sram_len = len;
216 } else { 179 } else {
@@ -267,22 +230,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
267 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 230 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
268} 231}
269 232
270static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, 233static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
271 const char __user *user_buf,
272 size_t count, loff_t *ppos) 234 size_t count, loff_t *ppos)
273{ 235{
274 struct iwl_mvm *mvm = file->private_data; 236 int ret, val;
275 char buf[64] = {};
276 int ret;
277 int val;
278 237
279 if (!mvm->ucode_loaded) 238 if (!mvm->ucode_loaded)
280 return -EIO; 239 return -EIO;
281 240
282 count = min_t(size_t, count, sizeof(buf) - 1);
283 if (copy_from_user(buf, user_buf, count))
284 return -EFAULT;
285
286 if (!strncmp("disable_power_off_d0=", buf, 21)) { 241 if (!strncmp("disable_power_off_d0=", buf, 21)) {
287 if (sscanf(buf + 21, "%d", &val) != 1) 242 if (sscanf(buf + 21, "%d", &val) != 1)
288 return -EINVAL; 243 return -EINVAL;
@@ -302,212 +257,6 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
302 return ret ?: count; 257 return ret ?: count;
303} 258}
304 259
305static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
306 struct ieee80211_vif *vif,
307 enum iwl_dbgfs_pm_mask param, int val)
308{
309 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
310 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
311
312 dbgfs_pm->mask |= param;
313
314 switch (param) {
315 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
316 struct ieee80211_hw *hw = mvm->hw;
317 int dtimper = hw->conf.ps_dtim_period ?: 1;
318 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
319
320 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
321 if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
322 IWL_WARN(mvm,
323 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
324 val * MSEC_PER_SEC, 3 * dtimper_msec);
325 }
326 dbgfs_pm->keep_alive_seconds = val;
327 break;
328 }
329 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
330 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
331 val ? "enabled" : "disabled");
332 dbgfs_pm->skip_over_dtim = val;
333 break;
334 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
335 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
336 dbgfs_pm->skip_dtim_periods = val;
337 break;
338 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
339 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
340 dbgfs_pm->rx_data_timeout = val;
341 break;
342 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
343 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
344 dbgfs_pm->tx_data_timeout = val;
345 break;
346 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
347 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
348 dbgfs_pm->disable_power_off = val;
349 break;
350 case MVM_DEBUGFS_PM_LPRX_ENA:
351 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
352 dbgfs_pm->lprx_ena = val;
353 break;
354 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
355 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
356 dbgfs_pm->lprx_rssi_threshold = val;
357 break;
358 case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
359 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
360 dbgfs_pm->snooze_ena = val;
361 break;
362 }
363}
364
365static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
366 const char __user *user_buf,
367 size_t count, loff_t *ppos)
368{
369 struct ieee80211_vif *vif = file->private_data;
370 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
371 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
372 enum iwl_dbgfs_pm_mask param;
373 char buf[32] = {};
374 int val;
375 int ret;
376
377 count = min_t(size_t, count, sizeof(buf) - 1);
378 if (copy_from_user(buf, user_buf, count))
379 return -EFAULT;
380
381 if (!strncmp("keep_alive=", buf, 11)) {
382 if (sscanf(buf + 11, "%d", &val) != 1)
383 return -EINVAL;
384 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
385 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
386 if (sscanf(buf + 15, "%d", &val) != 1)
387 return -EINVAL;
388 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
389 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
390 if (sscanf(buf + 18, "%d", &val) != 1)
391 return -EINVAL;
392 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
393 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
394 if (sscanf(buf + 16, "%d", &val) != 1)
395 return -EINVAL;
396 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
397 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
398 if (sscanf(buf + 16, "%d", &val) != 1)
399 return -EINVAL;
400 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
401 } else if (!strncmp("disable_power_off=", buf, 18) &&
402 !(mvm->fw->ucode_capa.flags &
403 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
404 if (sscanf(buf + 18, "%d", &val) != 1)
405 return -EINVAL;
406 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
407 } else if (!strncmp("lprx=", buf, 5)) {
408 if (sscanf(buf + 5, "%d", &val) != 1)
409 return -EINVAL;
410 param = MVM_DEBUGFS_PM_LPRX_ENA;
411 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
412 if (sscanf(buf + 20, "%d", &val) != 1)
413 return -EINVAL;
414 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
415 POWER_LPRX_RSSI_THRESHOLD_MIN)
416 return -EINVAL;
417 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
418 } else if (!strncmp("snooze_enable=", buf, 14)) {
419 if (sscanf(buf + 14, "%d", &val) != 1)
420 return -EINVAL;
421 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
422 } else {
423 return -EINVAL;
424 }
425
426 mutex_lock(&mvm->mutex);
427 iwl_dbgfs_update_pm(mvm, vif, param, val);
428 ret = iwl_mvm_power_update_mode(mvm, vif);
429 mutex_unlock(&mvm->mutex);
430
431 return ret ?: count;
432}
433
434static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
435 char __user *user_buf,
436 size_t count, loff_t *ppos)
437{
438 struct ieee80211_vif *vif = file->private_data;
439 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
440 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
441 char buf[512];
442 int bufsz = sizeof(buf);
443 int pos;
444
445 pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);
446
447 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
448}
449
450static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
451 char __user *user_buf,
452 size_t count, loff_t *ppos)
453{
454 struct ieee80211_vif *vif = file->private_data;
455 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
456 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
457 u8 ap_sta_id;
458 struct ieee80211_chanctx_conf *chanctx_conf;
459 char buf[512];
460 int bufsz = sizeof(buf);
461 int pos = 0;
462 int i;
463
464 mutex_lock(&mvm->mutex);
465
466 ap_sta_id = mvmvif->ap_sta_id;
467
468 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
469 mvmvif->id, mvmvif->color);
470 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
471 vif->bss_conf.bssid);
472 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
473 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
474 pos += scnprintf(buf+pos, bufsz-pos,
475 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
476 i, mvmvif->queue_params[i].txop,
477 mvmvif->queue_params[i].cw_min,
478 mvmvif->queue_params[i].cw_max,
479 mvmvif->queue_params[i].aifs,
480 mvmvif->queue_params[i].uapsd);
481 }
482
483 if (vif->type == NL80211_IFTYPE_STATION &&
484 ap_sta_id != IWL_MVM_STATION_COUNT) {
485 struct ieee80211_sta *sta;
486 struct iwl_mvm_sta *mvm_sta;
487
488 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
489 lockdep_is_held(&mvm->mutex));
490 mvm_sta = (void *)sta->drv_priv;
491 pos += scnprintf(buf+pos, bufsz-pos,
492 "ap_sta_id %d - reduced Tx power %d\n",
493 ap_sta_id, mvm_sta->bt_reduced_txpower);
494 }
495
496 rcu_read_lock();
497 chanctx_conf = rcu_dereference(vif->chanctx_conf);
498 if (chanctx_conf) {
499 pos += scnprintf(buf+pos, bufsz-pos,
500 "idle rx chains %d, active rx chains: %d\n",
501 chanctx_conf->rx_chains_static,
502 chanctx_conf->rx_chains_dynamic);
503 }
504 rcu_read_unlock();
505
506 mutex_unlock(&mvm->mutex);
507
508 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
509}
510
511#define BT_MBOX_MSG(_notif, _num, _field) \ 260#define BT_MBOX_MSG(_notif, _num, _field) \
512 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ 261 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
513 >> BT_MBOX##_num##_##_field##_POS) 262 >> BT_MBOX##_num##_##_field##_POS)
@@ -783,11 +532,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
783} 532}
784#undef PRINT_STAT_LE32 533#undef PRINT_STAT_LE32
785 534
786static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 535static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
787 const char __user *user_buf,
788 size_t count, loff_t *ppos) 536 size_t count, loff_t *ppos)
789{ 537{
790 struct iwl_mvm *mvm = file->private_data;
791 int ret; 538 int ret;
792 539
793 mutex_lock(&mvm->mutex); 540 mutex_lock(&mvm->mutex);
@@ -804,6 +551,14 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
804 return count; 551 return count;
805} 552}
806 553
554static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
555 size_t count, loff_t *ppos)
556{
557 iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
558
559 return count;
560}
561
807static ssize_t 562static ssize_t
808iwl_dbgfs_scan_ant_rxchain_read(struct file *file, 563iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
809 char __user *user_buf, 564 char __user *user_buf,
@@ -828,21 +583,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
828} 583}
829 584
830static ssize_t 585static ssize_t
831iwl_dbgfs_scan_ant_rxchain_write(struct file *file, 586iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
832 const char __user *user_buf,
833 size_t count, loff_t *ppos) 587 size_t count, loff_t *ppos)
834{ 588{
835 struct iwl_mvm *mvm = file->private_data;
836 char buf[8];
837 int buf_size;
838 u8 scan_rx_ant; 589 u8 scan_rx_ant;
839 590
840 memset(buf, 0, sizeof(buf));
841 buf_size = min(count, sizeof(buf) - 1);
842
843 /* get the argument from the user and check if it is valid */
844 if (copy_from_user(buf, user_buf, buf_size))
845 return -EFAULT;
846 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) 591 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
847 return -EINVAL; 592 return -EINVAL;
848 if (scan_rx_ant > ANT_ABC) 593 if (scan_rx_ant > ANT_ABC)
@@ -850,228 +595,17 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
850 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw)) 595 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
851 return -EINVAL; 596 return -EINVAL;
852 597
853 /* change the rx antennas for scan command */
854 mvm->scan_rx_ant = scan_rx_ant; 598 mvm->scan_rx_ant = scan_rx_ant;
855 599
856 return count; 600 return count;
857} 601}
858 602
859
860static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
861 enum iwl_dbgfs_bf_mask param, int value)
862{
863 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
864 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
865
866 dbgfs_bf->mask |= param;
867
868 switch (param) {
869 case MVM_DEBUGFS_BF_ENERGY_DELTA:
870 dbgfs_bf->bf_energy_delta = value;
871 break;
872 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
873 dbgfs_bf->bf_roaming_energy_delta = value;
874 break;
875 case MVM_DEBUGFS_BF_ROAMING_STATE:
876 dbgfs_bf->bf_roaming_state = value;
877 break;
878 case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
879 dbgfs_bf->bf_temp_threshold = value;
880 break;
881 case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
882 dbgfs_bf->bf_temp_fast_filter = value;
883 break;
884 case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
885 dbgfs_bf->bf_temp_slow_filter = value;
886 break;
887 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
888 dbgfs_bf->bf_enable_beacon_filter = value;
889 break;
890 case MVM_DEBUGFS_BF_DEBUG_FLAG:
891 dbgfs_bf->bf_debug_flag = value;
892 break;
893 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
894 dbgfs_bf->bf_escape_timer = value;
895 break;
896 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
897 dbgfs_bf->ba_enable_beacon_abort = value;
898 break;
899 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
900 dbgfs_bf->ba_escape_timer = value;
901 break;
902 }
903}
904
905static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
906 const char __user *user_buf,
907 size_t count, loff_t *ppos)
908{
909 struct ieee80211_vif *vif = file->private_data;
910 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
911 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
912 enum iwl_dbgfs_bf_mask param;
913 char buf[256];
914 int buf_size;
915 int value;
916 int ret = 0;
917
918 memset(buf, 0, sizeof(buf));
919 buf_size = min(count, sizeof(buf) - 1);
920 if (copy_from_user(buf, user_buf, buf_size))
921 return -EFAULT;
922
923 if (!strncmp("bf_energy_delta=", buf, 16)) {
924 if (sscanf(buf+16, "%d", &value) != 1)
925 return -EINVAL;
926 if (value < IWL_BF_ENERGY_DELTA_MIN ||
927 value > IWL_BF_ENERGY_DELTA_MAX)
928 return -EINVAL;
929 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
930 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
931 if (sscanf(buf+24, "%d", &value) != 1)
932 return -EINVAL;
933 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
934 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
935 return -EINVAL;
936 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
937 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
938 if (sscanf(buf+17, "%d", &value) != 1)
939 return -EINVAL;
940 if (value < IWL_BF_ROAMING_STATE_MIN ||
941 value > IWL_BF_ROAMING_STATE_MAX)
942 return -EINVAL;
943 param = MVM_DEBUGFS_BF_ROAMING_STATE;
944 } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
945 if (sscanf(buf+18, "%d", &value) != 1)
946 return -EINVAL;
947 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
948 value > IWL_BF_TEMP_THRESHOLD_MAX)
949 return -EINVAL;
950 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
951 } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
952 if (sscanf(buf+20, "%d", &value) != 1)
953 return -EINVAL;
954 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
955 value > IWL_BF_TEMP_FAST_FILTER_MAX)
956 return -EINVAL;
957 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
958 } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
959 if (sscanf(buf+20, "%d", &value) != 1)
960 return -EINVAL;
961 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
962 value > IWL_BF_TEMP_SLOW_FILTER_MAX)
963 return -EINVAL;
964 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
965 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
966 if (sscanf(buf+24, "%d", &value) != 1)
967 return -EINVAL;
968 if (value < 0 || value > 1)
969 return -EINVAL;
970 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
971 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
972 if (sscanf(buf+14, "%d", &value) != 1)
973 return -EINVAL;
974 if (value < 0 || value > 1)
975 return -EINVAL;
976 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
977 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
978 if (sscanf(buf+16, "%d", &value) != 1)
979 return -EINVAL;
980 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
981 value > IWL_BF_ESCAPE_TIMER_MAX)
982 return -EINVAL;
983 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
984 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
985 if (sscanf(buf+16, "%d", &value) != 1)
986 return -EINVAL;
987 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
988 value > IWL_BA_ESCAPE_TIMER_MAX)
989 return -EINVAL;
990 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
991 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
992 if (sscanf(buf+23, "%d", &value) != 1)
993 return -EINVAL;
994 if (value < 0 || value > 1)
995 return -EINVAL;
996 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
997 } else {
998 return -EINVAL;
999 }
1000
1001 mutex_lock(&mvm->mutex);
1002 iwl_dbgfs_update_bf(vif, param, value);
1003 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
1004 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
1005 } else {
1006 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
1007 }
1008 mutex_unlock(&mvm->mutex);
1009
1010 return ret ?: count;
1011}
1012
1013static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
1014 char __user *user_buf,
1015 size_t count, loff_t *ppos)
1016{
1017 struct ieee80211_vif *vif = file->private_data;
1018 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1019 char buf[256];
1020 int pos = 0;
1021 const size_t bufsz = sizeof(buf);
1022 struct iwl_beacon_filter_cmd cmd = {
1023 IWL_BF_CMD_CONFIG_DEFAULTS,
1024 .bf_enable_beacon_filter =
1025 cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
1026 .ba_enable_beacon_abort =
1027 cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
1028 };
1029
1030 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
1031 if (mvmvif->bf_data.bf_enabled)
1032 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
1033 else
1034 cmd.bf_enable_beacon_filter = 0;
1035
1036 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
1037 le32_to_cpu(cmd.bf_energy_delta));
1038 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
1039 le32_to_cpu(cmd.bf_roaming_energy_delta));
1040 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
1041 le32_to_cpu(cmd.bf_roaming_state));
1042 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
1043 le32_to_cpu(cmd.bf_temp_threshold));
1044 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
1045 le32_to_cpu(cmd.bf_temp_fast_filter));
1046 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
1047 le32_to_cpu(cmd.bf_temp_slow_filter));
1048 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
1049 le32_to_cpu(cmd.bf_enable_beacon_filter));
1050 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
1051 le32_to_cpu(cmd.bf_debug_flag));
1052 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
1053 le32_to_cpu(cmd.bf_escape_timer));
1054 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
1055 le32_to_cpu(cmd.ba_escape_timer));
1056 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
1057 le32_to_cpu(cmd.ba_enable_beacon_abort));
1058
1059 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1060}
1061
1062#ifdef CONFIG_PM_SLEEP 603#ifdef CONFIG_PM_SLEEP
1063static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, 604static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
1064 const char __user *user_buf,
1065 size_t count, loff_t *ppos) 605 size_t count, loff_t *ppos)
1066{ 606{
1067 struct iwl_mvm *mvm = file->private_data;
1068 char buf[8] = {};
1069 int store; 607 int store;
1070 608
1071 count = min_t(size_t, count, sizeof(buf) - 1);
1072 if (copy_from_user(buf, user_buf, count))
1073 return -EFAULT;
1074
1075 if (sscanf(buf, "%d", &store) != 1) 609 if (sscanf(buf, "%d", &store) != 1)
1076 return -EINVAL; 610 return -EINVAL;
1077 611
@@ -1124,61 +658,33 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
1124} 658}
1125#endif 659#endif
1126 660
1127#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 661#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1128static const struct file_operations iwl_dbgfs_##name##_ops = { \ 662 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1129 .read = iwl_dbgfs_##name##_read, \ 663#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1130 .open = simple_open, \ 664 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1131 .llseek = generic_file_llseek, \
1132}
1133
1134#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \
1135static const struct file_operations iwl_dbgfs_##name##_ops = { \
1136 .write = iwl_dbgfs_##name##_write, \
1137 .read = iwl_dbgfs_##name##_read, \
1138 .open = simple_open, \
1139 .llseek = generic_file_llseek, \
1140};
1141
1142#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
1143static const struct file_operations iwl_dbgfs_##name##_ops = { \
1144 .write = iwl_dbgfs_##name##_write, \
1145 .open = simple_open, \
1146 .llseek = generic_file_llseek, \
1147};
1148
1149#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \ 665#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
1150 if (!debugfs_create_file(#name, mode, parent, mvm, \ 666 if (!debugfs_create_file(#name, mode, parent, mvm, \
1151 &iwl_dbgfs_##name##_ops)) \ 667 &iwl_dbgfs_##name##_ops)) \
1152 goto err; \ 668 goto err; \
1153 } while (0) 669 } while (0)
1154 670
1155#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
1156 if (!debugfs_create_file(#name, mode, parent, vif, \
1157 &iwl_dbgfs_##name##_ops)) \
1158 goto err; \
1159 } while (0)
1160
1161/* Device wide debugfs entries */ 671/* Device wide debugfs entries */
1162MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); 672MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1163MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 673MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1164MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 674MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1165MVM_DEBUGFS_READ_FILE_OPS(stations); 675MVM_DEBUGFS_READ_FILE_OPS(stations);
1166MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 676MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1167MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 677MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1168MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); 678MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1169MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 679MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1170MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 680MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1171MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); 681MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
682MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1172 683
1173#ifdef CONFIG_PM_SLEEP 684#ifdef CONFIG_PM_SLEEP
1174MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); 685MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
1175#endif 686#endif
1176 687
1177/* Interface specific debugfs entries */
1178MVM_DEBUGFS_READ_FILE_OPS(mac_params);
1179MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
1180MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
1181
1182int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 688int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1183{ 689{
1184 char buf[100]; 690 char buf[100];
@@ -1196,6 +702,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1196 S_IRUSR | S_IWUSR); 702 S_IRUSR | S_IWUSR);
1197 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); 703 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
1198 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 704 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
705 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
1199 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 706 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1200 S_IWUSR | S_IRUSR); 707 S_IWUSR | S_IRUSR);
1201#ifdef CONFIG_PM_SLEEP 708#ifdef CONFIG_PM_SLEEP
@@ -1206,6 +713,19 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1206 goto err; 713 goto err;
1207#endif 714#endif
1208 715
716 if (!debugfs_create_blob("nvm_hw", S_IRUSR,
717 mvm->debugfs_dir, &mvm->nvm_hw_blob))
718 goto err;
719 if (!debugfs_create_blob("nvm_sw", S_IRUSR,
720 mvm->debugfs_dir, &mvm->nvm_sw_blob))
721 goto err;
722 if (!debugfs_create_blob("nvm_calib", S_IRUSR,
723 mvm->debugfs_dir, &mvm->nvm_calib_blob))
724 goto err;
725 if (!debugfs_create_blob("nvm_prod", S_IRUSR,
726 mvm->debugfs_dir, &mvm->nvm_prod_blob))
727 goto err;
728
1209 /* 729 /*
1210 * Create a symlink with mac80211. It will be removed when mac80211 730 * Create a symlink with mac80211. It will be removed when mac80211
1211 * exists (before the opmode exists which removes the target.) 731 * exists (before the opmode exists which removes the target.)
@@ -1221,72 +741,3 @@ err:
1221 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); 741 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
1222 return -ENOMEM; 742 return -ENOMEM;
1223} 743}
1224
1225void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1226{
1227 struct dentry *dbgfs_dir = vif->debugfs_dir;
1228 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1229 char buf[100];
1230
1231 /*
1232 * Check if debugfs directory already exist before creating it.
1233 * This may happen when, for example, resetting hw or suspend-resume
1234 */
1235 if (!dbgfs_dir || mvmvif->dbgfs_dir)
1236 return;
1237
1238 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
1239 mvmvif->dbgfs_data = mvm;
1240
1241 if (!mvmvif->dbgfs_dir) {
1242 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
1243 dbgfs_dir->d_name.name);
1244 return;
1245 }
1246
1247 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
1248 vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
1249 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
1250 S_IRUSR);
1251
1252 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
1253 S_IRUSR);
1254
1255 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
1256 mvmvif == mvm->bf_allowed_vif)
1257 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
1258 S_IRUSR | S_IWUSR);
1259
1260 /*
1261 * Create symlink for convenience pointing to interface specific
1262 * debugfs entries for the driver. For example, under
1263 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
1264 * find
1265 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
1266 */
1267 snprintf(buf, 100, "../../../%s/%s/%s/%s",
1268 dbgfs_dir->d_parent->d_parent->d_name.name,
1269 dbgfs_dir->d_parent->d_name.name,
1270 dbgfs_dir->d_name.name,
1271 mvmvif->dbgfs_dir->d_name.name);
1272
1273 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
1274 mvm->debugfs_dir, buf);
1275 if (!mvmvif->dbgfs_slink)
1276 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
1277 dbgfs_dir->d_name.name);
1278 return;
1279err:
1280 IWL_ERR(mvm, "Can't create debugfs entity\n");
1281}
1282
1283void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1284{
1285 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1286
1287 debugfs_remove(mvmvif->dbgfs_slink);
1288 mvmvif->dbgfs_slink = NULL;
1289
1290 debugfs_remove_recursive(mvmvif->dbgfs_dir);
1291 mvmvif->dbgfs_dir = NULL;
1292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
new file mode 100644
index 000000000000..e3a9774af495
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#define MVM_DEBUGFS_READ_FILE_OPS(name) \
65static const struct file_operations iwl_dbgfs_##name##_ops = { \
66 .read = iwl_dbgfs_##name##_read, \
67 .open = simple_open, \
68 .llseek = generic_file_llseek, \
69}
70
71#define MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
72static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
73 const char __user *user_buf, \
74 size_t count, loff_t *ppos) \
75{ \
76 argtype *arg = file->private_data; \
77 char buf[buflen] = {}; \
78 size_t buf_size = min(count, sizeof(buf) - 1); \
79 \
80 if (copy_from_user(buf, user_buf, buf_size)) \
81 return -EFAULT; \
82 \
83 return iwl_dbgfs_##name##_write(arg, buf, buf_size, ppos); \
84} \
85
86#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype) \
87MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
88static const struct file_operations iwl_dbgfs_##name##_ops = { \
89 .write = _iwl_dbgfs_##name##_write, \
90 .read = iwl_dbgfs_##name##_read, \
91 .open = simple_open, \
92 .llseek = generic_file_llseek, \
93};
94
95#define _MVM_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype) \
96MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
97static const struct file_operations iwl_dbgfs_##name##_ops = { \
98 .write = _iwl_dbgfs_##name##_write, \
99 .open = simple_open, \
100 .llseek = generic_file_llseek, \
101};
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
index 4ea5e24ca92d..1b4e54d416b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -127,6 +127,7 @@ enum iwl_bt_coex_valid_bit_msk {
127 BT_VALID_ANT_ISOLATION_THRS = BIT(15), 127 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
128 BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), 128 BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
129 BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), 129 BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
130 BT_VALID_SYNC_TO_SCO = BIT(18),
130}; 131};
131 132
132/** 133/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 4e7dd8cf87dc..8415ff312d0e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index 39c3148bdfa8..c405cda1025f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 5cb93ae5cd2f..884c08725308 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -85,6 +85,8 @@
85 * PBW Snoozing enabled 85 * PBW Snoozing enabled
86 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask 86 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
87 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. 87 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
88 * @POWER_FLAGS_AP_UAPSD_MISBEHAVING_ENA_MSK: AP/GO's uAPSD misbehaving
89 * detection enablement
88*/ 90*/
89enum iwl_power_flags { 91enum iwl_power_flags {
90 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), 92 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
@@ -94,6 +96,7 @@ enum iwl_power_flags {
94 POWER_FLAGS_BT_SCO_ENA = BIT(8), 96 POWER_FLAGS_BT_SCO_ENA = BIT(8),
95 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), 97 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9),
96 POWER_FLAGS_LPRX_ENA_MSK = BIT(11), 98 POWER_FLAGS_LPRX_ENA_MSK = BIT(11),
99 POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK = BIT(12),
97}; 100};
98 101
99#define IWL_POWER_VEC_SIZE 5 102#define IWL_POWER_VEC_SIZE 5
@@ -228,6 +231,19 @@ struct iwl_mac_power_cmd {
228 u8 reserved; 231 u8 reserved;
229} __packed; 232} __packed;
230 233
234/*
235 * struct iwl_uapsd_misbehaving_ap_notif - FW sends this notification when
236 * associated AP is identified as improperly implementing uAPSD protocol.
237 * PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78
238 * @sta_id: index of station in uCode's station table - associated AP ID in
239 * this context.
240 */
241struct iwl_uapsd_misbehaving_ap_notif {
242 __le32 sta_id;
243 u8 mac_id;
244 u8 reserved[3];
245} __packed;
246
231/** 247/**
232 * struct iwl_beacon_filter_cmd 248 * struct iwl_beacon_filter_cmd
233 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) 249 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 538f1c7a5966..85057219cc43 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -281,8 +281,31 @@ enum {
281/* # entries in rate scale table to support Tx retries */ 281/* # entries in rate scale table to support Tx retries */
282#define LQ_MAX_RETRY_NUM 16 282#define LQ_MAX_RETRY_NUM 16
283 283
284/* Link quality command flags, only this one is available */ 284/* Link quality command flags bit fields */
285#define LQ_FLAG_SET_STA_TLC_RTS_MSK BIT(0) 285
286/* Bit 0: (0) Don't use RTS (1) Use RTS */
287#define LQ_FLAG_USE_RTS_POS 0
288#define LQ_FLAG_USE_RTS_MSK (1 << LQ_FLAG_USE_RTS_POS)
289
290/* Bit 1-3: LQ command color. Used to match responses to LQ commands */
291#define LQ_FLAG_COLOR_POS 1
292#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS)
293
294/* Bit 4-5: Tx RTS BW Signalling
295 * (0) No RTS BW signalling
296 * (1) Static BW signalling
297 * (2) Dynamic BW signalling
298 */
299#define LQ_FLAG_RTS_BW_SIG_POS 4
300#define LQ_FLAG_RTS_BW_SIG_NONE (0 << LQ_FLAG_RTS_BW_SIG_POS)
301#define LQ_FLAG_RTS_BW_SIG_STATIC (1 << LQ_FLAG_RTS_BW_SIG_POS)
302#define LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << LQ_FLAG_RTS_BW_SIG_POS)
303
304/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection
305 * Dyanmic BW selection allows Tx with narrower BW then requested in rates
306 */
307#define LQ_FLAG_DYNAMIC_BW_POS 6
308#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)
286 309
287/** 310/**
288 * struct iwl_lq_cmd - link quality command 311 * struct iwl_lq_cmd - link quality command
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index c3782b48ded1..73cbba7424f2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -530,14 +530,13 @@ struct iwl_scan_offload_schedule {
530/* 530/*
531 * iwl_scan_offload_flags 531 * iwl_scan_offload_flags
532 * 532 *
533 * IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match 533 * IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering.
534 * ssid list.
535 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan. 534 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
536 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan 535 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
537 * on A band. 536 * on A band.
538 */ 537 */
539enum iwl_scan_offload_flags { 538enum iwl_scan_offload_flags {
540 IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID = BIT(0), 539 IWL_SCAN_OFFLOAD_FLAG_PASS_ALL = BIT(0),
541 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2), 540 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
542 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3), 541 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3),
543}; 542};
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 4aca5933a65d..1b60fdff6a56 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -97,9 +97,6 @@ enum iwl_sta_flags {
97 STA_FLG_FLG_ANT_B), 97 STA_FLG_FLG_ANT_B),
98 98
99 STA_FLG_PS = BIT(8), 99 STA_FLG_PS = BIT(8),
100 STA_FLG_INVALID = BIT(9),
101 STA_FLG_DLP_EN = BIT(10),
102 STA_FLG_SET_ALL_KEYS = BIT(11),
103 STA_FLG_DRAIN_FLOW = BIT(12), 100 STA_FLG_DRAIN_FLOW = BIT(12),
104 STA_FLG_PAN = BIT(13), 101 STA_FLG_PAN = BIT(13),
105 STA_FLG_CLASS_AUTH = BIT(14), 102 STA_FLG_CLASS_AUTH = BIT(14),
@@ -138,7 +135,14 @@ enum iwl_sta_flags {
138 135
139/** 136/**
140 * enum iwl_sta_key_flag - key flags for the ADD_STA host command 137 * enum iwl_sta_key_flag - key flags for the ADD_STA host command
141 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithm 138 * @STA_KEY_FLG_NO_ENC: no encryption
139 * @STA_KEY_FLG_WEP: WEP encryption algorithm
140 * @STA_KEY_FLG_CCM: CCMP encryption algorithm
141 * @STA_KEY_FLG_TKIP: TKIP encryption algorithm
142 * @STA_KEY_FLG_EXT: extended cipher algorithm (depends on the FW support)
143 * @STA_KEY_FLG_CMAC: CMAC encryption algorithm
144 * @STA_KEY_FLG_ENC_UNKNOWN: unknown encryption algorithm
145 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithmi value
142 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from 146 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from
143 * station info array (1 - n 1X mode) 147 * station info array (1 - n 1X mode)
144 * @STA_KEY_FLG_KEYID_MSK: the index of the key 148 * @STA_KEY_FLG_KEYID_MSK: the index of the key
@@ -152,6 +156,7 @@ enum iwl_sta_key_flag {
152 STA_KEY_FLG_WEP = (1 << 0), 156 STA_KEY_FLG_WEP = (1 << 0),
153 STA_KEY_FLG_CCM = (2 << 0), 157 STA_KEY_FLG_CCM = (2 << 0),
154 STA_KEY_FLG_TKIP = (3 << 0), 158 STA_KEY_FLG_TKIP = (3 << 0),
159 STA_KEY_FLG_EXT = (4 << 0),
155 STA_KEY_FLG_CMAC = (6 << 0), 160 STA_KEY_FLG_CMAC = (6 << 0),
156 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0), 161 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0),
157 STA_KEY_FLG_EN_MSK = (7 << 0), 162 STA_KEY_FLG_EN_MSK = (7 << 0),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index d606197bde8f..b674c2a2b51c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -132,6 +132,7 @@ enum iwl_tx_flags {
132#define TX_CMD_SEC_WEP 0x01 132#define TX_CMD_SEC_WEP 0x01
133#define TX_CMD_SEC_CCM 0x02 133#define TX_CMD_SEC_CCM 0x02
134#define TX_CMD_SEC_TKIP 0x03 134#define TX_CMD_SEC_TKIP 0x03
135#define TX_CMD_SEC_EXT 0x04
135#define TX_CMD_SEC_MSK 0x07 136#define TX_CMD_SEC_MSK 0x07
136#define TX_CMD_SEC_WEP_KEY_IDX_POS 6 137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
137#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0 138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index bad5a552dd8d..989d7dbdca6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -141,6 +141,7 @@ enum {
141 141
142 /* Power - legacy power table command */ 142 /* Power - legacy power table command */
143 POWER_TABLE_CMD = 0x77, 143 POWER_TABLE_CMD = 0x77,
144 PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
144 145
145 /* Thermal Throttling*/ 146 /* Thermal Throttling*/
146 REPLY_THERMAL_MNG_BACKOFF = 0x7e, 147 REPLY_THERMAL_MNG_BACKOFF = 0x7e,
@@ -183,6 +184,7 @@ enum {
183 BT_PROFILE_NOTIFICATION = 0xce, 184 BT_PROFILE_NOTIFICATION = 0xce,
184 BT_COEX_CI = 0x5d, 185 BT_COEX_CI = 0x5d,
185 186
187 REPLY_SF_CFG_CMD = 0xd1,
186 REPLY_BEACON_FILTERING_CMD = 0xd2, 188 REPLY_BEACON_FILTERING_CMD = 0xd2,
187 189
188 REPLY_DEBUG_CMD = 0xf0, 190 REPLY_DEBUG_CMD = 0xf0,
@@ -1052,6 +1054,7 @@ enum iwl_mvm_rx_status {
1052 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8), 1054 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8),
1053 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8), 1055 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8),
1054 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8), 1056 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8),
1057 RX_MPDU_RES_STATUS_SEC_EXT_ENC = (4 << 8),
1055 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8), 1058 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8),
1056 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8), 1059 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
1057 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8), 1060 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
@@ -1131,6 +1134,7 @@ struct iwl_set_calib_default_cmd {
1131} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ 1134} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
1132 1135
1133#define MAX_PORT_ID_NUM 2 1136#define MAX_PORT_ID_NUM 2
1137#define MAX_MCAST_FILTERING_ADDRESSES 256
1134 1138
1135/** 1139/**
1136 * struct iwl_mcast_filter_cmd - configure multicast filter. 1140 * struct iwl_mcast_filter_cmd - configure multicast filter.
@@ -1363,4 +1367,65 @@ struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1363 struct mvm_statistics_general general; 1367 struct mvm_statistics_general general;
1364} __packed; 1368} __packed;
1365 1369
1370/***********************************
1371 * Smart Fifo API
1372 ***********************************/
1373/* Smart Fifo state */
1374enum iwl_sf_state {
1375 SF_LONG_DELAY_ON = 0, /* should never be called by driver */
1376 SF_FULL_ON,
1377 SF_UNINIT,
1378 SF_INIT_OFF,
1379 SF_HW_NUM_STATES
1380};
1381
1382/* Smart Fifo possible scenario */
1383enum iwl_sf_scenario {
1384 SF_SCENARIO_SINGLE_UNICAST,
1385 SF_SCENARIO_AGG_UNICAST,
1386 SF_SCENARIO_MULTICAST,
1387 SF_SCENARIO_BA_RESP,
1388 SF_SCENARIO_TX_RESP,
1389 SF_NUM_SCENARIO
1390};
1391
1392#define SF_TRANSIENT_STATES_NUMBER 2 /* SF_LONG_DELAY_ON and SF_FULL_ON */
1393#define SF_NUM_TIMEOUT_TYPES 2 /* Aging timer and Idle timer */
1394
1395/* smart FIFO default values */
1396#define SF_W_MARK_SISO 4096
1397#define SF_W_MARK_MIMO2 8192
1398#define SF_W_MARK_MIMO3 6144
1399#define SF_W_MARK_LEGACY 4096
1400#define SF_W_MARK_SCAN 4096
1401
1402/* SF Scenarios timers for FULL_ON state (aligned to 32 uSec) */
1403#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1404#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1405#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1406#define SF_AGG_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1407#define SF_MCAST_IDLE_TIMER 2016 /* 2 mSec */
1408#define SF_MCAST_AGING_TIMER 10016 /* 10 mSec */
1409#define SF_BA_IDLE_TIMER 320 /* 300 uSec */
1410#define SF_BA_AGING_TIMER 2016 /* 2 mSec */
1411#define SF_TX_RE_IDLE_TIMER 320 /* 300 uSec */
1412#define SF_TX_RE_AGING_TIMER 2016 /* 2 mSec */
1413
1414#define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */
1415
1416/**
1417 * Smart Fifo configuration command.
1418 * @state: smart fifo state, types listed in iwl_sf_sate.
1419 * @watermark: Minimum allowed availabe free space in RXF for transient state.
1420 * @long_delay_timeouts: aging and idle timer values for each scenario
1421 * in long delay state.
1422 * @full_on_timeouts: timer values for each scenario in full on state.
1423 */
1424struct iwl_sf_cfg_cmd {
1425 enum iwl_sf_state state;
1426 __le32 watermark[SF_TRANSIENT_STATES_NUMBER];
1427 __le32 long_delay_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1428 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1429} __packed; /* SF_CFG_API_S_VER_2 */
1430
1366#endif /* __fw_api_h__ */ 1431#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 70e5297646b2..c03d39541f9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -241,7 +241,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
241 241
242 lockdep_assert_held(&mvm->mutex); 242 lockdep_assert_held(&mvm->mutex);
243 243
244 if (mvm->init_ucode_complete) 244 if (WARN_ON_ONCE(mvm->init_ucode_complete))
245 return 0; 245 return 0;
246 246
247 iwl_init_notification_wait(&mvm->notif_wait, 247 iwl_init_notification_wait(&mvm->notif_wait,
@@ -287,7 +287,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
287 IWL_DEBUG_RF_KILL(mvm, 287 IWL_DEBUG_RF_KILL(mvm,
288 "jump over all phy activities due to RF kill\n"); 288 "jump over all phy activities due to RF kill\n");
289 iwl_remove_notification(&mvm->notif_wait, &calib_wait); 289 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
290 return 1; 290 ret = 1;
291 goto out;
291 } 292 }
292 293
293 /* Send TX valid antennas before triggering calibrations */ 294 /* Send TX valid antennas before triggering calibrations */
@@ -319,9 +320,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
319error: 320error:
320 iwl_remove_notification(&mvm->notif_wait, &calib_wait); 321 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
321out: 322out:
322 if (!iwlmvm_mod_params.init_dbg) { 323 if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
323 iwl_trans_stop_device(mvm->trans);
324 } else if (!mvm->nvm_data) {
325 /* we want to debug INIT and we have no NVM - fake */ 324 /* we want to debug INIT and we have no NVM - fake */
326 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) + 325 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
327 sizeof(struct ieee80211_channel) + 326 sizeof(struct ieee80211_channel) +
@@ -370,11 +369,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
370 ret = -ERFKILL; 369 ret = -ERFKILL;
371 goto error; 370 goto error;
372 } 371 }
373 /* should stop & start HW since that INIT image just loaded */ 372 if (!iwlmvm_mod_params.init_dbg) {
374 iwl_trans_stop_hw(mvm->trans, false); 373 /*
375 ret = iwl_trans_start_hw(mvm->trans); 374 * should stop and start HW since that INIT
376 if (ret) 375 * image just loaded
377 return ret; 376 */
377 iwl_trans_stop_device(mvm->trans);
378 ret = iwl_trans_start_hw(mvm->trans);
379 if (ret)
380 return ret;
381 }
378 } 382 }
379 383
380 if (iwlmvm_mod_params.init_dbg) 384 if (iwlmvm_mod_params.init_dbg)
@@ -386,6 +390,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
386 goto error; 390 goto error;
387 } 391 }
388 392
393 ret = iwl_mvm_sf_update(mvm, NULL, false);
394 if (ret)
395 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
396
389 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 397 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
390 if (ret) 398 if (ret)
391 goto error; 399 goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 2269a9e5cc67..6b4ea6bf8ffe 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -103,7 +103,7 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
103 return 0; 103 return 0;
104 default: 104 default:
105 return -EINVAL; 105 return -EINVAL;
106 }; 106 }
107 107
108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led", 108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
109 wiphy_name(mvm->hw->wiphy)); 109 wiphy_name(mvm->hw->wiphy));
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index f41f9b079831..ba723d50939a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -69,10 +69,10 @@
69#include "mvm.h" 69#include "mvm.h"
70 70
71const u8 iwl_mvm_ac_to_tx_fifo[] = { 71const u8 iwl_mvm_ac_to_tx_fifo[] = {
72 IWL_MVM_TX_FIFO_BK,
73 IWL_MVM_TX_FIFO_BE,
74 IWL_MVM_TX_FIFO_VI,
75 IWL_MVM_TX_FIFO_VO, 72 IWL_MVM_TX_FIFO_VO,
73 IWL_MVM_TX_FIFO_VI,
74 IWL_MVM_TX_FIFO_BE,
75 IWL_MVM_TX_FIFO_BK,
76}; 76};
77 77
78struct iwl_mvm_mac_iface_iterator_data { 78struct iwl_mvm_mac_iface_iterator_data {
@@ -85,35 +85,15 @@ struct iwl_mvm_mac_iface_iterator_data {
85 bool found_vif; 85 bool found_vif;
86}; 86};
87 87
88static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, 88static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
89 struct ieee80211_vif *vif) 89 struct ieee80211_vif *vif)
90{ 90{
91 struct iwl_mvm_mac_iface_iterator_data *data = _data; 91 struct iwl_mvm_mac_iface_iterator_data *data = _data;
92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
93 u32 ac;
94 93
95 /* Iterator may already find the interface being added -- skip it */ 94 /* Skip the interface for which we are trying to assign a tsf_id */
96 if (vif == data->vif) { 95 if (vif == data->vif)
97 data->found_vif = true;
98 return; 96 return;
99 }
100
101 /* Mark the queues used by the vif */
102 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
103 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
104 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
105
106 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
107 __set_bit(vif->cab_queue, data->used_hw_queues);
108
109 /*
110 * Mark MAC IDs as used by clearing the available bit, and
111 * (below) mark TSFs as used if their existing use is not
112 * compatible with the new interface type.
113 * No locking or atomic bit operations are needed since the
114 * data is on the stack of the caller function.
115 */
116 __clear_bit(mvmvif->id, data->available_mac_ids);
117 97
118 /* 98 /*
119 * The TSF is a hardware/firmware resource, there are 4 and 99 * The TSF is a hardware/firmware resource, there are 4 and
@@ -135,21 +115,26 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
135 case NL80211_IFTYPE_STATION: 115 case NL80211_IFTYPE_STATION:
136 /* 116 /*
137 * The new interface is client, so if the existing one 117 * The new interface is client, so if the existing one
138 * we're iterating is an AP, the TSF should be used to 118 * we're iterating is an AP, and both interfaces have the
119 * same beacon interval, the same TSF should be used to
139 * avoid drift between the new client and existing AP, 120 * avoid drift between the new client and existing AP,
140 * the existing AP will get drift updates from the new 121 * the existing AP will get drift updates from the new
141 * client context in this case 122 * client context in this case
142 */ 123 */
143 if (vif->type == NL80211_IFTYPE_AP) { 124 if (vif->type == NL80211_IFTYPE_AP) {
144 if (data->preferred_tsf == NUM_TSF_IDS && 125 if (data->preferred_tsf == NUM_TSF_IDS &&
145 test_bit(mvmvif->tsf_id, data->available_tsf_ids)) 126 test_bit(mvmvif->tsf_id, data->available_tsf_ids) &&
127 (vif->bss_conf.beacon_int ==
128 data->vif->bss_conf.beacon_int)) {
146 data->preferred_tsf = mvmvif->tsf_id; 129 data->preferred_tsf = mvmvif->tsf_id;
147 return; 130 return;
131 }
148 } 132 }
149 break; 133 break;
150 case NL80211_IFTYPE_AP: 134 case NL80211_IFTYPE_AP:
151 /* 135 /*
152 * The new interface is AP/GO, so should get drift 136 * The new interface is AP/GO, so in case both interfaces
137 * have the same beacon interval, it should get drift
153 * updates from an existing client or use the same 138 * updates from an existing client or use the same
154 * TSF as an existing GO. There's no drift between 139 * TSF as an existing GO. There's no drift between
155 * TSFs internally but if they used different TSFs 140 * TSFs internally but if they used different TSFs
@@ -159,9 +144,12 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
159 if (vif->type == NL80211_IFTYPE_STATION || 144 if (vif->type == NL80211_IFTYPE_STATION ||
160 vif->type == NL80211_IFTYPE_AP) { 145 vif->type == NL80211_IFTYPE_AP) {
161 if (data->preferred_tsf == NUM_TSF_IDS && 146 if (data->preferred_tsf == NUM_TSF_IDS &&
162 test_bit(mvmvif->tsf_id, data->available_tsf_ids)) 147 test_bit(mvmvif->tsf_id, data->available_tsf_ids) &&
148 (vif->bss_conf.beacon_int ==
149 data->vif->bss_conf.beacon_int)) {
163 data->preferred_tsf = mvmvif->tsf_id; 150 data->preferred_tsf = mvmvif->tsf_id;
164 return; 151 return;
152 }
165 } 153 }
166 break; 154 break;
167 default: 155 default:
@@ -187,6 +175,39 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
187 data->preferred_tsf = NUM_TSF_IDS; 175 data->preferred_tsf = NUM_TSF_IDS;
188} 176}
189 177
178static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
179 struct ieee80211_vif *vif)
180{
181 struct iwl_mvm_mac_iface_iterator_data *data = _data;
182 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
183 u32 ac;
184
185 /* Iterator may already find the interface being added -- skip it */
186 if (vif == data->vif) {
187 data->found_vif = true;
188 return;
189 }
190
191 /* Mark the queues used by the vif */
192 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
193 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
194 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
195
196 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
197 __set_bit(vif->cab_queue, data->used_hw_queues);
198
199 /* Mark MAC IDs as used by clearing the available bit, and
200 * (below) mark TSFs as used if their existing use is not
201 * compatible with the new interface type.
202 * No locking or atomic bit operations are needed since the
203 * data is on the stack of the caller function.
204 */
205 __clear_bit(mvmvif->id, data->available_mac_ids);
206
207 /* find a suitable tsf_id */
208 iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
209}
210
190/* 211/*
191 * Get the mask of the queus used by the vif 212 * Get the mask of the queus used by the vif
192 */ 213 */
@@ -205,6 +226,29 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
205 return qmask; 226 return qmask;
206} 227}
207 228
229void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
230 struct ieee80211_vif *vif)
231{
232 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
233 struct iwl_mvm_mac_iface_iterator_data data = {
234 .mvm = mvm,
235 .vif = vif,
236 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
237 /* no preference yet */
238 .preferred_tsf = NUM_TSF_IDS,
239 };
240
241 ieee80211_iterate_active_interfaces_atomic(
242 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
243 iwl_mvm_mac_tsf_id_iter, &data);
244
245 if (data.preferred_tsf != NUM_TSF_IDS)
246 mvmvif->tsf_id = data.preferred_tsf;
247 else if (!test_bit(mvmvif->tsf_id, data.available_tsf_ids))
248 mvmvif->tsf_id = find_first_bit(data.available_tsf_ids,
249 NUM_TSF_IDS);
250}
251
208static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, 252static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
209 struct ieee80211_vif *vif) 253 struct ieee80211_vif *vif)
210{ 254{
@@ -488,6 +532,40 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
488 *ofdm_rates = ofdm; 532 *ofdm_rates = ofdm;
489} 533}
490 534
535static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
536 struct ieee80211_vif *vif,
537 struct iwl_mac_ctx_cmd *cmd)
538{
539 /* for both sta and ap, ht_operation_mode hold the protection_mode */
540 u8 protection_mode = vif->bss_conf.ht_operation_mode &
541 IEEE80211_HT_OP_MODE_PROTECTION;
542 /* The fw does not distinguish between ht and fat */
543 u32 ht_flag = MAC_PROT_FLG_HT_PROT | MAC_PROT_FLG_FAT_PROT;
544
545 IWL_DEBUG_RATE(mvm, "protection mode set to %d\n", protection_mode);
546 /*
547 * See section 9.23.3.1 of IEEE 80211-2012.
548 * Nongreenfield HT STAs Present is not supported.
549 */
550 switch (protection_mode) {
551 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
552 break;
553 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
554 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
555 cmd->protection_flags |= cpu_to_le32(ht_flag);
556 break;
557 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
558 /* Protect when channel wider than 20MHz */
559 if (vif->bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
560 cmd->protection_flags |= cpu_to_le32(ht_flag);
561 break;
562 default:
563 IWL_ERR(mvm, "Illegal protection mode %d\n",
564 protection_mode);
565 break;
566 }
567}
568
491static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, 569static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
492 struct ieee80211_vif *vif, 570 struct ieee80211_vif *vif,
493 struct iwl_mac_ctx_cmd *cmd, 571 struct iwl_mac_ctx_cmd *cmd,
@@ -495,6 +573,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
495{ 573{
496 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 574 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
497 struct ieee80211_chanctx_conf *chanctx; 575 struct ieee80211_chanctx_conf *chanctx;
576 bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
577 IEEE80211_HT_OP_MODE_PROTECTION);
498 u8 cck_ack_rates, ofdm_ack_rates; 578 u8 cck_ack_rates, ofdm_ack_rates;
499 int i; 579 int i;
500 580
@@ -550,18 +630,23 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
550 cpu_to_le32(vif->bss_conf.use_short_slot ? 630 cpu_to_le32(vif->bss_conf.use_short_slot ?
551 MAC_FLG_SHORT_SLOT : 0); 631 MAC_FLG_SHORT_SLOT : 0);
552 632
553 for (i = 0; i < AC_NUM; i++) { 633 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
554 cmd->ac[i].cw_min = cpu_to_le16(mvmvif->queue_params[i].cw_min); 634 u8 txf = iwl_mvm_ac_to_tx_fifo[i];
555 cmd->ac[i].cw_max = cpu_to_le16(mvmvif->queue_params[i].cw_max); 635
556 cmd->ac[i].aifsn = mvmvif->queue_params[i].aifs; 636 cmd->ac[txf].cw_min =
557 cmd->ac[i].edca_txop = 637 cpu_to_le16(mvmvif->queue_params[i].cw_min);
638 cmd->ac[txf].cw_max =
639 cpu_to_le16(mvmvif->queue_params[i].cw_max);
640 cmd->ac[txf].edca_txop =
558 cpu_to_le16(mvmvif->queue_params[i].txop * 32); 641 cpu_to_le16(mvmvif->queue_params[i].txop * 32);
559 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]); 642 cmd->ac[txf].aifsn = mvmvif->queue_params[i].aifs;
643 cmd->ac[txf].fifos_mask = BIT(txf);
560 } 644 }
561 645
562 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */ 646 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */
563 if (vif->type == NL80211_IFTYPE_AP) 647 if (vif->type == NL80211_IFTYPE_AP)
564 cmd->ac[AC_VO].fifos_mask |= BIT(IWL_MVM_TX_FIFO_MCAST); 648 cmd->ac[IWL_MVM_TX_FIFO_VO].fifos_mask |=
649 BIT(IWL_MVM_TX_FIFO_MCAST);
565 650
566 if (vif->bss_conf.qos) 651 if (vif->bss_conf.qos)
567 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 652 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
@@ -573,16 +658,13 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
573 cmd->protection_flags |= 658 cmd->protection_flags |=
574 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN); 659 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
575 } 660 }
576 661 IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
577 /* 662 vif->bss_conf.use_cts_prot,
578 * I think that we should enable these 2 flags regardless the HT PROT 663 vif->bss_conf.ht_operation_mode);
579 * fields in the HT IE, but I am not sure. Someone knows whom to ask?... 664 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
580 */
581 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
582 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN); 665 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
583 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT | 666 if (ht_enabled)
584 MAC_PROT_FLG_FAT_PROT); 667 iwl_mvm_mac_ctxt_set_ht_flags(mvm, vif, cmd);
585 }
586 668
587 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP); 669 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
588} 670}
@@ -974,7 +1056,7 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
974 iwl_mvm_mac_ap_iterator, &data); 1056 iwl_mvm_mac_ap_iterator, &data);
975 1057
976 if (data.beacon_device_ts) { 1058 if (data.beacon_device_ts) {
977 u32 rand = (prandom_u32() % (80 - 20)) + 20; 1059 u32 rand = (prandom_u32() % (64 - 36)) + 36;
978 mvmvif->ap_beacon_time = data.beacon_device_ts + 1060 mvmvif->ap_beacon_time = data.beacon_device_ts +
979 ieee80211_tu_to_usec(data.beacon_int * rand / 1061 ieee80211_tu_to_usec(data.beacon_int * rand /
980 100); 1062 100);
@@ -1153,10 +1235,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1153static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, 1235static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1154 struct ieee80211_vif *vif) 1236 struct ieee80211_vif *vif)
1155{ 1237{
1156 u16 *id = _data; 1238 struct iwl_missed_beacons_notif *missed_beacons = _data;
1157 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1239 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1158 1240
1159 if (mvmvif->id == *id) 1241 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
1242 return;
1243
1244 /*
1245 * TODO: the threshold should be adjusted based on latency conditions,
1246 * and/or in case of a CS flow on one of the other AP vifs.
1247 */
1248 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
1249 IWL_MVM_MISSED_BEACONS_THRESHOLD)
1160 ieee80211_beacon_loss(vif); 1250 ieee80211_beacon_loss(vif);
1161} 1251}
1162 1252
@@ -1165,12 +1255,19 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1165 struct iwl_device_cmd *cmd) 1255 struct iwl_device_cmd *cmd)
1166{ 1256{
1167 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1257 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1168 struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data; 1258 struct iwl_missed_beacons_notif *mb = (void *)pkt->data;
1169 u16 id = (u16)le32_to_cpu(missed_beacons->mac_id); 1259
1260 IWL_DEBUG_INFO(mvm,
1261 "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
1262 le32_to_cpu(mb->mac_id),
1263 le32_to_cpu(mb->consec_missed_beacons),
1264 le32_to_cpu(mb->consec_missed_beacons_since_last_rx),
1265 le32_to_cpu(mb->num_recvd_beacons),
1266 le32_to_cpu(mb->num_expected_beacons));
1170 1267
1171 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 1268 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1172 IEEE80211_IFACE_ITER_NORMAL, 1269 IEEE80211_IFACE_ITER_NORMAL,
1173 iwl_mvm_beacon_loss_iterator, 1270 iwl_mvm_beacon_loss_iterator,
1174 &id); 1271 mb);
1175 return 0; 1272 return 0;
1176} 1273}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 74bc2c8af06d..c49b5073c251 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -199,9 +199,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) 199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
201 201
202 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 202 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
203 WIPHY_FLAG_DISABLE_BEACON_HINTS | 203 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
204 WIPHY_FLAG_IBSS_RSN; 204 REGULATORY_DISABLE_BEACON_HINTS;
205 205
206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
207 hw->wiphy->n_iface_combinations = 207 hw->wiphy->n_iface_combinations =
@@ -256,10 +256,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
256 } 256 }
257 257
258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
259 NL80211_FEATURE_P2P_GO_OPPPS; 259 NL80211_FEATURE_P2P_GO_OPPPS |
260 NL80211_FEATURE_LOW_PRIORITY_SCAN;
260 261
261 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 262 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
262 263
264 /* currently FW API supports only one optional cipher scheme */
265 if (mvm->fw->cs[0].cipher) {
266 mvm->hw->n_cipher_schemes = 1;
267 mvm->hw->cipher_schemes = &mvm->fw->cs[0];
268 }
269
263#ifdef CONFIG_PM_SLEEP 270#ifdef CONFIG_PM_SLEEP
264 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 271 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
265 mvm->trans->ops->d3_suspend && 272 mvm->trans->ops->d3_suspend &&
@@ -398,7 +405,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
398static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 405static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
399{ 406{
400 iwl_trans_stop_device(mvm->trans); 407 iwl_trans_stop_device(mvm->trans);
401 iwl_trans_stop_hw(mvm->trans, false);
402 408
403 mvm->scan_status = IWL_MVM_SCAN_NONE; 409 mvm->scan_status = IWL_MVM_SCAN_NONE;
404 410
@@ -470,7 +476,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
470 cancel_work_sync(&mvm->roc_done_wk); 476 cancel_work_sync(&mvm->roc_done_wk);
471 477
472 iwl_trans_stop_device(mvm->trans); 478 iwl_trans_stop_device(mvm->trans);
473 iwl_trans_stop_hw(mvm->trans, false);
474 479
475 iwl_mvm_async_handlers_purge(mvm); 480 iwl_mvm_async_handlers_purge(mvm);
476 /* async_handlers_list is empty and will stay empty: HW is stopped */ 481 /* async_handlers_list is empty and will stay empty: HW is stopped */
@@ -487,17 +492,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
487 cancel_work_sync(&mvm->async_handlers_wk); 492 cancel_work_sync(&mvm->async_handlers_wk);
488} 493}
489 494
490static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
491 struct ieee80211_vif *vif)
492{
493 struct iwl_mvm *mvm = data;
494 int ret;
495
496 ret = iwl_mvm_power_disable(mvm, vif);
497 if (ret)
498 IWL_ERR(mvm, "failed to disable power management\n");
499}
500
501static void iwl_mvm_power_update_iterator(void *data, u8 *mac, 495static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
502 struct ieee80211_vif *vif) 496 struct ieee80211_vif *vif)
503{ 497{
@@ -520,6 +514,20 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
520 return NULL; 514 return NULL;
521} 515}
522 516
517static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
518 s8 tx_power)
519{
520 /* FW is in charge of regulatory enforcement */
521 struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
522 .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id,
523 .pwr_restriction = cpu_to_le16(tx_power),
524 };
525
526 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC,
527 sizeof(reduce_txpwr_cmd),
528 &reduce_txpwr_cmd);
529}
530
523static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 531static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
524 struct ieee80211_vif *vif) 532 struct ieee80211_vif *vif)
525{ 533{
@@ -540,26 +548,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
540 if (ret) 548 if (ret)
541 goto out_unlock; 549 goto out_unlock;
542 550
543 /* 551 /* Counting number of interfaces is needed for legacy PM */
544 * TODO: remove this temporary code.
545 * Currently MVM FW supports power management only on single MAC.
546 * If new interface added, disable PM on existing interface.
547 * P2P device is a special case, since it is handled by FW similary to
548 * scan. If P2P deviced is added, PM remains enabled on existing
549 * interface.
550 * Note: the method below does not count the new interface being added
551 * at this moment.
552 */
553 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 552 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
554 mvm->vif_count++; 553 mvm->vif_count++;
555 if (mvm->vif_count > 1) {
556 IWL_DEBUG_MAC80211(mvm,
557 "Disable power on existing interfaces\n");
558 ieee80211_iterate_active_interfaces_atomic(
559 mvm->hw,
560 IEEE80211_IFACE_ITER_NORMAL,
561 iwl_mvm_pm_disable_iterator, mvm);
562 }
563 554
564 /* 555 /*
565 * The AP binding flow can be done only after the beacon 556 * The AP binding flow can be done only after the beacon
@@ -590,11 +581,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
590 if (ret) 581 if (ret)
591 goto out_release; 582 goto out_release;
592 583
593 /* 584 iwl_mvm_power_disable(mvm, vif);
594 * Update power state on the new interface. Admittedly, based on
595 * mac80211 logics this power update will disable power management
596 */
597 iwl_mvm_power_update_mode(mvm, vif);
598 585
599 /* beacon filtering */ 586 /* beacon filtering */
600 ret = iwl_mvm_disable_beacon_filter(mvm, vif); 587 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
@@ -655,9 +642,12 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
655 out_release: 642 out_release:
656 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 643 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
657 mvm->vif_count--; 644 mvm->vif_count--;
645
646 /* TODO: remove this when legacy PM will be discarded */
658 ieee80211_iterate_active_interfaces( 647 ieee80211_iterate_active_interfaces(
659 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 648 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
660 iwl_mvm_power_update_iterator, mvm); 649 iwl_mvm_power_update_iterator, mvm);
650
661 iwl_mvm_mac_ctxt_release(mvm, vif); 651 iwl_mvm_mac_ctxt_release(mvm, vif);
662 out_unlock: 652 out_unlock:
663 mutex_unlock(&mvm->mutex); 653 mutex_unlock(&mvm->mutex);
@@ -743,21 +733,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
743 mvmvif->phy_ctxt = NULL; 733 mvmvif->phy_ctxt = NULL;
744 } 734 }
745 735
746 /*
747 * TODO: remove this temporary code.
748 * Currently MVM FW supports power management only on single MAC.
749 * Check if only one additional interface remains after removing
750 * current one. Update power mode on the remaining interface.
751 */
752 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) 736 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
753 mvm->vif_count--; 737 mvm->vif_count--;
754 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 738
755 mvm->vif_count); 739 /* TODO: remove this when legacy PM will be discarded */
756 if (mvm->vif_count == 1) { 740 ieee80211_iterate_active_interfaces(
757 ieee80211_iterate_active_interfaces( 741 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
758 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 742 iwl_mvm_power_update_iterator, mvm);
759 iwl_mvm_power_update_iterator, mvm);
760 }
761 743
762 iwl_mvm_mac_ctxt_remove(mvm, vif); 744 iwl_mvm_mac_ctxt_remove(mvm, vif);
763 745
@@ -766,23 +748,91 @@ out_release:
766 mutex_unlock(&mvm->mutex); 748 mutex_unlock(&mvm->mutex);
767} 749}
768 750
769static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 751static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
770 s8 tx_power)
771{ 752{
772 /* FW is in charge of regulatory enforcement */ 753 return 0;
773 struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { 754}
774 .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id, 755
775 .pwr_restriction = cpu_to_le16(tx_power), 756struct iwl_mvm_mc_iter_data {
757 struct iwl_mvm *mvm;
758 int port_id;
759};
760
761static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
762 struct ieee80211_vif *vif)
763{
764 struct iwl_mvm_mc_iter_data *data = _data;
765 struct iwl_mvm *mvm = data->mvm;
766 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
767 int ret, len;
768
769 /* if we don't have free ports, mcast frames will be dropped */
770 if (WARN_ON_ONCE(data->port_id >= MAX_PORT_ID_NUM))
771 return;
772
773 if (vif->type != NL80211_IFTYPE_STATION ||
774 !vif->bss_conf.assoc)
775 return;
776
777 cmd->port_id = data->port_id++;
778 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
779 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
780
781 ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd);
782 if (ret)
783 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
784}
785
786static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
787{
788 struct iwl_mvm_mc_iter_data iter_data = {
789 .mvm = mvm,
776 }; 790 };
777 791
778 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC, 792 lockdep_assert_held(&mvm->mutex);
779 sizeof(reduce_txpwr_cmd), 793
780 &reduce_txpwr_cmd); 794 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
795 return;
796
797 ieee80211_iterate_active_interfaces(
798 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
799 iwl_mvm_mc_iface_iterator, &iter_data);
781} 800}
782 801
783static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) 802static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
803 struct netdev_hw_addr_list *mc_list)
784{ 804{
785 return 0; 805 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
806 struct iwl_mcast_filter_cmd *cmd;
807 struct netdev_hw_addr *addr;
808 int addr_count = netdev_hw_addr_list_count(mc_list);
809 bool pass_all = false;
810 int len;
811
812 if (addr_count > MAX_MCAST_FILTERING_ADDRESSES) {
813 pass_all = true;
814 addr_count = 0;
815 }
816
817 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
818 cmd = kzalloc(len, GFP_ATOMIC);
819 if (!cmd)
820 return 0;
821
822 if (pass_all) {
823 cmd->pass_all = 1;
824 return (u64)(unsigned long)cmd;
825 }
826
827 netdev_hw_addr_list_for_each(addr, mc_list) {
828 IWL_DEBUG_MAC80211(mvm, "mcast addr (%d): %pM\n",
829 cmd->count, addr->addr);
830 memcpy(&cmd->addr_list[cmd->count * ETH_ALEN],
831 addr->addr, ETH_ALEN);
832 cmd->count++;
833 }
834
835 return (u64)(unsigned long)cmd;
786} 836}
787 837
788static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, 838static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
@@ -790,21 +840,22 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
790 unsigned int *total_flags, 840 unsigned int *total_flags,
791 u64 multicast) 841 u64 multicast)
792{ 842{
793 *total_flags = 0; 843 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
794} 844 struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast;
795 845
796static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm, 846 mutex_lock(&mvm->mutex);
797 struct ieee80211_vif *vif)
798{
799 struct iwl_mcast_filter_cmd mcast_filter_cmd = {
800 .pass_all = 1,
801 };
802 847
803 memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN); 848 /* replace previous configuration */
849 kfree(mvm->mcast_filter_cmd);
850 mvm->mcast_filter_cmd = cmd;
804 851
805 return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, 852 if (!cmd)
806 sizeof(mcast_filter_cmd), 853 goto out;
807 &mcast_filter_cmd); 854
855 iwl_mvm_recalc_multicast(mvm);
856out:
857 mutex_unlock(&mvm->mutex);
858 *total_flags = 0;
808} 859}
809 860
810static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 861static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
@@ -815,6 +866,14 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
815 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 866 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
816 int ret; 867 int ret;
817 868
869 /*
870 * Re-calculate the tsf id, as the master-slave relations depend on the
871 * beacon interval, which was not known when the station interface was
872 * added.
873 */
874 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
875 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
876
818 ret = iwl_mvm_mac_ctxt_changed(mvm, vif); 877 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
819 if (ret) 878 if (ret)
820 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 879 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
@@ -827,7 +886,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
827 IWL_ERR(mvm, "failed to update quotas\n"); 886 IWL_ERR(mvm, "failed to update quotas\n");
828 return; 887 return;
829 } 888 }
830 iwl_mvm_configure_mcast_filter(mvm, vif);
831 889
832 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, 890 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
833 &mvm->status)) { 891 &mvm->status)) {
@@ -849,7 +907,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
849 iwl_mvm_protect_session(mvm, vif, dur, dur, 907 iwl_mvm_protect_session(mvm, vif, dur, dur,
850 5 * dur); 908 5 * dur);
851 } 909 }
910
911 iwl_mvm_sf_update(mvm, vif, false);
912 iwl_mvm_power_vif_assoc(mvm, vif);
852 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 913 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
914 /*
915 * If update fails - SF might be running in associated
916 * mode while disassociated - which is forbidden.
917 */
918 WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
919 "Failed to update SF upon disassociation\n");
920
853 /* remove AP station now that the MAC is unassoc */ 921 /* remove AP station now that the MAC is unassoc */
854 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 922 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
855 if (ret) 923 if (ret)
@@ -861,6 +929,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
861 IWL_ERR(mvm, "failed to update quotas\n"); 929 IWL_ERR(mvm, "failed to update quotas\n");
862 } 930 }
863 931
932 iwl_mvm_recalc_multicast(mvm);
933
864 /* reset rssi values */ 934 /* reset rssi values */
865 mvmvif->bf_data.ave_beacon_signal = 0; 935 mvmvif->bf_data.ave_beacon_signal = 0;
866 936
@@ -874,6 +944,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
874 IWL_ERR(mvm, "failed to update power mode\n"); 944 IWL_ERR(mvm, "failed to update power mode\n");
875 } 945 }
876 iwl_mvm_bt_coex_vif_change(mvm); 946 iwl_mvm_bt_coex_vif_change(mvm);
947 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
948 IEEE80211_SMPS_AUTOMATIC);
877 } else if (changes & BSS_CHANGED_BEACON_INFO) { 949 } else if (changes & BSS_CHANGED_BEACON_INFO) {
878 /* 950 /*
879 * We received a beacon _after_ association so 951 * We received a beacon _after_ association so
@@ -881,7 +953,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
881 */ 953 */
882 iwl_mvm_remove_time_event(mvm, mvmvif, 954 iwl_mvm_remove_time_event(mvm, mvmvif,
883 &mvmvif->time_event_data); 955 &mvmvif->time_event_data);
884 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_QOS)) { 956 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
957 BSS_CHANGED_QOS)) {
885 ret = iwl_mvm_power_update_mode(mvm, vif); 958 ret = iwl_mvm_power_update_mode(mvm, vif);
886 if (ret) 959 if (ret)
887 IWL_ERR(mvm, "failed to update power mode\n"); 960 IWL_ERR(mvm, "failed to update power mode\n");
@@ -916,6 +989,13 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
916 if (ret) 989 if (ret)
917 goto out_unlock; 990 goto out_unlock;
918 991
992 /*
993 * Re-calculate the tsf id, as the master-slave relations depend on the
994 * beacon interval, which was not known when the AP interface was added.
995 */
996 if (vif->type == NL80211_IFTYPE_AP)
997 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
998
919 /* Add the mac context */ 999 /* Add the mac context */
920 ret = iwl_mvm_mac_ctxt_add(mvm, vif); 1000 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
921 if (ret) 1001 if (ret)
@@ -934,9 +1014,16 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
934 if (ret) 1014 if (ret)
935 goto out_unbind; 1015 goto out_unbind;
936 1016
1017 /* must be set before quota calculations */
1018 mvmvif->ap_ibss_active = true;
1019
1020 /* power updated needs to be done before quotas */
1021 mvm->bound_vif_cnt++;
1022 iwl_mvm_power_update_binding(mvm, vif, true);
1023
937 ret = iwl_mvm_update_quotas(mvm, vif); 1024 ret = iwl_mvm_update_quotas(mvm, vif);
938 if (ret) 1025 if (ret)
939 goto out_rm_bcast; 1026 goto out_quota_failed;
940 1027
941 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 1028 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
942 if (vif->p2p && mvm->p2p_device_vif) 1029 if (vif->p2p && mvm->p2p_device_vif)
@@ -947,7 +1034,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
947 mutex_unlock(&mvm->mutex); 1034 mutex_unlock(&mvm->mutex);
948 return 0; 1035 return 0;
949 1036
950out_rm_bcast: 1037out_quota_failed:
1038 mvm->bound_vif_cnt--;
1039 iwl_mvm_power_update_binding(mvm, vif, false);
1040 mvmvif->ap_ibss_active = false;
951 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1041 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
952out_unbind: 1042out_unbind:
953 iwl_mvm_binding_remove_vif(mvm, vif); 1043 iwl_mvm_binding_remove_vif(mvm, vif);
@@ -979,6 +1069,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
979 iwl_mvm_update_quotas(mvm, NULL); 1069 iwl_mvm_update_quotas(mvm, NULL);
980 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1070 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
981 iwl_mvm_binding_remove_vif(mvm, vif); 1071 iwl_mvm_binding_remove_vif(mvm, vif);
1072
1073 mvm->bound_vif_cnt--;
1074 iwl_mvm_power_update_binding(mvm, vif, false);
1075
982 iwl_mvm_mac_ctxt_remove(mvm, vif); 1076 iwl_mvm_mac_ctxt_remove(mvm, vif);
983 1077
984 mutex_unlock(&mvm->mutex); 1078 mutex_unlock(&mvm->mutex);
@@ -990,6 +1084,22 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
990 struct ieee80211_bss_conf *bss_conf, 1084 struct ieee80211_bss_conf *bss_conf,
991 u32 changes) 1085 u32 changes)
992{ 1086{
1087 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1088 enum ieee80211_bss_change ht_change = BSS_CHANGED_ERP_CTS_PROT |
1089 BSS_CHANGED_HT |
1090 BSS_CHANGED_BANDWIDTH;
1091 int ret;
1092
1093 /* Changes will be applied when the AP/IBSS is started */
1094 if (!mvmvif->ap_ibss_active)
1095 return;
1096
1097 if (changes & ht_change) {
1098 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1099 if (ret)
1100 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1101 }
1102
993 /* Need to send a new beacon template to the FW */ 1103 /* Need to send a new beacon template to the FW */
994 if (changes & BSS_CHANGED_BEACON) { 1104 if (changes & BSS_CHANGED_BEACON) {
995 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif)) 1105 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
@@ -1080,7 +1190,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1080 struct ieee80211_sta *sta) 1190 struct ieee80211_sta *sta)
1081{ 1191{
1082 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1192 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1083 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1193 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1084 1194
1085 switch (cmd) { 1195 switch (cmd) {
1086 case STA_NOTIFY_SLEEP: 1196 case STA_NOTIFY_SLEEP:
@@ -1102,6 +1212,28 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1102 } 1212 }
1103} 1213}
1104 1214
1215static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
1216 struct ieee80211_vif *vif,
1217 struct ieee80211_sta *sta)
1218{
1219 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1220 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1221
1222 /*
1223 * This is called before mac80211 does RCU synchronisation,
1224 * so here we already invalidate our internal RCU-protected
1225 * station pointer. The rest of the code will thus no longer
1226 * be able to find the station this way, and we don't rely
1227 * on further RCU synchronisation after the sta_state()
1228 * callback deleted the station.
1229 */
1230 mutex_lock(&mvm->mutex);
1231 if (sta == rcu_access_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id]))
1232 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
1233 ERR_PTR(-ENOENT));
1234 mutex_unlock(&mvm->mutex);
1235}
1236
1105static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 1237static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1106 struct ieee80211_vif *vif, 1238 struct ieee80211_vif *vif,
1107 struct ieee80211_sta *sta, 1239 struct ieee80211_sta *sta,
@@ -1149,7 +1281,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1149 ret = iwl_mvm_update_sta(mvm, vif, sta); 1281 ret = iwl_mvm_update_sta(mvm, vif, sta);
1150 if (ret == 0) 1282 if (ret == 0)
1151 iwl_mvm_rs_rate_init(mvm, sta, 1283 iwl_mvm_rs_rate_init(mvm, sta,
1152 mvmvif->phy_ctxt->channel->band); 1284 mvmvif->phy_ctxt->channel->band,
1285 true);
1153 } else if (old_state == IEEE80211_STA_ASSOC && 1286 } else if (old_state == IEEE80211_STA_ASSOC &&
1154 new_state == IEEE80211_STA_AUTHORIZED) { 1287 new_state == IEEE80211_STA_AUTHORIZED) {
1155 /* enable beacon filtering */ 1288 /* enable beacon filtering */
@@ -1187,6 +1320,17 @@ static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1187 return 0; 1320 return 0;
1188} 1321}
1189 1322
1323static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
1324 struct ieee80211_vif *vif,
1325 struct ieee80211_sta *sta, u32 changed)
1326{
1327 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1328
1329 if (vif->type == NL80211_IFTYPE_STATION &&
1330 changed & IEEE80211_RC_NSS_CHANGED)
1331 iwl_mvm_sf_update(mvm, vif, false);
1332}
1333
1190static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw, 1334static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
1191 struct ieee80211_vif *vif, u16 ac, 1335 struct ieee80211_vif *vif, u16 ac,
1192 const struct ieee80211_tx_queue_params *params) 1336 const struct ieee80211_tx_queue_params *params)
@@ -1309,7 +1453,12 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1309 */ 1453 */
1310 return 0; 1454 return 0;
1311 default: 1455 default:
1312 return -EOPNOTSUPP; 1456 /* currently FW supports only one optional cipher scheme */
1457 if (hw->n_cipher_schemes &&
1458 hw->cipher_schemes->cipher == key->cipher)
1459 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
1460 else
1461 return -EOPNOTSUPP;
1313 } 1462 }
1314 1463
1315 mutex_lock(&mvm->mutex); 1464 mutex_lock(&mvm->mutex);
@@ -1515,7 +1664,7 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1515 goto out; 1664 goto out;
1516 } 1665 }
1517 1666
1518 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1667 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1519 ctx->rx_chains_static, 1668 ctx->rx_chains_static,
1520 ctx->rx_chains_dynamic); 1669 ctx->rx_chains_dynamic);
1521 if (ret) { 1670 if (ret) {
@@ -1553,13 +1702,14 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1553 if (WARN_ONCE((phy_ctxt->ref > 1) && 1702 if (WARN_ONCE((phy_ctxt->ref > 1) &&
1554 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | 1703 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1555 IEEE80211_CHANCTX_CHANGE_RX_CHAINS | 1704 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1556 IEEE80211_CHANCTX_CHANGE_RADAR)), 1705 IEEE80211_CHANCTX_CHANGE_RADAR |
1706 IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
1557 "Cannot change PHY. Ref=%d, changed=0x%X\n", 1707 "Cannot change PHY. Ref=%d, changed=0x%X\n",
1558 phy_ctxt->ref, changed)) 1708 phy_ctxt->ref, changed))
1559 return; 1709 return;
1560 1710
1561 mutex_lock(&mvm->mutex); 1711 mutex_lock(&mvm->mutex);
1562 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1712 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1563 ctx->rx_chains_static, 1713 ctx->rx_chains_static,
1564 ctx->rx_chains_dynamic); 1714 ctx->rx_chains_dynamic);
1565 iwl_mvm_bt_coex_vif_change(mvm); 1715 iwl_mvm_bt_coex_vif_change(mvm);
@@ -1602,7 +1752,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1602 goto out_unlock; 1752 goto out_unlock;
1603 1753
1604 /* 1754 /*
1605 * Setting the quota at this stage is only required for monitor 1755 * Power state must be updated before quotas,
1756 * otherwise fw will complain.
1757 */
1758 mvm->bound_vif_cnt++;
1759 iwl_mvm_power_update_binding(mvm, vif, true);
1760
1761 /* Setting the quota at this stage is only required for monitor
1606 * interfaces. For the other types, the bss_info changed flow 1762 * interfaces. For the other types, the bss_info changed flow
1607 * will handle quota settings. 1763 * will handle quota settings.
1608 */ 1764 */
@@ -1617,6 +1773,8 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1617 1773
1618 out_remove_binding: 1774 out_remove_binding:
1619 iwl_mvm_binding_remove_vif(mvm, vif); 1775 iwl_mvm_binding_remove_vif(mvm, vif);
1776 mvm->bound_vif_cnt--;
1777 iwl_mvm_power_update_binding(mvm, vif, false);
1620 out_unlock: 1778 out_unlock:
1621 mutex_unlock(&mvm->mutex); 1779 mutex_unlock(&mvm->mutex);
1622 if (ret) 1780 if (ret)
@@ -1648,6 +1806,9 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1648 } 1806 }
1649 1807
1650 iwl_mvm_binding_remove_vif(mvm, vif); 1808 iwl_mvm_binding_remove_vif(mvm, vif);
1809 mvm->bound_vif_cnt--;
1810 iwl_mvm_power_update_binding(mvm, vif, false);
1811
1651out_unlock: 1812out_unlock:
1652 mvmvif->phy_ctxt = NULL; 1813 mvmvif->phy_ctxt = NULL;
1653 mutex_unlock(&mvm->mutex); 1814 mutex_unlock(&mvm->mutex);
@@ -1744,14 +1905,17 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
1744 .add_interface = iwl_mvm_mac_add_interface, 1905 .add_interface = iwl_mvm_mac_add_interface,
1745 .remove_interface = iwl_mvm_mac_remove_interface, 1906 .remove_interface = iwl_mvm_mac_remove_interface,
1746 .config = iwl_mvm_mac_config, 1907 .config = iwl_mvm_mac_config,
1908 .prepare_multicast = iwl_mvm_prepare_multicast,
1747 .configure_filter = iwl_mvm_configure_filter, 1909 .configure_filter = iwl_mvm_configure_filter,
1748 .bss_info_changed = iwl_mvm_bss_info_changed, 1910 .bss_info_changed = iwl_mvm_bss_info_changed,
1749 .hw_scan = iwl_mvm_mac_hw_scan, 1911 .hw_scan = iwl_mvm_mac_hw_scan,
1750 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan, 1912 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1913 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove,
1751 .sta_state = iwl_mvm_mac_sta_state, 1914 .sta_state = iwl_mvm_mac_sta_state,
1752 .sta_notify = iwl_mvm_mac_sta_notify, 1915 .sta_notify = iwl_mvm_mac_sta_notify,
1753 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames, 1916 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1754 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, 1917 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1918 .sta_rc_update = iwl_mvm_sta_rc_update,
1755 .conf_tx = iwl_mvm_mac_conf_tx, 1919 .conf_tx = iwl_mvm_mac_conf_tx,
1756 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 1920 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1757 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 1921 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fed21ef4162d..e4ead86f06d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,7 @@
81#define IWL_MVM_MAX_ADDRESSES 5 81#define IWL_MVM_MAX_ADDRESSES 5
82/* RSSI offset for WkP */ 82/* RSSI offset for WkP */
83#define IWL_RSSI_OFFSET 50 83#define IWL_RSSI_OFFSET 50
84#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8
84 85
85enum iwl_mvm_tx_fifo { 86enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0, 87 IWL_MVM_TX_FIFO_BK = 0,
@@ -163,6 +164,8 @@ struct iwl_mvm_power_ops {
163 struct ieee80211_vif *vif); 164 struct ieee80211_vif *vif);
164 int (*power_update_device_mode)(struct iwl_mvm *mvm); 165 int (*power_update_device_mode)(struct iwl_mvm *mvm);
165 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 166 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
167 void (*power_update_binding)(struct iwl_mvm *mvm,
168 struct ieee80211_vif *vif, bool assign);
166#ifdef CONFIG_IWLWIFI_DEBUGFS 169#ifdef CONFIG_IWLWIFI_DEBUGFS
167 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 170 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
168 char *buf, int bufsz); 171 char *buf, int bufsz);
@@ -181,6 +184,7 @@ enum iwl_dbgfs_pm_mask {
181 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6), 184 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
182 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), 185 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
183 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), 186 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
187 MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9),
184}; 188};
185 189
186struct iwl_dbgfs_pm { 190struct iwl_dbgfs_pm {
@@ -193,6 +197,7 @@ struct iwl_dbgfs_pm {
193 bool lprx_ena; 197 bool lprx_ena;
194 u32 lprx_rssi_threshold; 198 u32 lprx_rssi_threshold;
195 bool snooze_ena; 199 bool snooze_ena;
200 bool uapsd_misbehaving;
196 int mask; 201 int mask;
197}; 202};
198 203
@@ -269,8 +274,8 @@ struct iwl_mvm_vif_bf_data {
269 * @bcast_sta: station used for broadcast packets. Used by the following 274 * @bcast_sta: station used for broadcast packets. Used by the following
270 * vifs: P2P_DEVICE, GO and AP. 275 * vifs: P2P_DEVICE, GO and AP.
271 * @beacon_skb: the skb used to hold the AP/GO beacon template 276 * @beacon_skb: the skb used to hold the AP/GO beacon template
272 * @smps_requests: the requests of of differents parts of the driver, regard 277 * @smps_requests: the SMPS requests of differents parts of the driver,
273 the desired smps mode. 278 * combined on update to yield the overall request to mac80211.
274 */ 279 */
275struct iwl_mvm_vif { 280struct iwl_mvm_vif {
276 u16 id; 281 u16 id;
@@ -323,14 +328,19 @@ struct iwl_mvm_vif {
323#endif 328#endif
324 329
325#ifdef CONFIG_IWLWIFI_DEBUGFS 330#ifdef CONFIG_IWLWIFI_DEBUGFS
331 struct iwl_mvm *mvm;
326 struct dentry *dbgfs_dir; 332 struct dentry *dbgfs_dir;
327 struct dentry *dbgfs_slink; 333 struct dentry *dbgfs_slink;
328 void *dbgfs_data;
329 struct iwl_dbgfs_pm dbgfs_pm; 334 struct iwl_dbgfs_pm dbgfs_pm;
330 struct iwl_dbgfs_bf dbgfs_bf; 335 struct iwl_dbgfs_bf dbgfs_bf;
331#endif 336#endif
332 337
333 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ]; 338 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
339
340 /* FW identified misbehaving AP */
341 u8 uapsd_misbehaving_bssid[ETH_ALEN];
342
343 bool pm_prevented;
334}; 344};
335 345
336static inline struct iwl_mvm_vif * 346static inline struct iwl_mvm_vif *
@@ -479,6 +489,7 @@ struct iwl_mvm {
479 /* Scan status, cmd (pre-allocated) and auxiliary station */ 489 /* Scan status, cmd (pre-allocated) and auxiliary station */
480 enum iwl_scan_status scan_status; 490 enum iwl_scan_status scan_status;
481 struct iwl_scan_cmd *scan_cmd; 491 struct iwl_scan_cmd *scan_cmd;
492 struct iwl_mcast_filter_cmd *mcast_filter_cmd;
482 493
483 /* rx chain antennas set through debugfs for the scan command */ 494 /* rx chain antennas set through debugfs for the scan command */
484 u8 scan_rx_ant; 495 u8 scan_rx_ant;
@@ -489,11 +500,19 @@ struct iwl_mvm {
489 u8 scan_last_antenna_idx; /* to toggle TX between antennas */ 500 u8 scan_last_antenna_idx; /* to toggle TX between antennas */
490 u8 mgmt_last_antenna_idx; 501 u8 mgmt_last_antenna_idx;
491 502
503 /* last smart fifo state that was successfully sent to firmware */
504 enum iwl_sf_state sf_state;
505
492#ifdef CONFIG_IWLWIFI_DEBUGFS 506#ifdef CONFIG_IWLWIFI_DEBUGFS
493 struct dentry *debugfs_dir; 507 struct dentry *debugfs_dir;
494 u32 dbgfs_sram_offset, dbgfs_sram_len; 508 u32 dbgfs_sram_offset, dbgfs_sram_len;
495 bool disable_power_off; 509 bool disable_power_off;
496 bool disable_power_off_d3; 510 bool disable_power_off_d3;
511
512 struct debugfs_blob_wrapper nvm_hw_blob;
513 struct debugfs_blob_wrapper nvm_sw_blob;
514 struct debugfs_blob_wrapper nvm_calib_blob;
515 struct debugfs_blob_wrapper nvm_prod_blob;
497#endif 516#endif
498 517
499 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 518 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -507,12 +526,6 @@ struct iwl_mvm {
507 */ 526 */
508 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; 527 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
509 528
510 /*
511 * This counter of created interfaces is referenced only in conjunction
512 * with FW limitation related to power management. Currently PM is
513 * supported only on a single interface.
514 * IMPORTANT: this variable counts all interfaces except P2P device.
515 */
516 u8 vif_count; 529 u8 vif_count;
517 530
518 /* -1 for always, 0 for never, >0 for that many times */ 531 /* -1 for always, 0 for never, >0 for that many times */
@@ -531,6 +544,7 @@ struct iwl_mvm {
531 bool store_d3_resume_sram; 544 bool store_d3_resume_sram;
532 void *d3_resume_sram; 545 void *d3_resume_sram;
533 u32 d3_test_pme_ptr; 546 u32 d3_test_pme_ptr;
547 struct ieee80211_vif *keep_vif;
534#endif 548#endif
535#endif 549#endif
536 550
@@ -554,6 +568,11 @@ struct iwl_mvm {
554 u8 aux_queue; 568 u8 aux_queue;
555 u8 first_agg_queue; 569 u8 first_agg_queue;
556 u8 last_agg_queue; 570 u8 last_agg_queue;
571
572 u8 bound_vif_cnt;
573
574 /* Indicate if device power save is allowed */
575 bool ps_prevented;
557}; 576};
558 577
559/* Extract MVM priv from op_mode and _hw */ 578/* Extract MVM priv from op_mode and _hw */
@@ -693,6 +712,8 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
693int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, 712int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
694 struct iwl_rx_cmd_buffer *rxb, 713 struct iwl_rx_cmd_buffer *rxb,
695 struct iwl_device_cmd *cmd); 714 struct iwl_device_cmd *cmd);
715void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
716 struct ieee80211_vif *vif);
696 717
697/* Bindings */ 718/* Bindings */
698int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 719int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -750,8 +771,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
750#endif /* CONFIG_IWLWIFI_DEBUGFS */ 771#endif /* CONFIG_IWLWIFI_DEBUGFS */
751 772
752/* rate scaling */ 773/* rate scaling */
753int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 774int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
754 u8 flags, bool init);
755 775
756/* power managment */ 776/* power managment */
757static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, 777static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
@@ -773,6 +793,19 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
773 return 0; 793 return 0;
774} 794}
775 795
796static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
797 struct ieee80211_vif *vif,
798 bool assign)
799{
800 if (mvm->pm_ops->power_update_binding)
801 mvm->pm_ops->power_update_binding(mvm, vif, assign);
802}
803
804void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
805int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
806 struct iwl_rx_cmd_buffer *rxb,
807 struct iwl_device_cmd *cmd);
808
776#ifdef CONFIG_IWLWIFI_DEBUGFS 809#ifdef CONFIG_IWLWIFI_DEBUGFS
777static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, 810static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm,
778 struct ieee80211_vif *vif, 811 struct ieee80211_vif *vif,
@@ -864,4 +897,8 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
864void iwl_mvm_tt_exit(struct iwl_mvm *mvm); 897void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
865void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); 898void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
866 899
900/* smart fifo */
901int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
902 bool added_vif);
903
867#endif /* __IWL_MVM_H__ */ 904#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2beffd028b67..35b71af78d02 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -367,16 +367,17 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
367 break; 367 break;
368 } 368 }
369 369
370 if (WARN(section_id >= NVM_NUM_OF_SECTIONS,
371 "Invalid NVM section ID %d\n", section_id)) {
372 ret = -EINVAL;
373 break;
374 }
375
370 temp = kmemdup(file_sec->data, section_size, GFP_KERNEL); 376 temp = kmemdup(file_sec->data, section_size, GFP_KERNEL);
371 if (!temp) { 377 if (!temp) {
372 ret = -ENOMEM; 378 ret = -ENOMEM;
373 break; 379 break;
374 } 380 }
375 if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) {
376 IWL_ERR(mvm, "Invalid NVM section ID\n");
377 ret = -EINVAL;
378 break;
379 }
380 mvm->nvm_sections[section_id].data = temp; 381 mvm->nvm_sections[section_id].data = temp;
381 mvm->nvm_sections[section_id].length = section_size; 382 mvm->nvm_sections[section_id].length = section_size;
382 383
@@ -391,17 +392,16 @@ out:
391/* Loads the NVM data stored in mvm->nvm_sections into the NIC */ 392/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
392int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm) 393int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
393{ 394{
394 int i, ret; 395 int i, ret = 0;
395 u16 section_id;
396 struct iwl_nvm_section *sections = mvm->nvm_sections; 396 struct iwl_nvm_section *sections = mvm->nvm_sections;
397 397
398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n"); 398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
399 399
400 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 400 for (i = 0; i < ARRAY_SIZE(mvm->nvm_sections); i++) {
401 section_id = nvm_to_read[i]; 401 if (!mvm->nvm_sections[i].data || !mvm->nvm_sections[i].length)
402 ret = iwl_nvm_write_section(mvm, section_id, 402 continue;
403 sections[section_id].data, 403 ret = iwl_nvm_write_section(mvm, i, sections[i].data,
404 sections[section_id].length); 404 sections[i].length);
405 if (ret < 0) { 405 if (ret < 0) {
406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret); 406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
407 break; 407 break;
@@ -443,6 +443,29 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
443 } 443 }
444 mvm->nvm_sections[section].data = temp; 444 mvm->nvm_sections[section].data = temp;
445 mvm->nvm_sections[section].length = ret; 445 mvm->nvm_sections[section].length = ret;
446
447#ifdef CONFIG_IWLWIFI_DEBUGFS
448 switch (section) {
449 case NVM_SECTION_TYPE_HW:
450 mvm->nvm_hw_blob.data = temp;
451 mvm->nvm_hw_blob.size = ret;
452 break;
453 case NVM_SECTION_TYPE_SW:
454 mvm->nvm_sw_blob.data = temp;
455 mvm->nvm_sw_blob.size = ret;
456 break;
457 case NVM_SECTION_TYPE_CALIBRATION:
458 mvm->nvm_calib_blob.data = temp;
459 mvm->nvm_calib_blob.size = ret;
460 break;
461 case NVM_SECTION_TYPE_PRODUCTION:
462 mvm->nvm_prod_blob.data = temp;
463 mvm->nvm_prod_blob.size = ret;
464 break;
465 default:
466 WARN(1, "section: %d", section);
467 }
468#endif
446 } 469 }
447 kfree(nvm_buffer); 470 kfree(nvm_buffer);
448 if (ret < 0) 471 if (ret < 0)
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index d86083c6f445..a3d43de342d7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -236,6 +236,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
236 false), 236 false),
237 237
238 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 238 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
239 RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
240 iwl_mvm_power_uapsd_misbehaving_ap_notif, false),
239}; 241};
240#undef RX_HANDLER 242#undef RX_HANDLER
241#define CMD(x) [x] = #x 243#define CMD(x) [x] = #x
@@ -307,10 +309,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
307 CMD(BT_PROFILE_NOTIFICATION), 309 CMD(BT_PROFILE_NOTIFICATION),
308 CMD(BT_CONFIG), 310 CMD(BT_CONFIG),
309 CMD(MCAST_FILTER_CMD), 311 CMD(MCAST_FILTER_CMD),
312 CMD(REPLY_SF_CFG_CMD),
310 CMD(REPLY_BEACON_FILTERING_CMD), 313 CMD(REPLY_BEACON_FILTERING_CMD),
311 CMD(REPLY_THERMAL_MNG_BACKOFF), 314 CMD(REPLY_THERMAL_MNG_BACKOFF),
312 CMD(MAC_PM_POWER_TABLE), 315 CMD(MAC_PM_POWER_TABLE),
313 CMD(BT_COEX_CI), 316 CMD(BT_COEX_CI),
317 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
314}; 318};
315#undef CMD 319#undef CMD
316 320
@@ -341,7 +345,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
341 345
342 op_mode = hw->priv; 346 op_mode = hw->priv;
343 op_mode->ops = &iwl_mvm_ops; 347 op_mode->ops = &iwl_mvm_ops;
344 op_mode->trans = trans;
345 348
346 mvm = IWL_OP_MODE_GET_MVM(op_mode); 349 mvm = IWL_OP_MODE_GET_MVM(op_mode);
347 mvm->dev = trans->dev; 350 mvm->dev = trans->dev;
@@ -359,6 +362,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
359 mvm->aux_queue = 11; 362 mvm->aux_queue = 11;
360 mvm->first_agg_queue = 12; 363 mvm->first_agg_queue = 12;
361 } 364 }
365 mvm->sf_state = SF_UNINIT;
362 366
363 mutex_init(&mvm->mutex); 367 mutex_init(&mvm->mutex);
364 spin_lock_init(&mvm->async_handlers_lock); 368 spin_lock_init(&mvm->async_handlers_lock);
@@ -424,7 +428,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
424 * there is no need to unnecessarily power up the NIC at driver load 428 * there is no need to unnecessarily power up the NIC at driver load
425 */ 429 */
426 if (iwlwifi_mod_params.nvm_file) { 430 if (iwlwifi_mod_params.nvm_file) {
427 iwl_nvm_init(mvm); 431 err = iwl_nvm_init(mvm);
432 if (err)
433 goto out_free;
428 } else { 434 } else {
429 err = iwl_trans_start_hw(mvm->trans); 435 err = iwl_trans_start_hw(mvm->trans);
430 if (err) 436 if (err)
@@ -432,16 +438,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
432 438
433 mutex_lock(&mvm->mutex); 439 mutex_lock(&mvm->mutex);
434 err = iwl_run_init_mvm_ucode(mvm, true); 440 err = iwl_run_init_mvm_ucode(mvm, true);
441 iwl_trans_stop_device(trans);
435 mutex_unlock(&mvm->mutex); 442 mutex_unlock(&mvm->mutex);
436 /* returns 0 if successful, 1 if success but in rfkill */ 443 /* returns 0 if successful, 1 if success but in rfkill */
437 if (err < 0 && !iwlmvm_mod_params.init_dbg) { 444 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
438 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 445 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
439 goto out_free; 446 goto out_free;
440 } 447 }
441
442 /* Stop the hw after the ALIVE and NVM has been read */
443 if (!iwlmvm_mod_params.init_dbg)
444 iwl_trans_stop_hw(mvm->trans, false);
445 } 448 }
446 449
447 scan_size = sizeof(struct iwl_scan_cmd) + 450 scan_size = sizeof(struct iwl_scan_cmd) +
@@ -470,11 +473,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
470 473
471 out_unregister: 474 out_unregister:
472 ieee80211_unregister_hw(mvm->hw); 475 ieee80211_unregister_hw(mvm->hw);
476 iwl_mvm_leds_exit(mvm);
473 out_free: 477 out_free:
474 iwl_phy_db_free(mvm->phy_db); 478 iwl_phy_db_free(mvm->phy_db);
475 kfree(mvm->scan_cmd); 479 kfree(mvm->scan_cmd);
476 if (!iwlwifi_mod_params.nvm_file) 480 if (!iwlwifi_mod_params.nvm_file)
477 iwl_trans_stop_hw(trans, true); 481 iwl_trans_op_mode_leave(trans);
478 ieee80211_free_hw(mvm->hw); 482 ieee80211_free_hw(mvm->hw);
479 return NULL; 483 return NULL;
480} 484}
@@ -491,12 +495,14 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
491 ieee80211_unregister_hw(mvm->hw); 495 ieee80211_unregister_hw(mvm->hw);
492 496
493 kfree(mvm->scan_cmd); 497 kfree(mvm->scan_cmd);
498 kfree(mvm->mcast_filter_cmd);
499 mvm->mcast_filter_cmd = NULL;
494 500
495#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) 501#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
496 kfree(mvm->d3_resume_sram); 502 kfree(mvm->d3_resume_sram);
497#endif 503#endif
498 504
499 iwl_trans_stop_hw(mvm->trans, true); 505 iwl_trans_op_mode_leave(mvm->trans);
500 506
501 iwl_phy_db_free(mvm->phy_db); 507 iwl_phy_db_free(mvm->phy_db);
502 mvm->phy_db = NULL; 508 mvm->phy_db = NULL;
@@ -661,6 +667,8 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
661 else 667 else
662 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 668 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
663 669
670 if (state && mvm->cur_ucode != IWL_UCODE_INIT)
671 iwl_trans_stop_device(mvm->trans);
664 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 672 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
665} 673}
666 674
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index a8652ddd6bed..b7268c0b3333 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 550824aa84ea..d9eab3b7bb9f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,6 @@
64#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/module.h> 65#include <linux/module.h>
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/init.h>
68 67
69#include <net/mac80211.h> 68#include <net/mac80211.h>
70 69
@@ -186,6 +185,92 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
186 } 185 }
187} 186}
188 187
188static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
189 struct ieee80211_vif *vif,
190 struct iwl_mac_power_cmd *cmd)
191{
192 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
193 enum ieee80211_ac_numbers ac;
194 bool tid_found = false;
195
196 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) {
197 if (!mvmvif->queue_params[ac].uapsd)
198 continue;
199
200 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
201 cmd->flags |=
202 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
203
204 cmd->uapsd_ac_flags |= BIT(ac);
205
206 /* QNDP TID - the highest TID with no admission control */
207 if (!tid_found && !mvmvif->queue_params[ac].acm) {
208 tid_found = true;
209 switch (ac) {
210 case IEEE80211_AC_VO:
211 cmd->qndp_tid = 6;
212 break;
213 case IEEE80211_AC_VI:
214 cmd->qndp_tid = 5;
215 break;
216 case IEEE80211_AC_BE:
217 cmd->qndp_tid = 0;
218 break;
219 case IEEE80211_AC_BK:
220 cmd->qndp_tid = 1;
221 break;
222 }
223 }
224 }
225
226 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
227 return;
228
229 cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
230
231 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
232 BIT(IEEE80211_AC_VI) |
233 BIT(IEEE80211_AC_BE) |
234 BIT(IEEE80211_AC_BK))) {
235 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
236 cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
237 cmd->snooze_window = (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
238 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
239 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
240 }
241
242 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
243
244 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
245 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
246 cmd->rx_data_timeout_uapsd =
247 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
248 cmd->tx_data_timeout_uapsd =
249 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
250 } else {
251 cmd->rx_data_timeout_uapsd =
252 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
253 cmd->tx_data_timeout_uapsd =
254 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
255 }
256
257 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
258 cmd->heavy_tx_thld_packets =
259 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
260 cmd->heavy_rx_thld_packets =
261 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
262 } else {
263 cmd->heavy_tx_thld_packets =
264 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
265 cmd->heavy_rx_thld_packets =
266 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
267 }
268 cmd->heavy_tx_thld_percentage =
269 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
270 cmd->heavy_rx_thld_percentage =
271 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
272}
273
189static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, 274static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
190 struct ieee80211_vif *vif, 275 struct ieee80211_vif *vif,
191 struct iwl_mac_power_cmd *cmd) 276 struct iwl_mac_power_cmd *cmd)
@@ -198,8 +283,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
198 bool radar_detect = false; 283 bool radar_detect = false;
199 struct iwl_mvm_vif *mvmvif __maybe_unused = 284 struct iwl_mvm_vif *mvmvif __maybe_unused =
200 iwl_mvm_vif_from_mac80211(vif); 285 iwl_mvm_vif_from_mac80211(vif);
201 enum ieee80211_ac_numbers ac; 286 bool allow_uapsd = true;
202 bool tid_found = false;
203 287
204 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 288 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
205 mvmvif->color)); 289 mvmvif->color));
@@ -217,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
217 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 301 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
218 cmd->keep_alive_seconds = cpu_to_le16(keep_alive); 302 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
219 303
220 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 304 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
305 mvm->ps_prevented)
221 return; 306 return;
222 307
223 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 308 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
@@ -227,7 +312,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
227 mvmvif->dbgfs_pm.disable_power_off) 312 mvmvif->dbgfs_pm.disable_power_off)
228 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); 313 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
229#endif 314#endif
230 if (!vif->bss_conf.ps) 315 if (!vif->bss_conf.ps || mvmvif->pm_prevented)
231 return; 316 return;
232 317
233 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 318 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -269,81 +354,24 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
269 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); 354 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
270 } 355 }
271 356
272 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { 357 if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
273 if (!mvmvif->queue_params[ac].uapsd) 358 ETH_ALEN))
274 continue; 359 allow_uapsd = false;
275
276 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
277 cmd->flags |=
278 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
279
280 cmd->uapsd_ac_flags |= BIT(ac);
281 360
282 /* QNDP TID - the highest TID with no admission control */ 361 if (vif->p2p &&
283 if (!tid_found && !mvmvif->queue_params[ac].acm) { 362 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
284 tid_found = true; 363 allow_uapsd = false;
285 switch (ac) { 364 /*
286 case IEEE80211_AC_VO: 365 * Avoid using uAPSD if P2P client is associated to GO that uses
287 cmd->qndp_tid = 6; 366 * opportunistic power save. This is due to current FW limitation.
288 break; 367 */
289 case IEEE80211_AC_VI: 368 if (vif->p2p &&
290 cmd->qndp_tid = 5; 369 vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
291 break; 370 IEEE80211_P2P_OPPPS_ENABLE_BIT)
292 case IEEE80211_AC_BE: 371 allow_uapsd = false;
293 cmd->qndp_tid = 0;
294 break;
295 case IEEE80211_AC_BK:
296 cmd->qndp_tid = 1;
297 break;
298 }
299 }
300 }
301
302 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
303 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
304 BIT(IEEE80211_AC_VI) |
305 BIT(IEEE80211_AC_BE) |
306 BIT(IEEE80211_AC_BK))) {
307 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
308 cmd->snooze_interval =
309 cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
310 cmd->snooze_window =
311 (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
312 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
313 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
314 }
315
316 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
317
318 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
319 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
320 cmd->rx_data_timeout_uapsd =
321 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
322 cmd->tx_data_timeout_uapsd =
323 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
324 } else {
325 cmd->rx_data_timeout_uapsd =
326 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
327 cmd->tx_data_timeout_uapsd =
328 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
329 }
330 372
331 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { 373 if (allow_uapsd)
332 cmd->heavy_tx_thld_packets = 374 iwl_mvm_power_configure_uapsd(mvm, vif, cmd);
333 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
334 cmd->heavy_rx_thld_packets =
335 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
336 } else {
337 cmd->heavy_tx_thld_packets =
338 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
339 cmd->heavy_rx_thld_packets =
340 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
341 }
342 cmd->heavy_tx_thld_percentage =
343 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
344 cmd->heavy_rx_thld_percentage =
345 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
346 }
347 375
348#ifdef CONFIG_IWLWIFI_DEBUGFS 376#ifdef CONFIG_IWLWIFI_DEBUGFS
349 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) 377 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
@@ -381,6 +409,13 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
381 cmd->flags &= 409 cmd->flags &=
382 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK); 410 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK);
383 } 411 }
412 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_UAPSD_MISBEHAVING) {
413 u16 flag = POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK;
414 if (mvmvif->dbgfs_pm.uapsd_misbehaving)
415 cmd->flags |= cpu_to_le16(flag);
416 else
417 cmd->flags &= cpu_to_le16(flag);
418 }
384#endif /* CONFIG_IWLWIFI_DEBUGFS */ 419#endif /* CONFIG_IWLWIFI_DEBUGFS */
385} 420}
386 421
@@ -391,18 +426,11 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
391 bool ba_enable; 426 bool ba_enable;
392 struct iwl_mac_power_cmd cmd = {}; 427 struct iwl_mac_power_cmd cmd = {};
393 428
394 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 429 if (vif->type != NL80211_IFTYPE_STATION)
395 return 0; 430 return 0;
396 431
397 /* 432 if (vif->p2p &&
398 * TODO: The following vif_count verification is temporary condition. 433 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
399 * Avoid power mode update if more than one interface is currently
400 * active. Remove this condition when FW will support power management
401 * on multiple MACs.
402 */
403 IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
404 mvm->vif_count);
405 if (mvm->vif_count > 1)
406 return 0; 434 return 0;
407 435
408 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 436 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
@@ -446,7 +474,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
446 sizeof(cmd), &cmd); 474 sizeof(cmd), &cmd);
447} 475}
448 476
449static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) 477static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
450{ 478{
451 struct iwl_device_power_cmd cmd = { 479 struct iwl_device_power_cmd cmd = {
452 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), 480 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
@@ -455,7 +483,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
455 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) 483 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
456 return 0; 484 return 0;
457 485
458 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 486 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
487 force_disable)
459 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); 488 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
460 489
461#ifdef CONFIG_IWLWIFI_DEBUGFS 490#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -472,6 +501,78 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
472 &cmd); 501 &cmd);
473} 502}
474 503
504static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
505{
506 return _iwl_mvm_power_update_device(mvm, false);
507}
508
509void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
510{
511 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
512
513 if (memcmp(vif->bss_conf.bssid, mvmvif->uapsd_misbehaving_bssid,
514 ETH_ALEN))
515 memset(mvmvif->uapsd_misbehaving_bssid, 0, ETH_ALEN);
516}
517
518static void iwl_mvm_power_uapsd_misbehav_ap_iterator(void *_data, u8 *mac,
519 struct ieee80211_vif *vif)
520{
521 u8 *ap_sta_id = _data;
522 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
523
524 /* The ap_sta_id is not expected to change during current association
525 * so no explicit protection is needed
526 */
527 if (mvmvif->ap_sta_id == *ap_sta_id)
528 memcpy(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
529 ETH_ALEN);
530}
531
532int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
533 struct iwl_rx_cmd_buffer *rxb,
534 struct iwl_device_cmd *cmd)
535{
536 struct iwl_rx_packet *pkt = rxb_addr(rxb);
537 struct iwl_uapsd_misbehaving_ap_notif *notif = (void *)pkt->data;
538 u8 ap_sta_id = le32_to_cpu(notif->sta_id);
539
540 ieee80211_iterate_active_interfaces_atomic(
541 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
542 iwl_mvm_power_uapsd_misbehav_ap_iterator, &ap_sta_id);
543
544 return 0;
545}
546
547static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
548 struct ieee80211_vif *vif)
549{
550 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
551 struct iwl_mvm *mvm = _data;
552 int ret;
553
554 mvmvif->pm_prevented = (mvm->bound_vif_cnt <= 1) ? false : true;
555
556 ret = iwl_mvm_power_mac_update_mode(mvm, vif);
557 WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n");
558}
559
560static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
561 struct ieee80211_vif *vif,
562 bool assign)
563{
564 if (vif->type == NL80211_IFTYPE_MONITOR) {
565 int ret = _iwl_mvm_power_update_device(mvm, assign);
566 mvm->ps_prevented = assign;
567 WARN_ONCE(ret, "Failed to update power device state\n");
568 }
569
570 ieee80211_iterate_active_interfaces(mvm->hw,
571 IEEE80211_IFACE_ITER_NORMAL,
572 iwl_mvm_power_binding_iterator,
573 mvm);
574}
575
475#ifdef CONFIG_IWLWIFI_DEBUGFS 576#ifdef CONFIG_IWLWIFI_DEBUGFS
476static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, 577static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
477 struct ieee80211_vif *vif, char *buf, 578 struct ieee80211_vif *vif, char *buf,
@@ -494,70 +595,58 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
494 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 595 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
495 le16_to_cpu(cmd.keep_alive_seconds)); 596 le16_to_cpu(cmd.keep_alive_seconds));
496 597
497 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { 598 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)))
498 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", 599 return pos;
499 (cmd.flags & 600
500 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 601 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
501 1 : 0); 602 (cmd.flags &
502 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", 603 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 1 : 0);
503 cmd.skip_dtim_periods); 604 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
504 if (!(cmd.flags & 605 cmd.skip_dtim_periods);
505 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { 606 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
506 pos += scnprintf(buf+pos, bufsz-pos, 607 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
507 "rx_data_timeout = %d\n", 608 le32_to_cpu(cmd.rx_data_timeout));
508 le32_to_cpu(cmd.rx_data_timeout)); 609 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
509 pos += scnprintf(buf+pos, bufsz-pos, 610 le32_to_cpu(cmd.tx_data_timeout));
510 "tx_data_timeout = %d\n",
511 le32_to_cpu(cmd.tx_data_timeout));
512 }
513 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
514 pos += scnprintf(buf+pos, bufsz-pos,
515 "lprx_rssi_threshold = %d\n",
516 cmd.lprx_rssi_threshold);
517 if (cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
518 pos +=
519 scnprintf(buf+pos, bufsz-pos,
520 "rx_data_timeout_uapsd = %d\n",
521 le32_to_cpu(cmd.rx_data_timeout_uapsd));
522 pos +=
523 scnprintf(buf+pos, bufsz-pos,
524 "tx_data_timeout_uapsd = %d\n",
525 le32_to_cpu(cmd.tx_data_timeout_uapsd));
526 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n",
527 cmd.qndp_tid);
528 pos += scnprintf(buf+pos, bufsz-pos,
529 "uapsd_ac_flags = 0x%x\n",
530 cmd.uapsd_ac_flags);
531 pos += scnprintf(buf+pos, bufsz-pos,
532 "uapsd_max_sp = %d\n",
533 cmd.uapsd_max_sp);
534 pos += scnprintf(buf+pos, bufsz-pos,
535 "heavy_tx_thld_packets = %d\n",
536 cmd.heavy_tx_thld_packets);
537 pos += scnprintf(buf+pos, bufsz-pos,
538 "heavy_rx_thld_packets = %d\n",
539 cmd.heavy_rx_thld_packets);
540 pos += scnprintf(buf+pos, bufsz-pos,
541 "heavy_tx_thld_percentage = %d\n",
542 cmd.heavy_tx_thld_percentage);
543 pos += scnprintf(buf+pos, bufsz-pos,
544 "heavy_rx_thld_percentage = %d\n",
545 cmd.heavy_rx_thld_percentage);
546 pos +=
547 scnprintf(buf+pos, bufsz-pos, "snooze_enable = %d\n",
548 (cmd.flags &
549 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) ?
550 1 : 0);
551 }
552 if (cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
553 pos += scnprintf(buf+pos, bufsz-pos,
554 "snooze_interval = %d\n",
555 cmd.snooze_interval);
556 pos += scnprintf(buf+pos, bufsz-pos,
557 "snooze_window = %d\n",
558 cmd.snooze_window);
559 }
560 } 611 }
612 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
613 pos += scnprintf(buf+pos, bufsz-pos,
614 "lprx_rssi_threshold = %d\n",
615 cmd.lprx_rssi_threshold);
616
617 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
618 return pos;
619
620 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout_uapsd = %d\n",
621 le32_to_cpu(cmd.rx_data_timeout_uapsd));
622 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout_uapsd = %d\n",
623 le32_to_cpu(cmd.tx_data_timeout_uapsd));
624 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n", cmd.qndp_tid);
625 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_ac_flags = 0x%x\n",
626 cmd.uapsd_ac_flags);
627 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_max_sp = %d\n",
628 cmd.uapsd_max_sp);
629 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_packets = %d\n",
630 cmd.heavy_tx_thld_packets);
631 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_packets = %d\n",
632 cmd.heavy_rx_thld_packets);
633 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_percentage = %d\n",
634 cmd.heavy_tx_thld_percentage);
635 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_percentage = %d\n",
636 cmd.heavy_rx_thld_percentage);
637 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_misbehaving_enable = %d\n",
638 (cmd.flags &
639 cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK)) ?
640 1 : 0);
641
642 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)))
643 return pos;
644
645 pos += scnprintf(buf+pos, bufsz-pos, "snooze_interval = %d\n",
646 cmd.snooze_interval);
647 pos += scnprintf(buf+pos, bufsz-pos, "snooze_window = %d\n",
648 cmd.snooze_window);
649
561 return pos; 650 return pos;
562} 651}
563 652
@@ -654,6 +743,7 @@ const struct iwl_mvm_power_ops pm_mac_ops = {
654 .power_update_mode = iwl_mvm_power_mac_update_mode, 743 .power_update_mode = iwl_mvm_power_mac_update_mode,
655 .power_update_device_mode = iwl_mvm_power_update_device, 744 .power_update_device_mode = iwl_mvm_power_update_device,
656 .power_disable = iwl_mvm_power_mac_disable, 745 .power_disable = iwl_mvm_power_mac_disable,
746 .power_update_binding = _iwl_mvm_power_update_binding,
657#ifdef CONFIG_IWLWIFI_DEBUGFS 747#ifdef CONFIG_IWLWIFI_DEBUGFS
658 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, 748 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
659#endif 749#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
index 2ce79bad5845..ef712ae5bc62 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 17e2bc827f9a..ce5db6c4ef7e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -217,8 +217,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
217 } else { 217 } else {
218 cmd.quotas[idx].quota = 218 cmd.quotas[idx].quota =
219 cpu_to_le32(quota * data.n_interfaces[i]); 219 cpu_to_le32(quota * data.n_interfaces[i]);
220 cmd.quotas[idx].max_duration = 220 cmd.quotas[idx].max_duration = cpu_to_le32(0);
221 cpu_to_le32(IWL_MVM_MAX_QUOTA);
222 } 221 }
223 idx++; 222 idx++;
224 } 223 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index a0b4cc8d9c3b..6abf74e1351f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -24,7 +24,6 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h> 27#include <linux/skbuff.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <net/mac80211.h> 29#include <net/mac80211.h>
@@ -42,33 +41,37 @@
42 41
43#define RS_NAME "iwl-mvm-rs" 42#define RS_NAME "iwl-mvm-rs"
44 43
45#define NUM_TRY_BEFORE_ANT_TOGGLE 1 44#define NUM_TRY_BEFORE_ANT_TOGGLE 1
46#define IWL_NUMBER_TRY 1 45#define RS_LEGACY_RETRIES_PER_RATE 1
47#define IWL_HT_NUMBER_TRY 3 46#define RS_HT_VHT_RETRIES_PER_RATE 2
47#define RS_HT_VHT_RETRIES_PER_RATE_TW 1
48#define RS_INITIAL_MIMO_NUM_RATES 3
49#define RS_INITIAL_SISO_NUM_RATES 3
50#define RS_INITIAL_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
51#define RS_SECONDARY_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
52#define RS_SECONDARY_SISO_NUM_RATES 3
53#define RS_SECONDARY_SISO_RETRIES 1
48 54
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ 55#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ 56#define IWL_RATE_MIN_FAILURE_TH 3 /* min failures to calc tpt */
51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ 57#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52 58
53/* max allowed rate miss before sync LQ cmd */ 59/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15 60#define IWL_MISSED_RATE_MAX 15
55/* max time to accum history 2 seconds */ 61#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ) 62
57 63
58static u8 rs_ht_to_legacy[] = { 64static u8 rs_ht_to_legacy[] = {
59 [IWL_RATE_1M_INDEX] = IWL_RATE_6M_INDEX, 65 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
60 [IWL_RATE_2M_INDEX] = IWL_RATE_6M_INDEX, 66 [IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX,
61 [IWL_RATE_5M_INDEX] = IWL_RATE_6M_INDEX, 67 [IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX,
62 [IWL_RATE_11M_INDEX] = IWL_RATE_6M_INDEX, 68 [IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX,
63 [IWL_RATE_6M_INDEX] = IWL_RATE_6M_INDEX, 69 [IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX,
64 [IWL_RATE_9M_INDEX] = IWL_RATE_6M_INDEX, 70 [IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX,
65 [IWL_RATE_12M_INDEX] = IWL_RATE_9M_INDEX, 71 [IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX,
66 [IWL_RATE_18M_INDEX] = IWL_RATE_12M_INDEX, 72 [IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX,
67 [IWL_RATE_24M_INDEX] = IWL_RATE_18M_INDEX, 73 [IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX,
68 [IWL_RATE_36M_INDEX] = IWL_RATE_24M_INDEX, 74 [IWL_RATE_MCS_9_INDEX] = IWL_RATE_54M_INDEX,
69 [IWL_RATE_48M_INDEX] = IWL_RATE_36M_INDEX,
70 [IWL_RATE_54M_INDEX] = IWL_RATE_48M_INDEX,
71 [IWL_RATE_60M_INDEX] = IWL_RATE_54M_INDEX,
72}; 75};
73 76
74static const u8 ant_toggle_lookup[] = { 77static const u8 ant_toggle_lookup[] = {
@@ -126,6 +129,196 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
126 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ 129 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */
127}; 130};
128 131
132enum rs_action {
133 RS_ACTION_STAY = 0,
134 RS_ACTION_DOWNSCALE = -1,
135 RS_ACTION_UPSCALE = 1,
136};
137
138enum rs_column_mode {
139 RS_INVALID = 0,
140 RS_LEGACY,
141 RS_SISO,
142 RS_MIMO2,
143};
144
145#define MAX_NEXT_COLUMNS 5
146#define MAX_COLUMN_CHECKS 3
147
148typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
149 struct ieee80211_sta *sta,
150 struct iwl_scale_tbl_info *tbl);
151
152struct rs_tx_column {
153 enum rs_column_mode mode;
154 u8 ant;
155 bool sgi;
156 enum rs_column next_columns[MAX_NEXT_COLUMNS];
157 allow_column_func_t checks[MAX_COLUMN_CHECKS];
158};
159
160static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
161 struct iwl_scale_tbl_info *tbl)
162{
163 if (!sta->ht_cap.ht_supported)
164 return false;
165
166 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
167 return false;
168
169 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
170 return false;
171
172 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
173 return false;
174
175 return true;
176}
177
178static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
179 struct iwl_scale_tbl_info *tbl)
180{
181 if (!sta->ht_cap.ht_supported)
182 return false;
183
184 return true;
185}
186
187static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
188 struct iwl_scale_tbl_info *tbl)
189{
190 struct rs_rate *rate = &tbl->rate;
191 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
192 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
193
194 if (is_ht20(rate) && (ht_cap->cap &
195 IEEE80211_HT_CAP_SGI_20))
196 return true;
197 if (is_ht40(rate) && (ht_cap->cap &
198 IEEE80211_HT_CAP_SGI_40))
199 return true;
200 if (is_ht80(rate) && (vht_cap->cap &
201 IEEE80211_VHT_CAP_SHORT_GI_80))
202 return true;
203
204 return false;
205}
206
207static const struct rs_tx_column rs_tx_columns[] = {
208 [RS_COLUMN_LEGACY_ANT_A] = {
209 .mode = RS_LEGACY,
210 .ant = ANT_A,
211 .next_columns = {
212 RS_COLUMN_LEGACY_ANT_B,
213 RS_COLUMN_SISO_ANT_A,
214 RS_COLUMN_MIMO2,
215 RS_COLUMN_INVALID,
216 RS_COLUMN_INVALID,
217 },
218 },
219 [RS_COLUMN_LEGACY_ANT_B] = {
220 .mode = RS_LEGACY,
221 .ant = ANT_B,
222 .next_columns = {
223 RS_COLUMN_LEGACY_ANT_A,
224 RS_COLUMN_SISO_ANT_B,
225 RS_COLUMN_MIMO2,
226 RS_COLUMN_INVALID,
227 RS_COLUMN_INVALID,
228 },
229 },
230 [RS_COLUMN_SISO_ANT_A] = {
231 .mode = RS_SISO,
232 .ant = ANT_A,
233 .next_columns = {
234 RS_COLUMN_SISO_ANT_B,
235 RS_COLUMN_MIMO2,
236 RS_COLUMN_SISO_ANT_A_SGI,
237 RS_COLUMN_INVALID,
238 RS_COLUMN_INVALID,
239 },
240 .checks = {
241 rs_siso_allow,
242 },
243 },
244 [RS_COLUMN_SISO_ANT_B] = {
245 .mode = RS_SISO,
246 .ant = ANT_B,
247 .next_columns = {
248 RS_COLUMN_SISO_ANT_A,
249 RS_COLUMN_MIMO2,
250 RS_COLUMN_SISO_ANT_B_SGI,
251 RS_COLUMN_INVALID,
252 RS_COLUMN_INVALID,
253 },
254 .checks = {
255 rs_siso_allow,
256 },
257 },
258 [RS_COLUMN_SISO_ANT_A_SGI] = {
259 .mode = RS_SISO,
260 .ant = ANT_A,
261 .sgi = true,
262 .next_columns = {
263 RS_COLUMN_SISO_ANT_B_SGI,
264 RS_COLUMN_MIMO2_SGI,
265 RS_COLUMN_SISO_ANT_A,
266 RS_COLUMN_INVALID,
267 RS_COLUMN_INVALID,
268 },
269 .checks = {
270 rs_siso_allow,
271 rs_sgi_allow,
272 },
273 },
274 [RS_COLUMN_SISO_ANT_B_SGI] = {
275 .mode = RS_SISO,
276 .ant = ANT_B,
277 .sgi = true,
278 .next_columns = {
279 RS_COLUMN_SISO_ANT_A_SGI,
280 RS_COLUMN_MIMO2_SGI,
281 RS_COLUMN_SISO_ANT_B,
282 RS_COLUMN_INVALID,
283 RS_COLUMN_INVALID,
284 },
285 .checks = {
286 rs_siso_allow,
287 rs_sgi_allow,
288 },
289 },
290 [RS_COLUMN_MIMO2] = {
291 .mode = RS_MIMO2,
292 .ant = ANT_AB,
293 .next_columns = {
294 RS_COLUMN_SISO_ANT_A,
295 RS_COLUMN_MIMO2_SGI,
296 RS_COLUMN_INVALID,
297 RS_COLUMN_INVALID,
298 RS_COLUMN_INVALID,
299 },
300 .checks = {
301 rs_mimo_allow,
302 },
303 },
304 [RS_COLUMN_MIMO2_SGI] = {
305 .mode = RS_MIMO2,
306 .ant = ANT_AB,
307 .sgi = true,
308 .next_columns = {
309 RS_COLUMN_SISO_ANT_A_SGI,
310 RS_COLUMN_MIMO2,
311 RS_COLUMN_INVALID,
312 RS_COLUMN_INVALID,
313 RS_COLUMN_INVALID,
314 },
315 .checks = {
316 rs_mimo_allow,
317 rs_sgi_allow,
318 },
319 },
320};
321
129static inline u8 rs_extract_rate(u32 rate_n_flags) 322static inline u8 rs_extract_rate(u32 rate_n_flags)
130{ 323{
131 /* also works for HT because bits 7:6 are zero there */ 324 /* also works for HT because bits 7:6 are zero there */
@@ -163,28 +356,19 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
163 return idx; 356 return idx;
164 } 357 }
165 358
166 return -1; 359 return IWL_RATE_INVALID;
167} 360}
168 361
169static void rs_rate_scale_perform(struct iwl_mvm *mvm, 362static void rs_rate_scale_perform(struct iwl_mvm *mvm,
170 struct sk_buff *skb, 363 struct sk_buff *skb,
171 struct ieee80211_sta *sta, 364 struct ieee80211_sta *sta,
172 struct iwl_lq_sta *lq_sta); 365 struct iwl_lq_sta *lq_sta);
173static void rs_fill_link_cmd(struct iwl_mvm *mvm, 366static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
174 struct ieee80211_sta *sta, 367 struct ieee80211_sta *sta,
175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 368 struct iwl_lq_sta *lq_sta,
369 const struct rs_rate *initial_rate);
176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); 370static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
177 371
178
179#ifdef CONFIG_MAC80211_DEBUGFS
180static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
181 u32 *rate_n_flags);
182#else
183static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
184 u32 *rate_n_flags)
185{}
186#endif
187
188/** 372/**
189 * The following tables contain the expected throughput metrics for all rates 373 * The following tables contain the expected throughput metrics for all rates
190 * 374 *
@@ -264,6 +448,52 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
264 448
265#define MCS_INDEX_PER_STREAM (8) 449#define MCS_INDEX_PER_STREAM (8)
266 450
451static const char *rs_pretty_ant(u8 ant)
452{
453 static const char * const ant_name[] = {
454 [ANT_NONE] = "None",
455 [ANT_A] = "A",
456 [ANT_B] = "B",
457 [ANT_AB] = "AB",
458 [ANT_C] = "C",
459 [ANT_AC] = "AC",
460 [ANT_BC] = "BC",
461 [ANT_ABC] = "ABC",
462 };
463
464 if (ant > ANT_ABC)
465 return "UNKNOWN";
466
467 return ant_name[ant];
468}
469
470static const char *rs_pretty_lq_type(enum iwl_table_type type)
471{
472 static const char * const lq_types[] = {
473 [LQ_NONE] = "NONE",
474 [LQ_LEGACY_A] = "LEGACY_A",
475 [LQ_LEGACY_G] = "LEGACY_G",
476 [LQ_HT_SISO] = "HT SISO",
477 [LQ_HT_MIMO2] = "HT MIMO",
478 [LQ_VHT_SISO] = "VHT SISO",
479 [LQ_VHT_MIMO2] = "VHT MIMO",
480 };
481
482 if (type < LQ_NONE || type >= LQ_MAX)
483 return "UNKNOWN";
484
485 return lq_types[type];
486}
487
488static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
489 const char *prefix)
490{
491 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n",
492 prefix, rs_pretty_lq_type(rate->type),
493 rate->index, rs_pretty_ant(rate->ant),
494 rate->bw, rate->sgi);
495}
496
267static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 497static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
268{ 498{
269 window->data = 0; 499 window->data = 0;
@@ -271,7 +501,6 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
271 window->success_ratio = IWL_INVALID_VALUE; 501 window->success_ratio = IWL_INVALID_VALUE;
272 window->counter = 0; 502 window->counter = 0;
273 window->average_tpt = IWL_INVALID_VALUE; 503 window->average_tpt = IWL_INVALID_VALUE;
274 window->stamp = 0;
275} 504}
276 505
277static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) 506static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
@@ -279,30 +508,6 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
279 return (ant_type & valid_antenna) == ant_type; 508 return (ant_type & valid_antenna) == ant_type;
280} 509}
281 510
282#ifdef CONFIG_MAC80211_DEBUGFS
283/**
284 * Program the device to use fixed rate for frame transmit
285 * This is for debugging/testing only
286 * once the device start use fixed rate, we need to reload the module
287 * to being back the normal operation.
288 */
289static void rs_program_fix_rate(struct iwl_mvm *mvm,
290 struct iwl_lq_sta *lq_sta)
291{
292 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
293 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
294 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
295
296 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
297 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
298
299 if (lq_sta->dbg_fixed_rate) {
300 rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate);
301 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
302 }
303}
304#endif
305
306static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, 511static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
307 struct iwl_lq_sta *lq_data, u8 tid, 512 struct iwl_lq_sta *lq_data, u8 tid,
308 struct ieee80211_sta *sta) 513 struct ieee80211_sta *sta)
@@ -428,192 +633,168 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
428 else 633 else
429 window->average_tpt = IWL_INVALID_VALUE; 634 window->average_tpt = IWL_INVALID_VALUE;
430 635
431 /* Tag this window as having been updated */
432 window->stamp = jiffies;
433
434 return 0; 636 return 0;
435} 637}
436 638
437/* 639/* Convert rs_rate object into ucode rate bitmask */
438 * Fill uCode API rate_n_flags field, based on "search" or "active" table. 640static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
439 */ 641 struct rs_rate *rate)
440/* FIXME:RS:remove this function and put the flags statically in the table */
441static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
442 struct iwl_scale_tbl_info *tbl, int index)
443{ 642{
444 u32 rate_n_flags = 0; 643 u32 ucode_rate = 0;
644 int index = rate->index;
445 645
446 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 646 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &
447 RATE_MCS_ANT_ABC_MSK); 647 RATE_MCS_ANT_ABC_MSK);
448 648
449 if (is_legacy(tbl->lq_type)) { 649 if (is_legacy(rate)) {
450 rate_n_flags |= iwl_rates[index].plcp; 650 ucode_rate |= iwl_rates[index].plcp;
451 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 651 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
452 rate_n_flags |= RATE_MCS_CCK_MSK; 652 ucode_rate |= RATE_MCS_CCK_MSK;
453 return rate_n_flags; 653 return ucode_rate;
454 } 654 }
455 655
456 if (is_ht(tbl->lq_type)) { 656 if (is_ht(rate)) {
457 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { 657 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {
458 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); 658 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
459 index = IWL_LAST_HT_RATE; 659 index = IWL_LAST_HT_RATE;
460 } 660 }
461 rate_n_flags |= RATE_MCS_HT_MSK; 661 ucode_rate |= RATE_MCS_HT_MSK;
462 662
463 if (is_ht_siso(tbl->lq_type)) 663 if (is_ht_siso(rate))
464 rate_n_flags |= iwl_rates[index].plcp_ht_siso; 664 ucode_rate |= iwl_rates[index].plcp_ht_siso;
465 else if (is_ht_mimo2(tbl->lq_type)) 665 else if (is_ht_mimo2(rate))
466 rate_n_flags |= iwl_rates[index].plcp_ht_mimo2; 666 ucode_rate |= iwl_rates[index].plcp_ht_mimo2;
467 else 667 else
468 WARN_ON_ONCE(1); 668 WARN_ON_ONCE(1);
469 } else if (is_vht(tbl->lq_type)) { 669 } else if (is_vht(rate)) {
470 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { 670 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {
471 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); 671 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
472 index = IWL_LAST_VHT_RATE; 672 index = IWL_LAST_VHT_RATE;
473 } 673 }
474 rate_n_flags |= RATE_MCS_VHT_MSK; 674 ucode_rate |= RATE_MCS_VHT_MSK;
475 if (is_vht_siso(tbl->lq_type)) 675 if (is_vht_siso(rate))
476 rate_n_flags |= iwl_rates[index].plcp_vht_siso; 676 ucode_rate |= iwl_rates[index].plcp_vht_siso;
477 else if (is_vht_mimo2(tbl->lq_type)) 677 else if (is_vht_mimo2(rate))
478 rate_n_flags |= iwl_rates[index].plcp_vht_mimo2; 678 ucode_rate |= iwl_rates[index].plcp_vht_mimo2;
479 else 679 else
480 WARN_ON_ONCE(1); 680 WARN_ON_ONCE(1);
481 681
482 } else { 682 } else {
483 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 683 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type);
484 } 684 }
485 685
486 rate_n_flags |= tbl->bw; 686 ucode_rate |= rate->bw;
487 if (tbl->is_SGI) 687 if (rate->sgi)
488 rate_n_flags |= RATE_MCS_SGI_MSK; 688 ucode_rate |= RATE_MCS_SGI_MSK;
489 689
490 return rate_n_flags; 690 return ucode_rate;
491} 691}
492 692
493/* 693/* Convert a ucode rate into an rs_rate object */
494 * Interpret uCode API's rate_n_flags format, 694static int rs_rate_from_ucode_rate(const u32 ucode_rate,
495 * fill "search" or "active" tx mode table. 695 enum ieee80211_band band,
496 */ 696 struct rs_rate *rate)
497static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
498 enum ieee80211_band band,
499 struct iwl_scale_tbl_info *tbl,
500 int *rate_idx)
501{ 697{
502 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); 698 u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK;
503 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 699 u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);
504 u8 nss; 700 u8 nss;
505 701
506 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); 702 memset(rate, 0, sizeof(*rate));
507 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 703 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);
508 704
509 if (*rate_idx == IWL_RATE_INVALID) { 705 if (rate->index == IWL_RATE_INVALID)
510 *rate_idx = -1;
511 return -EINVAL; 706 return -EINVAL;
512 } 707
513 tbl->is_SGI = 0; /* default legacy setup */ 708 rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
514 tbl->bw = 0;
515 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
516 tbl->lq_type = LQ_NONE;
517 tbl->max_search = IWL_MAX_SEARCH;
518 709
519 /* Legacy */ 710 /* Legacy */
520 if (!(rate_n_flags & RATE_MCS_HT_MSK) && 711 if (!(ucode_rate & RATE_MCS_HT_MSK) &&
521 !(rate_n_flags & RATE_MCS_VHT_MSK)) { 712 !(ucode_rate & RATE_MCS_VHT_MSK)) {
522 if (num_of_ant == 1) { 713 if (num_of_ant == 1) {
523 if (band == IEEE80211_BAND_5GHZ) 714 if (band == IEEE80211_BAND_5GHZ)
524 tbl->lq_type = LQ_LEGACY_A; 715 rate->type = LQ_LEGACY_A;
525 else 716 else
526 tbl->lq_type = LQ_LEGACY_G; 717 rate->type = LQ_LEGACY_G;
527 } 718 }
528 719
529 return 0; 720 return 0;
530 } 721 }
531 722
532 /* HT or VHT */ 723 /* HT or VHT */
533 if (rate_n_flags & RATE_MCS_SGI_MSK) 724 if (ucode_rate & RATE_MCS_SGI_MSK)
534 tbl->is_SGI = 1; 725 rate->sgi = true;
535 726
536 tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 727 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
537 728
538 if (rate_n_flags & RATE_MCS_HT_MSK) { 729 if (ucode_rate & RATE_MCS_HT_MSK) {
539 nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> 730 nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >>
540 RATE_HT_MCS_NSS_POS) + 1; 731 RATE_HT_MCS_NSS_POS) + 1;
541 732
542 if (nss == 1) { 733 if (nss == 1) {
543 tbl->lq_type = LQ_HT_SISO; 734 rate->type = LQ_HT_SISO;
544 WARN_ON_ONCE(num_of_ant != 1); 735 WARN_ON_ONCE(num_of_ant != 1);
545 } else if (nss == 2) { 736 } else if (nss == 2) {
546 tbl->lq_type = LQ_HT_MIMO2; 737 rate->type = LQ_HT_MIMO2;
547 WARN_ON_ONCE(num_of_ant != 2); 738 WARN_ON_ONCE(num_of_ant != 2);
548 } else { 739 } else {
549 WARN_ON_ONCE(1); 740 WARN_ON_ONCE(1);
550 } 741 }
551 } else if (rate_n_flags & RATE_MCS_VHT_MSK) { 742 } else if (ucode_rate & RATE_MCS_VHT_MSK) {
552 nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 743 nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
553 RATE_VHT_MCS_NSS_POS) + 1; 744 RATE_VHT_MCS_NSS_POS) + 1;
554 745
555 if (nss == 1) { 746 if (nss == 1) {
556 tbl->lq_type = LQ_VHT_SISO; 747 rate->type = LQ_VHT_SISO;
557 WARN_ON_ONCE(num_of_ant != 1); 748 WARN_ON_ONCE(num_of_ant != 1);
558 } else if (nss == 2) { 749 } else if (nss == 2) {
559 tbl->lq_type = LQ_VHT_MIMO2; 750 rate->type = LQ_VHT_MIMO2;
560 WARN_ON_ONCE(num_of_ant != 2); 751 WARN_ON_ONCE(num_of_ant != 2);
561 } else { 752 } else {
562 WARN_ON_ONCE(1); 753 WARN_ON_ONCE(1);
563 } 754 }
564 } 755 }
565 756
566 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160); 757 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_160);
567 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 && 758 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
568 !is_vht(tbl->lq_type)); 759 !is_vht(rate));
569 760
570 return 0; 761 return 0;
571} 762}
572 763
573/* switch to another antenna/antennas and return 1 */ 764/* switch to another antenna/antennas and return 1 */
574/* if no other valid antenna found, return 0 */ 765/* if no other valid antenna found, return 0 */
575static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, 766static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)
576 struct iwl_scale_tbl_info *tbl)
577{ 767{
578 u8 new_ant_type; 768 u8 new_ant_type;
579 769
580 if (!tbl->ant_type || tbl->ant_type > ANT_ABC) 770 if (!rate->ant || rate->ant > ANT_ABC)
581 return 0; 771 return 0;
582 772
583 if (!rs_is_valid_ant(valid_ant, tbl->ant_type)) 773 if (!rs_is_valid_ant(valid_ant, rate->ant))
584 return 0; 774 return 0;
585 775
586 new_ant_type = ant_toggle_lookup[tbl->ant_type]; 776 new_ant_type = ant_toggle_lookup[rate->ant];
587 777
588 while ((new_ant_type != tbl->ant_type) && 778 while ((new_ant_type != rate->ant) &&
589 !rs_is_valid_ant(valid_ant, new_ant_type)) 779 !rs_is_valid_ant(valid_ant, new_ant_type))
590 new_ant_type = ant_toggle_lookup[new_ant_type]; 780 new_ant_type = ant_toggle_lookup[new_ant_type];
591 781
592 if (new_ant_type == tbl->ant_type) 782 if (new_ant_type == rate->ant)
593 return 0; 783 return 0;
594 784
595 tbl->ant_type = new_ant_type; 785 rate->ant = new_ant_type;
596 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; 786
597 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
598 return 1; 787 return 1;
599} 788}
600 789
601/**
602 * rs_get_supported_rates - get the available rates
603 *
604 * if management frame or broadcast frame only return
605 * basic available rates.
606 *
607 */
608static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, 790static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
609 struct ieee80211_hdr *hdr, 791 struct rs_rate *rate)
610 enum iwl_table_type rate_type)
611{ 792{
612 if (is_legacy(rate_type)) 793 if (is_legacy(rate))
613 return lq_sta->active_legacy_rate; 794 return lq_sta->active_legacy_rate;
614 else if (is_siso(rate_type)) 795 else if (is_siso(rate))
615 return lq_sta->active_siso_rate; 796 return lq_sta->active_siso_rate;
616 else if (is_mimo2(rate_type)) 797 else if (is_mimo2(rate))
617 return lq_sta->active_mimo2_rate; 798 return lq_sta->active_mimo2_rate;
618 799
619 WARN_ON_ONCE(1); 800 WARN_ON_ONCE(1);
@@ -628,7 +809,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
628 809
629 /* 802.11A or ht walks to the next literal adjacent rate in 810 /* 802.11A or ht walks to the next literal adjacent rate in
630 * the rate table */ 811 * the rate table */
631 if (is_a_band(rate_type) || !is_legacy(rate_type)) { 812 if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) {
632 int i; 813 int i;
633 u32 mask; 814 u32 mask;
634 815
@@ -676,73 +857,80 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
676 return (high << 8) | low; 857 return (high << 8) | low;
677} 858}
678 859
679static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, 860static inline bool rs_rate_supported(struct iwl_lq_sta *lq_sta,
680 struct iwl_scale_tbl_info *tbl, 861 struct rs_rate *rate)
681 u8 scale_index, u8 ht_possible)
682{ 862{
683 s32 low; 863 return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate);
684 u16 rate_mask; 864}
865
866/* Get the next supported lower rate in the current column.
867 * Return true if bottom rate in the current column was reached
868 */
869static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
870 struct rs_rate *rate)
871{
872 u8 low;
685 u16 high_low; 873 u16 high_low;
686 u8 switch_to_legacy = 0; 874 u16 rate_mask;
687 struct iwl_mvm *mvm = lq_sta->drv; 875 struct iwl_mvm *mvm = lq_sta->drv;
688 876
689 /* check if we need to switch from HT to legacy rates. 877 rate_mask = rs_get_supported_rates(lq_sta, rate);
690 * assumption is that mandatory rates (1Mbps or 6Mbps) 878 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask,
691 * are always supported (spec demand) */ 879 rate->type);
692 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { 880 low = high_low & 0xff;
693 switch_to_legacy = 1;
694 scale_index = rs_ht_to_legacy[scale_index];
695 if (lq_sta->band == IEEE80211_BAND_5GHZ)
696 tbl->lq_type = LQ_LEGACY_A;
697 else
698 tbl->lq_type = LQ_LEGACY_G;
699 881
700 if (num_of_ant(tbl->ant_type) > 1) 882 /* Bottom rate of column reached */
701 tbl->ant_type = 883 if (low == IWL_RATE_INVALID)
702 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 884 return true;
703 885
704 tbl->bw = 0; 886 rate->index = low;
705 tbl->is_SGI = 0; 887 return false;
706 tbl->max_search = IWL_MAX_SEARCH; 888}
707 }
708 889
709 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); 890/* Get the next rate to use following a column downgrade */
891static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
892 struct rs_rate *rate)
893{
894 struct iwl_mvm *mvm = lq_sta->drv;
710 895
711 /* Mask with station rate restriction */ 896 if (is_legacy(rate)) {
712 if (is_legacy(tbl->lq_type)) { 897 /* No column to downgrade from Legacy */
713 /* supp_rates has no CCK bits in A mode */ 898 return;
899 } else if (is_siso(rate)) {
900 /* Downgrade to Legacy if we were in SISO */
714 if (lq_sta->band == IEEE80211_BAND_5GHZ) 901 if (lq_sta->band == IEEE80211_BAND_5GHZ)
715 rate_mask = (u16)(rate_mask & 902 rate->type = LQ_LEGACY_A;
716 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
717 else 903 else
718 rate_mask = (u16)(rate_mask & lq_sta->supp_rates); 904 rate->type = LQ_LEGACY_G;
719 }
720 905
721 /* If we switched from HT to legacy, check current rate */ 906 rate->bw = RATE_MCS_CHAN_WIDTH_20;
722 if (switch_to_legacy && (rate_mask & (1 << scale_index))) { 907
723 low = scale_index; 908 WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX &&
724 goto out; 909 rate->index > IWL_RATE_MCS_9_INDEX);
910
911 rate->index = rs_ht_to_legacy[rate->index];
912 } else {
913 /* Downgrade to SISO with same MCS if in MIMO */
914 rate->type = is_vht_mimo2(rate) ?
915 LQ_VHT_SISO : LQ_HT_SISO;
725 } 916 }
726 917
727 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
728 tbl->lq_type);
729 low = high_low & 0xff;
730 918
731 if (low == IWL_RATE_INVALID) 919 if (num_of_ant(rate->ant) > 1)
732 low = scale_index; 920 rate->ant = first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
733 921
734out: 922 /* Relevant in both switching to SISO or Legacy */
735 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low); 923 rate->sgi = false;
924
925 if (!rs_rate_supported(lq_sta, rate))
926 rs_get_lower_rate_in_column(lq_sta, rate);
736} 927}
737 928
738/* 929/* Simple function to compare two rate scale table types */
739 * Simple function to compare two rate scale table types 930static inline bool rs_rate_match(struct rs_rate *a,
740 */ 931 struct rs_rate *b)
741static bool table_type_matches(struct iwl_scale_tbl_info *a,
742 struct iwl_scale_tbl_info *b)
743{ 932{
744 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 933 return (a->type == b->type) && (a->ant == b->ant) && (a->sgi == b->sgi);
745 (a->is_SGI == b->is_SGI);
746} 934}
747 935
748static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) 936static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
@@ -766,7 +954,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
766{ 954{
767 int legacy_success; 955 int legacy_success;
768 int retries; 956 int retries;
769 int rs_index, mac_index, i; 957 int mac_index, i;
770 struct iwl_lq_sta *lq_sta = priv_sta; 958 struct iwl_lq_sta *lq_sta = priv_sta;
771 struct iwl_lq_cmd *table; 959 struct iwl_lq_cmd *table;
772 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 960 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -774,13 +962,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
774 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 962 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
775 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 963 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
776 enum mac80211_rate_control_flags mac_flags; 964 enum mac80211_rate_control_flags mac_flags;
777 u32 tx_rate; 965 u32 ucode_rate;
778 struct iwl_scale_tbl_info tbl_type; 966 struct rs_rate rate;
779 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 967 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
780 968
781 IWL_DEBUG_RATE_LIMIT(mvm,
782 "get frame ack response, update rate scale window\n");
783
784 /* Treat uninitialized rate scaling data same as non-existing. */ 969 /* Treat uninitialized rate scaling data same as non-existing. */
785 if (!lq_sta) { 970 if (!lq_sta) {
786 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n"); 971 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
@@ -808,10 +993,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
808 * to a new "search" mode (which might become the new "active" mode). 993 * to a new "search" mode (which might become the new "active" mode).
809 */ 994 */
810 table = &lq_sta->lq; 995 table = &lq_sta->lq;
811 tx_rate = le32_to_cpu(table->rs_table[0]); 996 ucode_rate = le32_to_cpu(table->rs_table[0]);
812 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index); 997 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
813 if (info->band == IEEE80211_BAND_5GHZ) 998 if (info->band == IEEE80211_BAND_5GHZ)
814 rs_index -= IWL_FIRST_OFDM_RATE; 999 rate.index -= IWL_FIRST_OFDM_RATE;
815 mac_flags = info->status.rates[0].flags; 1000 mac_flags = info->status.rates[0].flags;
816 mac_index = info->status.rates[0].idx; 1001 mac_index = info->status.rates[0].idx;
817 /* For HT packets, map MCS to PLCP */ 1002 /* For HT packets, map MCS to PLCP */
@@ -834,19 +1019,19 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
834 1019
835 /* Here we actually compare this rate to the latest LQ command */ 1020 /* Here we actually compare this rate to the latest LQ command */
836 if ((mac_index < 0) || 1021 if ((mac_index < 0) ||
837 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 1022 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
838 (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) || 1023 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
839 (tbl_type.ant_type != info->status.antenna) || 1024 (rate.ant != info->status.antenna) ||
840 (!!(tx_rate & RATE_MCS_HT_MSK) != 1025 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
841 !!(mac_flags & IEEE80211_TX_RC_MCS)) || 1026 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
842 (!!(tx_rate & RATE_MCS_VHT_MSK) != 1027 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
843 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) || 1028 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
844 (!!(tx_rate & RATE_HT_MCS_GF_MSK) != 1029 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
845 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 1030 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
846 (rs_index != mac_index)) { 1031 (rate.index != mac_index)) {
847 IWL_DEBUG_RATE(mvm, 1032 IWL_DEBUG_RATE(mvm,
848 "initial rate %d does not match %d (0x%x)\n", 1033 "initial rate %d does not match %d (0x%x)\n",
849 mac_index, rs_index, tx_rate); 1034 mac_index, rate.index, ucode_rate);
850 /* 1035 /*
851 * Since rates mis-match, the last LQ command may have failed. 1036 * Since rates mis-match, the last LQ command may have failed.
852 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 1037 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -855,7 +1040,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
855 lq_sta->missed_rate_counter++; 1040 lq_sta->missed_rate_counter++;
856 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 1041 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
857 lq_sta->missed_rate_counter = 0; 1042 lq_sta->missed_rate_counter = 0;
858 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 1043 IWL_DEBUG_RATE(mvm,
1044 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
1045 lq_sta->rs_state);
1046 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
859 } 1047 }
860 /* Regardless, ignore this status info for outdated rate */ 1048 /* Regardless, ignore this status info for outdated rate */
861 return; 1049 return;
@@ -864,28 +1052,23 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
864 lq_sta->missed_rate_counter = 0; 1052 lq_sta->missed_rate_counter = 0;
865 1053
866 /* Figure out if rate scale algorithm is in active or search table */ 1054 /* Figure out if rate scale algorithm is in active or search table */
867 if (table_type_matches(&tbl_type, 1055 if (rs_rate_match(&rate,
868 &(lq_sta->lq_info[lq_sta->active_tbl]))) { 1056 &(lq_sta->lq_info[lq_sta->active_tbl].rate))) {
869 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1057 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
870 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1058 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
871 } else if (table_type_matches( 1059 } else if (rs_rate_match(&rate,
872 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) { 1060 &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) {
873 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1061 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
874 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1062 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
875 } else { 1063 } else {
876 IWL_DEBUG_RATE(mvm, 1064 IWL_DEBUG_RATE(mvm,
877 "Neither active nor search matches tx rate\n"); 1065 "Neither active nor search matches tx rate\n");
878 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1066 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
879 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n", 1067 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
880 tmp_tbl->lq_type, tmp_tbl->ant_type,
881 tmp_tbl->is_SGI);
882 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1068 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
883 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n", 1069 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
884 tmp_tbl->lq_type, tmp_tbl->ant_type, 1070 rs_dump_rate(mvm, &rate, "ACTUAL");
885 tmp_tbl->is_SGI); 1071
886 IWL_DEBUG_RATE(mvm, "actual- lq:%x, ant:%x, SGI:%d\n",
887 tbl_type.lq_type, tbl_type.ant_type,
888 tbl_type.is_SGI);
889 /* 1072 /*
890 * no matching table found, let's by-pass the data collection 1073 * no matching table found, let's by-pass the data collection
891 * and continue to perform rate scale to find the rate table 1074 * and continue to perform rate scale to find the rate table
@@ -902,15 +1085,14 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
902 * first index into rate scale table. 1085 * first index into rate scale table.
903 */ 1086 */
904 if (info->flags & IEEE80211_TX_STAT_AMPDU) { 1087 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
905 tx_rate = le32_to_cpu(table->rs_table[0]); 1088 ucode_rate = le32_to_cpu(table->rs_table[0]);
906 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, 1089 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
907 &rs_index); 1090 rs_collect_tx_data(curr_tbl, rate.index,
908 rs_collect_tx_data(curr_tbl, rs_index,
909 info->status.ampdu_len, 1091 info->status.ampdu_len,
910 info->status.ampdu_ack_len); 1092 info->status.ampdu_ack_len);
911 1093
912 /* Update success/fail counts if not searching for new mode */ 1094 /* Update success/fail counts if not searching for new mode */
913 if (lq_sta->stay_in_tbl) { 1095 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
914 lq_sta->total_success += info->status.ampdu_ack_len; 1096 lq_sta->total_success += info->status.ampdu_ack_len;
915 lq_sta->total_failed += (info->status.ampdu_len - 1097 lq_sta->total_failed += (info->status.ampdu_len -
916 info->status.ampdu_ack_len); 1098 info->status.ampdu_ack_len);
@@ -927,31 +1109,31 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
927 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 1109 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
928 /* Collect data for each rate used during failed TX attempts */ 1110 /* Collect data for each rate used during failed TX attempts */
929 for (i = 0; i <= retries; ++i) { 1111 for (i = 0; i <= retries; ++i) {
930 tx_rate = le32_to_cpu(table->rs_table[i]); 1112 ucode_rate = le32_to_cpu(table->rs_table[i]);
931 rs_get_tbl_info_from_mcs(tx_rate, info->band, 1113 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
932 &tbl_type, &rs_index);
933 /* 1114 /*
934 * Only collect stats if retried rate is in the same RS 1115 * Only collect stats if retried rate is in the same RS
935 * table as active/search. 1116 * table as active/search.
936 */ 1117 */
937 if (table_type_matches(&tbl_type, curr_tbl)) 1118 if (rs_rate_match(&rate, &curr_tbl->rate))
938 tmp_tbl = curr_tbl; 1119 tmp_tbl = curr_tbl;
939 else if (table_type_matches(&tbl_type, other_tbl)) 1120 else if (rs_rate_match(&rate, &other_tbl->rate))
940 tmp_tbl = other_tbl; 1121 tmp_tbl = other_tbl;
941 else 1122 else
942 continue; 1123 continue;
943 rs_collect_tx_data(tmp_tbl, rs_index, 1, 1124
1125 rs_collect_tx_data(tmp_tbl, rate.index, 1,
944 i < retries ? 0 : legacy_success); 1126 i < retries ? 0 : legacy_success);
945 } 1127 }
946 1128
947 /* Update success/fail counts if not searching for new mode */ 1129 /* Update success/fail counts if not searching for new mode */
948 if (lq_sta->stay_in_tbl) { 1130 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
949 lq_sta->total_success += legacy_success; 1131 lq_sta->total_success += legacy_success;
950 lq_sta->total_failed += retries + (1 - legacy_success); 1132 lq_sta->total_failed += retries + (1 - legacy_success);
951 } 1133 }
952 } 1134 }
953 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1135 /* The last TX rate is cached in lq_sta; it's set in if/else above */
954 lq_sta->last_rate_n_flags = tx_rate; 1136 lq_sta->last_rate_n_flags = ucode_rate;
955done: 1137done:
956 /* See if there's a better rate or modulation mode to try. */ 1138 /* See if there's a better rate or modulation mode to try. */
957 if (sta && sta->supp_rates[sband->band]) 1139 if (sta && sta->supp_rates[sband->band])
@@ -969,8 +1151,8 @@ done:
969static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy, 1151static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
970 struct iwl_lq_sta *lq_sta) 1152 struct iwl_lq_sta *lq_sta)
971{ 1153{
972 IWL_DEBUG_RATE(mvm, "we are staying in the same table\n"); 1154 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
973 lq_sta->stay_in_tbl = 1; /* only place this gets set */ 1155 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
974 if (is_legacy) { 1156 if (is_legacy) {
975 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; 1157 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
976 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 1158 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
@@ -984,37 +1166,31 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
984 lq_sta->total_failed = 0; 1166 lq_sta->total_failed = 0;
985 lq_sta->total_success = 0; 1167 lq_sta->total_success = 0;
986 lq_sta->flush_timer = jiffies; 1168 lq_sta->flush_timer = jiffies;
987 lq_sta->action_counter = 0; 1169 lq_sta->visited_columns = 0;
988} 1170}
989 1171
990/* 1172static s32 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
991 * Find correct throughput table for given mode of modulation 1173 const struct rs_tx_column *column,
992 */ 1174 u32 bw)
993static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
994 struct iwl_scale_tbl_info *tbl)
995{ 1175{
996 /* Used to choose among HT tables */ 1176 /* Used to choose among HT tables */
997 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 1177 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
998 1178
999 /* Check for invalid LQ type */ 1179 if (WARN_ON_ONCE(column->mode != RS_LEGACY &&
1000 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) && 1180 column->mode != RS_SISO &&
1001 !(is_vht(tbl->lq_type)))) { 1181 column->mode != RS_MIMO2))
1002 tbl->expected_tpt = expected_tpt_legacy; 1182 return expected_tpt_legacy;
1003 return;
1004 }
1005 1183
1006 /* Legacy rates have only one table */ 1184 /* Legacy rates have only one table */
1007 if (is_legacy(tbl->lq_type)) { 1185 if (column->mode == RS_LEGACY)
1008 tbl->expected_tpt = expected_tpt_legacy; 1186 return expected_tpt_legacy;
1009 return;
1010 }
1011 1187
1012 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1188 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1013 /* Choose among many HT tables depending on number of streams 1189 /* Choose among many HT tables depending on number of streams
1014 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation 1190 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation
1015 * status */ 1191 * status */
1016 if (is_siso(tbl->lq_type)) { 1192 if (column->mode == RS_SISO) {
1017 switch (tbl->bw) { 1193 switch (bw) {
1018 case RATE_MCS_CHAN_WIDTH_20: 1194 case RATE_MCS_CHAN_WIDTH_20:
1019 ht_tbl_pointer = expected_tpt_siso_20MHz; 1195 ht_tbl_pointer = expected_tpt_siso_20MHz;
1020 break; 1196 break;
@@ -1027,8 +1203,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1027 default: 1203 default:
1028 WARN_ON_ONCE(1); 1204 WARN_ON_ONCE(1);
1029 } 1205 }
1030 } else if (is_mimo2(tbl->lq_type)) { 1206 } else if (column->mode == RS_MIMO2) {
1031 switch (tbl->bw) { 1207 switch (bw) {
1032 case RATE_MCS_CHAN_WIDTH_20: 1208 case RATE_MCS_CHAN_WIDTH_20:
1033 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1209 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1034 break; 1210 break;
@@ -1045,14 +1221,23 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1045 WARN_ON_ONCE(1); 1221 WARN_ON_ONCE(1);
1046 } 1222 }
1047 1223
1048 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 1224 if (!column->sgi && !lq_sta->is_agg) /* Normal */
1049 tbl->expected_tpt = ht_tbl_pointer[0]; 1225 return ht_tbl_pointer[0];
1050 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ 1226 else if (column->sgi && !lq_sta->is_agg) /* SGI */
1051 tbl->expected_tpt = ht_tbl_pointer[1]; 1227 return ht_tbl_pointer[1];
1052 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ 1228 else if (!column->sgi && lq_sta->is_agg) /* AGG */
1053 tbl->expected_tpt = ht_tbl_pointer[2]; 1229 return ht_tbl_pointer[2];
1054 else /* AGG+SGI */ 1230 else /* AGG+SGI */
1055 tbl->expected_tpt = ht_tbl_pointer[3]; 1231 return ht_tbl_pointer[3];
1232}
1233
1234static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1235 struct iwl_scale_tbl_info *tbl)
1236{
1237 struct rs_rate *rate = &tbl->rate;
1238 const struct rs_tx_column *column = &rs_tx_columns[tbl->column];
1239
1240 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);
1056} 1241}
1057 1242
1058/* 1243/*
@@ -1089,7 +1274,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1089 1274
1090 while (1) { 1275 while (1) {
1091 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask, 1276 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1092 tbl->lq_type); 1277 tbl->rate.type);
1093 1278
1094 low = high_low & 0xff; 1279 low = high_low & 0xff;
1095 high = (high_low >> 8) & 0xff; 1280 high = (high_low >> 8) & 0xff;
@@ -1110,7 +1295,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1110 * "active" throughput (under perfect conditions). 1295 * "active" throughput (under perfect conditions).
1111 */ 1296 */
1112 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) && 1297 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1113 ((active_sr > IWL_RATE_DECREASE_TH) && 1298 ((active_sr > RS_SR_FORCE_DECREASE) &&
1114 (active_sr <= IWL_RATE_HIGH_TH) && 1299 (active_sr <= IWL_RATE_HIGH_TH) &&
1115 (tpt_tbl[rate] <= active_tpt))) || 1300 (tpt_tbl[rate] <= active_tpt))) ||
1116 ((active_sr >= IWL_RATE_SCALE_SWITCH) && 1301 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
@@ -1157,417 +1342,14 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1157 return new_rate; 1342 return new_rate;
1158} 1343}
1159 1344
1160/* Move to the next action and wrap around to the first action in case 1345static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1161 * we're at the last action. Assumes actions start at 0.
1162 */
1163static inline void rs_move_next_action(struct iwl_scale_tbl_info *tbl,
1164 u8 last_action)
1165{
1166 BUILD_BUG_ON(IWL_LEGACY_FIRST_ACTION != 0);
1167 BUILD_BUG_ON(IWL_SISO_FIRST_ACTION != 0);
1168 BUILD_BUG_ON(IWL_MIMO2_FIRST_ACTION != 0);
1169
1170 tbl->action = (tbl->action + 1) % (last_action + 1);
1171}
1172
1173static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl,
1174 struct ieee80211_sta *sta)
1175{ 1346{
1176 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 1347 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
1177 tbl->bw = RATE_MCS_CHAN_WIDTH_80; 1348 return RATE_MCS_CHAN_WIDTH_80;
1178 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) 1349 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
1179 tbl->bw = RATE_MCS_CHAN_WIDTH_40; 1350 return RATE_MCS_CHAN_WIDTH_40;
1180 else
1181 tbl->bw = RATE_MCS_CHAN_WIDTH_20;
1182}
1183
1184static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl,
1185 struct ieee80211_sta *sta)
1186{
1187 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1188 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1189
1190 if (is_ht20(tbl) && (ht_cap->cap &
1191 IEEE80211_HT_CAP_SGI_20))
1192 return true;
1193 if (is_ht40(tbl) && (ht_cap->cap &
1194 IEEE80211_HT_CAP_SGI_40))
1195 return true;
1196 if (is_ht80(tbl) && (vht_cap->cap &
1197 IEEE80211_VHT_CAP_SHORT_GI_80))
1198 return true;
1199
1200 return false;
1201}
1202
1203/*
1204 * Set up search table for MIMO2
1205 */
1206static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1207 struct iwl_lq_sta *lq_sta,
1208 struct ieee80211_sta *sta,
1209 struct iwl_scale_tbl_info *tbl, int index)
1210{
1211 u16 rate_mask;
1212 s32 rate;
1213
1214 if (!sta->ht_cap.ht_supported)
1215 return -1;
1216
1217 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
1218 return -1;
1219
1220 /* Need both Tx chains/antennas to support MIMO */
1221 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
1222 return -1;
1223
1224 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1225
1226 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1227 tbl->action = 0;
1228 tbl->max_search = IWL_MAX_SEARCH;
1229 rate_mask = lq_sta->active_mimo2_rate;
1230
1231 rs_set_bw_from_sta(tbl, sta);
1232 rs_set_expected_tpt_table(lq_sta, tbl);
1233
1234 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1235
1236 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n",
1237 rate, rate_mask);
1238 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1239 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1240 rate, rate_mask);
1241 return -1;
1242 }
1243 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1244
1245 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1246 tbl->current_rate);
1247 return 0;
1248}
1249
1250/*
1251 * Set up search table for SISO
1252 */
1253static int rs_switch_to_siso(struct iwl_mvm *mvm,
1254 struct iwl_lq_sta *lq_sta,
1255 struct ieee80211_sta *sta,
1256 struct iwl_scale_tbl_info *tbl, int index)
1257{
1258 u16 rate_mask;
1259 s32 rate;
1260
1261 if (!sta->ht_cap.ht_supported)
1262 return -1;
1263
1264 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1265
1266 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1267 tbl->action = 0;
1268 tbl->max_search = IWL_MAX_SEARCH;
1269 rate_mask = lq_sta->active_siso_rate;
1270
1271 rs_set_bw_from_sta(tbl, sta);
1272 rs_set_expected_tpt_table(lq_sta, tbl);
1273 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1274
1275 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n", rate, rate_mask);
1276 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1277 IWL_DEBUG_RATE(mvm,
1278 "can not switch with index %d rate mask %x\n",
1279 rate, rate_mask);
1280 return -1;
1281 }
1282 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1283 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1284 tbl->current_rate);
1285 return 0;
1286}
1287
1288/*
1289 * Try to switch to new modulation mode from legacy
1290 */
1291static int rs_move_legacy_other(struct iwl_mvm *mvm,
1292 struct iwl_lq_sta *lq_sta,
1293 struct ieee80211_sta *sta,
1294 int index)
1295{
1296 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1297 struct iwl_scale_tbl_info *search_tbl =
1298 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1299 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1300 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1301 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1302 u8 start_action;
1303 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1304 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1305 int ret;
1306 u8 update_search_tbl_counter = 0;
1307
1308 start_action = tbl->action;
1309 while (1) {
1310 lq_sta->action_counter++;
1311 switch (tbl->action) {
1312 case IWL_LEGACY_SWITCH_ANTENNA:
1313 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n");
1314
1315 if (tx_chains_num <= 1)
1316 break;
1317
1318 /* Don't change antenna if success has been great */
1319 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1320 break;
1321
1322 /* Set up search table to try other antenna */
1323 memcpy(search_tbl, tbl, sz);
1324
1325 if (rs_toggle_antenna(valid_tx_ant,
1326 &search_tbl->current_rate,
1327 search_tbl)) {
1328 update_search_tbl_counter = 1;
1329 rs_set_expected_tpt_table(lq_sta, search_tbl);
1330 goto out;
1331 }
1332 break;
1333 case IWL_LEGACY_SWITCH_SISO:
1334 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to SISO\n");
1335
1336 /* Set up search table to try SISO */
1337 memcpy(search_tbl, tbl, sz);
1338 search_tbl->is_SGI = 0;
1339 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1340 search_tbl, index);
1341 if (!ret) {
1342 lq_sta->action_counter = 0;
1343 goto out;
1344 }
1345
1346 break;
1347 case IWL_LEGACY_SWITCH_MIMO2:
1348 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n");
1349
1350 /* Set up search table to try MIMO */
1351 memcpy(search_tbl, tbl, sz);
1352 search_tbl->is_SGI = 0;
1353
1354 search_tbl->ant_type = ANT_AB;
1355
1356 if (!rs_is_valid_ant(valid_tx_ant,
1357 search_tbl->ant_type))
1358 break;
1359
1360 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1361 search_tbl, index);
1362 if (!ret) {
1363 lq_sta->action_counter = 0;
1364 goto out;
1365 }
1366 break;
1367 default:
1368 WARN_ON_ONCE(1);
1369 }
1370 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1371
1372 if (tbl->action == start_action)
1373 break;
1374 }
1375 search_tbl->lq_type = LQ_NONE;
1376 return 0;
1377
1378out:
1379 lq_sta->search_better_tbl = 1;
1380 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1381 if (update_search_tbl_counter)
1382 search_tbl->action = tbl->action;
1383 return 0;
1384}
1385
1386/*
1387 * Try to switch to new modulation mode from SISO
1388 */
1389static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1390 struct iwl_lq_sta *lq_sta,
1391 struct ieee80211_sta *sta, int index)
1392{
1393 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1394 struct iwl_scale_tbl_info *search_tbl =
1395 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1396 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1397 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1398 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1399 u8 start_action;
1400 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1401 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1402 u8 update_search_tbl_counter = 0;
1403 int ret;
1404
1405 if (tbl->action == IWL_SISO_SWITCH_MIMO2 &&
1406 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
1407 tbl->action = IWL_SISO_SWITCH_ANTENNA;
1408
1409 start_action = tbl->action;
1410 while (1) {
1411 lq_sta->action_counter++;
1412 switch (tbl->action) {
1413 case IWL_SISO_SWITCH_ANTENNA:
1414 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n");
1415 if (tx_chains_num <= 1)
1416 break;
1417
1418 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1419 BT_MBOX_MSG(&mvm->last_bt_notif, 3,
1420 TRAFFIC_LOAD) == 0)
1421 break;
1422
1423 memcpy(search_tbl, tbl, sz);
1424 if (rs_toggle_antenna(valid_tx_ant,
1425 &search_tbl->current_rate,
1426 search_tbl)) {
1427 update_search_tbl_counter = 1;
1428 goto out;
1429 }
1430 break;
1431 case IWL_SISO_SWITCH_MIMO2:
1432 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1433 memcpy(search_tbl, tbl, sz);
1434 search_tbl->is_SGI = 0;
1435
1436 search_tbl->ant_type = ANT_AB;
1437
1438 if (!rs_is_valid_ant(valid_tx_ant,
1439 search_tbl->ant_type))
1440 break;
1441
1442 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1443 search_tbl, index);
1444 if (!ret)
1445 goto out;
1446 break;
1447 case IWL_SISO_SWITCH_GI:
1448 if (!rs_sgi_allowed(tbl, sta))
1449 break;
1450
1451 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1452
1453 memcpy(search_tbl, tbl, sz);
1454 search_tbl->is_SGI = !tbl->is_SGI;
1455 rs_set_expected_tpt_table(lq_sta, search_tbl);
1456 if (tbl->is_SGI) {
1457 s32 tpt = lq_sta->last_tpt / 100;
1458 if (tpt >= search_tbl->expected_tpt[index])
1459 break;
1460 }
1461 search_tbl->current_rate =
1462 rate_n_flags_from_tbl(mvm, search_tbl, index);
1463 update_search_tbl_counter = 1;
1464 goto out;
1465 default:
1466 WARN_ON_ONCE(1);
1467 }
1468 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1469
1470 if (tbl->action == start_action)
1471 break;
1472 }
1473 search_tbl->lq_type = LQ_NONE;
1474 return 0;
1475
1476 out:
1477 lq_sta->search_better_tbl = 1;
1478 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1479 if (update_search_tbl_counter)
1480 search_tbl->action = tbl->action;
1481
1482 return 0;
1483}
1484
1485/*
1486 * Try to switch to new modulation mode from MIMO2
1487 */
1488static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1489 struct iwl_lq_sta *lq_sta,
1490 struct ieee80211_sta *sta, int index)
1491{
1492 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1493 struct iwl_scale_tbl_info *search_tbl =
1494 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1495 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1496 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1497 u8 start_action;
1498 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1499 u8 update_search_tbl_counter = 0;
1500 int ret;
1501
1502 start_action = tbl->action;
1503 while (1) {
1504 lq_sta->action_counter++;
1505 switch (tbl->action) {
1506 case IWL_MIMO2_SWITCH_SISO_A:
1507 case IWL_MIMO2_SWITCH_SISO_B:
1508 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
1509
1510 /* Set up new search table for SISO */
1511 memcpy(search_tbl, tbl, sz);
1512
1513 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1514 search_tbl->ant_type = ANT_A;
1515 else /* tbl->action == IWL_MIMO2_SWITCH_SISO_B */
1516 search_tbl->ant_type = ANT_B;
1517
1518 if (!rs_is_valid_ant(valid_tx_ant,
1519 search_tbl->ant_type))
1520 break;
1521
1522 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1523 search_tbl, index);
1524 if (!ret)
1525 goto out;
1526
1527 break;
1528
1529 case IWL_MIMO2_SWITCH_GI:
1530 if (!rs_sgi_allowed(tbl, sta))
1531 break;
1532
1533 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
1534
1535 /* Set up new search table for MIMO2 */
1536 memcpy(search_tbl, tbl, sz);
1537 search_tbl->is_SGI = !tbl->is_SGI;
1538 rs_set_expected_tpt_table(lq_sta, search_tbl);
1539 /*
1540 * If active table already uses the fastest possible
1541 * modulation (dual stream with short guard interval),
1542 * and it's working well, there's no need to look
1543 * for a better type of modulation!
1544 */
1545 if (tbl->is_SGI) {
1546 s32 tpt = lq_sta->last_tpt / 100;
1547 if (tpt >= search_tbl->expected_tpt[index])
1548 break;
1549 }
1550 search_tbl->current_rate =
1551 rate_n_flags_from_tbl(mvm, search_tbl, index);
1552 update_search_tbl_counter = 1;
1553 goto out;
1554 default:
1555 WARN_ON_ONCE(1);
1556 }
1557 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1558
1559 if (tbl->action == start_action)
1560 break;
1561 }
1562 search_tbl->lq_type = LQ_NONE;
1563 return 0;
1564 out:
1565 lq_sta->search_better_tbl = 1;
1566 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1567 if (update_search_tbl_counter)
1568 search_tbl->action = tbl->action;
1569 1351
1570 return 0; 1352 return RATE_MCS_CHAN_WIDTH_20;
1571} 1353}
1572 1354
1573/* 1355/*
@@ -1591,13 +1373,13 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1591 tbl = &(lq_sta->lq_info[active_tbl]); 1373 tbl = &(lq_sta->lq_info[active_tbl]);
1592 1374
1593 /* If we've been disallowing search, see if we should now allow it */ 1375 /* If we've been disallowing search, see if we should now allow it */
1594 if (lq_sta->stay_in_tbl) { 1376 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1595 /* Elapsed time using current modulation mode */ 1377 /* Elapsed time using current modulation mode */
1596 if (lq_sta->flush_timer) 1378 if (lq_sta->flush_timer)
1597 flush_interval_passed = 1379 flush_interval_passed =
1598 time_after(jiffies, 1380 time_after(jiffies,
1599 (unsigned long)(lq_sta->flush_timer + 1381 (unsigned long)(lq_sta->flush_timer +
1600 IWL_RATE_SCALE_FLUSH_INTVL)); 1382 RS_STAY_IN_COLUMN_TIMEOUT));
1601 1383
1602 /* 1384 /*
1603 * Check if we should allow search for new modulation mode. 1385 * Check if we should allow search for new modulation mode.
@@ -1619,10 +1401,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1619 flush_interval_passed); 1401 flush_interval_passed);
1620 1402
1621 /* Allow search for new mode */ 1403 /* Allow search for new mode */
1622 lq_sta->stay_in_tbl = 0; /* only place reset */ 1404 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED;
1405 IWL_DEBUG_RATE(mvm,
1406 "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n");
1623 lq_sta->total_failed = 0; 1407 lq_sta->total_failed = 0;
1624 lq_sta->total_success = 0; 1408 lq_sta->total_success = 0;
1625 lq_sta->flush_timer = 0; 1409 lq_sta->flush_timer = 0;
1410 /* mark the current column as visited */
1411 lq_sta->visited_columns = BIT(tbl->column);
1626 /* 1412 /*
1627 * Else if we've used this modulation mode enough repetitions 1413 * Else if we've used this modulation mode enough repetitions
1628 * (regardless of elapsed time or success/failure), reset 1414 * (regardless of elapsed time or success/failure), reset
@@ -1646,7 +1432,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1646 /* If transitioning to allow "search", reset all history 1432 /* If transitioning to allow "search", reset all history
1647 * bitmaps and stats in active table (this will become the new 1433 * bitmaps and stats in active table (this will become the new
1648 * "search" table). */ 1434 * "search" table). */
1649 if (!lq_sta->stay_in_tbl) { 1435 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
1436 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
1650 for (i = 0; i < IWL_RATE_COUNT; i++) 1437 for (i = 0; i < IWL_RATE_COUNT; i++)
1651 rs_rate_scale_clear_window(&(tbl->win[i])); 1438 rs_rate_scale_clear_window(&(tbl->win[i]));
1652 } 1439 }
@@ -1659,15 +1446,10 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1659static void rs_update_rate_tbl(struct iwl_mvm *mvm, 1446static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1660 struct ieee80211_sta *sta, 1447 struct ieee80211_sta *sta,
1661 struct iwl_lq_sta *lq_sta, 1448 struct iwl_lq_sta *lq_sta,
1662 struct iwl_scale_tbl_info *tbl, 1449 struct rs_rate *rate)
1663 int index)
1664{ 1450{
1665 u32 rate; 1451 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
1666 1452 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1667 /* Update uCode's rate table. */
1668 rate = rate_n_flags_from_tbl(mvm, tbl, index);
1669 rs_fill_link_cmd(mvm, sta, lq_sta, rate);
1670 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
1671} 1453}
1672 1454
1673static u8 rs_get_tid(struct iwl_lq_sta *lq_data, 1455static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
@@ -1686,6 +1468,250 @@ static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
1686 return tid; 1468 return tid;
1687} 1469}
1688 1470
1471static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1472 struct iwl_lq_sta *lq_sta,
1473 struct ieee80211_sta *sta,
1474 struct iwl_scale_tbl_info *tbl)
1475{
1476 int i, j, n;
1477 enum rs_column next_col_id;
1478 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1479 const struct rs_tx_column *next_col;
1480 allow_column_func_t allow_func;
1481 u8 valid_ants = iwl_fw_valid_tx_ant(mvm->fw);
1482 s32 *expected_tpt_tbl;
1483 s32 tpt, max_expected_tpt;
1484
1485 for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
1486 next_col_id = curr_col->next_columns[i];
1487
1488 if (next_col_id == RS_COLUMN_INVALID)
1489 continue;
1490
1491 if (lq_sta->visited_columns & BIT(next_col_id)) {
1492 IWL_DEBUG_RATE(mvm, "Skip already visited column %d\n",
1493 next_col_id);
1494 continue;
1495 }
1496
1497 next_col = &rs_tx_columns[next_col_id];
1498
1499 if (!rs_is_valid_ant(valid_ants, next_col->ant)) {
1500 IWL_DEBUG_RATE(mvm,
1501 "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n",
1502 next_col_id, valid_ants, next_col->ant);
1503 continue;
1504 }
1505
1506 for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
1507 allow_func = next_col->checks[j];
1508 if (allow_func && !allow_func(mvm, sta, tbl))
1509 break;
1510 }
1511
1512 if (j != MAX_COLUMN_CHECKS) {
1513 IWL_DEBUG_RATE(mvm,
1514 "Skip column %d: not allowed (check %d failed)\n",
1515 next_col_id, j);
1516
1517 continue;
1518 }
1519
1520 tpt = lq_sta->last_tpt / 100;
1521 expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col,
1522 tbl->rate.bw);
1523 if (WARN_ON_ONCE(!expected_tpt_tbl))
1524 continue;
1525
1526 max_expected_tpt = 0;
1527 for (n = 0; n < IWL_RATE_COUNT; n++)
1528 if (expected_tpt_tbl[n] > max_expected_tpt)
1529 max_expected_tpt = expected_tpt_tbl[n];
1530
1531 if (tpt >= max_expected_tpt) {
1532 IWL_DEBUG_RATE(mvm,
1533 "Skip column %d: can't beat current TPT. Max expected %d current %d\n",
1534 next_col_id, max_expected_tpt, tpt);
1535 continue;
1536 }
1537
1538 break;
1539 }
1540
1541 if (i == MAX_NEXT_COLUMNS)
1542 return RS_COLUMN_INVALID;
1543
1544 IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
1545
1546 return next_col_id;
1547}
1548
1549static int rs_switch_to_column(struct iwl_mvm *mvm,
1550 struct iwl_lq_sta *lq_sta,
1551 struct ieee80211_sta *sta,
1552 enum rs_column col_id)
1553{
1554 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1555 struct iwl_scale_tbl_info *search_tbl =
1556 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1557 struct rs_rate *rate = &search_tbl->rate;
1558 const struct rs_tx_column *column = &rs_tx_columns[col_id];
1559 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];
1560 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1561 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1562 u16 rate_mask = 0;
1563 u32 rate_idx = 0;
1564
1565 memcpy(search_tbl, tbl, sz);
1566
1567 rate->sgi = column->sgi;
1568 rate->ant = column->ant;
1569
1570 if (column->mode == RS_LEGACY) {
1571 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1572 rate->type = LQ_LEGACY_A;
1573 else
1574 rate->type = LQ_LEGACY_G;
1575
1576 rate_mask = lq_sta->active_legacy_rate;
1577 } else if (column->mode == RS_SISO) {
1578 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1579 rate_mask = lq_sta->active_siso_rate;
1580 } else if (column->mode == RS_MIMO2) {
1581 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1582 rate_mask = lq_sta->active_mimo2_rate;
1583 } else {
1584 WARN_ON_ONCE("Bad column mode");
1585 }
1586
1587 rate->bw = rs_bw_from_sta_bw(sta);
1588 search_tbl->column = col_id;
1589 rs_set_expected_tpt_table(lq_sta, search_tbl);
1590
1591 lq_sta->visited_columns |= BIT(col_id);
1592
1593 /* Get the best matching rate if we're changing modes. e.g.
1594 * SISO->MIMO, LEGACY->SISO, MIMO->SISO
1595 */
1596 if (curr_column->mode != column->mode) {
1597 rate_idx = rs_get_best_rate(mvm, lq_sta, search_tbl,
1598 rate_mask, rate->index);
1599
1600 if ((rate_idx == IWL_RATE_INVALID) ||
1601 !(BIT(rate_idx) & rate_mask)) {
1602 IWL_DEBUG_RATE(mvm,
1603 "can not switch with index %d"
1604 " rate mask %x\n",
1605 rate_idx, rate_mask);
1606
1607 goto err;
1608 }
1609
1610 rate->index = rate_idx;
1611 }
1612
1613 IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
1614 col_id, rate->index);
1615
1616 return 0;
1617
1618err:
1619 rate->type = LQ_NONE;
1620 return -1;
1621}
1622
1623static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1624 struct iwl_scale_tbl_info *tbl,
1625 s32 sr, int low, int high,
1626 int current_tpt,
1627 int low_tpt, int high_tpt)
1628{
1629 enum rs_action action = RS_ACTION_STAY;
1630
1631 /* Too many failures, decrease rate */
1632 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
1633 IWL_DEBUG_RATE(mvm,
1634 "decrease rate because of low SR\n");
1635 action = RS_ACTION_DOWNSCALE;
1636 /* No throughput measured yet for adjacent rates; try increase. */
1637 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1638 (high_tpt == IWL_INVALID_VALUE)) {
1639 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
1640 IWL_DEBUG_RATE(mvm,
1641 "Good SR and no high rate measurement. "
1642 "Increase rate\n");
1643 action = RS_ACTION_UPSCALE;
1644 } else if (low != IWL_RATE_INVALID) {
1645 IWL_DEBUG_RATE(mvm,
1646 "Remain in current rate\n");
1647 action = RS_ACTION_STAY;
1648 }
1649 }
1650
1651 /* Both adjacent throughputs are measured, but neither one has better
1652 * throughput; we're using the best rate, don't change it!
1653 */
1654 else if ((low_tpt != IWL_INVALID_VALUE) &&
1655 (high_tpt != IWL_INVALID_VALUE) &&
1656 (low_tpt < current_tpt) &&
1657 (high_tpt < current_tpt)) {
1658 IWL_DEBUG_RATE(mvm,
1659 "Both high and low are worse. "
1660 "Maintain rate\n");
1661 action = RS_ACTION_STAY;
1662 }
1663
1664 /* At least one adjacent rate's throughput is measured,
1665 * and may have better performance.
1666 */
1667 else {
1668 /* Higher adjacent rate's throughput is measured */
1669 if (high_tpt != IWL_INVALID_VALUE) {
1670 /* Higher rate has better throughput */
1671 if (high_tpt > current_tpt &&
1672 sr >= IWL_RATE_INCREASE_TH) {
1673 IWL_DEBUG_RATE(mvm,
1674 "Higher rate is better and good "
1675 "SR. Increate rate\n");
1676 action = RS_ACTION_UPSCALE;
1677 } else {
1678 IWL_DEBUG_RATE(mvm,
1679 "Higher rate isn't better OR "
1680 "no good SR. Maintain rate\n");
1681 action = RS_ACTION_STAY;
1682 }
1683
1684 /* Lower adjacent rate's throughput is measured */
1685 } else if (low_tpt != IWL_INVALID_VALUE) {
1686 /* Lower rate has better throughput */
1687 if (low_tpt > current_tpt) {
1688 IWL_DEBUG_RATE(mvm,
1689 "Lower rate is better. "
1690 "Decrease rate\n");
1691 action = RS_ACTION_DOWNSCALE;
1692 } else if (sr >= IWL_RATE_INCREASE_TH) {
1693 IWL_DEBUG_RATE(mvm,
1694 "Lower rate isn't better and "
1695 "good SR. Increase rate\n");
1696 action = RS_ACTION_UPSCALE;
1697 }
1698 }
1699 }
1700
1701 /* Sanity check; asked for decrease, but success rate or throughput
1702 * has been good at old rate. Don't change it.
1703 */
1704 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) &&
1705 ((sr > IWL_RATE_HIGH_TH) ||
1706 (current_tpt > (100 * tbl->expected_tpt[low])))) {
1707 IWL_DEBUG_RATE(mvm,
1708 "Sanity check failed. Maintain rate\n");
1709 action = RS_ACTION_STAY;
1710 }
1711
1712 return action;
1713}
1714
1689/* 1715/*
1690 * Do rate scaling and search for new modulation mode. 1716 * Do rate scaling and search for new modulation mode.
1691 */ 1717 */
@@ -1705,20 +1731,19 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1705 int low_tpt = IWL_INVALID_VALUE; 1731 int low_tpt = IWL_INVALID_VALUE;
1706 int high_tpt = IWL_INVALID_VALUE; 1732 int high_tpt = IWL_INVALID_VALUE;
1707 u32 fail_count; 1733 u32 fail_count;
1708 s8 scale_action = 0; 1734 enum rs_action scale_action = RS_ACTION_STAY;
1709 u16 rate_mask; 1735 u16 rate_mask;
1710 u8 update_lq = 0; 1736 u8 update_lq = 0;
1711 struct iwl_scale_tbl_info *tbl, *tbl1; 1737 struct iwl_scale_tbl_info *tbl, *tbl1;
1712 u16 rate_scale_index_msk = 0;
1713 u8 active_tbl = 0; 1738 u8 active_tbl = 0;
1714 u8 done_search = 0; 1739 u8 done_search = 0;
1715 u16 high_low; 1740 u16 high_low;
1716 s32 sr; 1741 s32 sr;
1717 u8 tid = IWL_MAX_TID_COUNT; 1742 u8 tid = IWL_MAX_TID_COUNT;
1743 u8 prev_agg = lq_sta->is_agg;
1718 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 1744 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
1719 struct iwl_mvm_tid_data *tid_data; 1745 struct iwl_mvm_tid_data *tid_data;
1720 1746 struct rs_rate *rate;
1721 IWL_DEBUG_RATE(mvm, "rate scale calculate new rate for skb\n");
1722 1747
1723 /* Send management frames and NO_ACK data using lowest rate. */ 1748 /* Send management frames and NO_ACK data using lowest rate. */
1724 /* TODO: this could probably be improved.. */ 1749 /* TODO: this could probably be improved.. */
@@ -1726,8 +1751,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1726 info->flags & IEEE80211_TX_CTL_NO_ACK) 1751 info->flags & IEEE80211_TX_CTL_NO_ACK)
1727 return; 1752 return;
1728 1753
1729 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
1730
1731 tid = rs_get_tid(lq_sta, hdr); 1754 tid = rs_get_tid(lq_sta, hdr);
1732 if ((tid != IWL_MAX_TID_COUNT) && 1755 if ((tid != IWL_MAX_TID_COUNT) &&
1733 (lq_sta->tx_agg_tid_en & (1 << tid))) { 1756 (lq_sta->tx_agg_tid_en & (1 << tid))) {
@@ -1751,45 +1774,29 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1751 active_tbl = 1 - lq_sta->active_tbl; 1774 active_tbl = 1 - lq_sta->active_tbl;
1752 1775
1753 tbl = &(lq_sta->lq_info[active_tbl]); 1776 tbl = &(lq_sta->lq_info[active_tbl]);
1777 rate = &tbl->rate;
1778
1779 if (prev_agg != lq_sta->is_agg) {
1780 IWL_DEBUG_RATE(mvm,
1781 "Aggregation changed: prev %d current %d. Update expected TPT table\n",
1782 prev_agg, lq_sta->is_agg);
1783 rs_set_expected_tpt_table(lq_sta, tbl);
1784 }
1754 1785
1755 /* current tx rate */ 1786 /* current tx rate */
1756 index = lq_sta->last_txrate_idx; 1787 index = lq_sta->last_txrate_idx;
1757 1788
1758 IWL_DEBUG_RATE(mvm, "Rate scale index %d for type %d\n", index,
1759 tbl->lq_type);
1760
1761 /* rates available for this association, and for modulation mode */ 1789 /* rates available for this association, and for modulation mode */
1762 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 1790 rate_mask = rs_get_supported_rates(lq_sta, rate);
1763 1791
1764 IWL_DEBUG_RATE(mvm, "mask 0x%04X\n", rate_mask); 1792 if (!(BIT(index) & rate_mask)) {
1765
1766 /* mask with station rate restriction */
1767 if (is_legacy(tbl->lq_type)) {
1768 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1769 /* supp_rates has no CCK bits in A mode */
1770 rate_scale_index_msk = (u16) (rate_mask &
1771 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
1772 else
1773 rate_scale_index_msk = (u16) (rate_mask &
1774 lq_sta->supp_rates);
1775
1776 } else {
1777 rate_scale_index_msk = rate_mask;
1778 }
1779
1780 if (!rate_scale_index_msk)
1781 rate_scale_index_msk = rate_mask;
1782
1783 if (!((1 << index) & rate_scale_index_msk)) {
1784 IWL_ERR(mvm, "Current Rate is not valid\n"); 1793 IWL_ERR(mvm, "Current Rate is not valid\n");
1785 if (lq_sta->search_better_tbl) { 1794 if (lq_sta->search_better_tbl) {
1786 /* revert to active table if search table is not valid*/ 1795 /* revert to active table if search table is not valid*/
1787 tbl->lq_type = LQ_NONE; 1796 rate->type = LQ_NONE;
1788 lq_sta->search_better_tbl = 0; 1797 lq_sta->search_better_tbl = 0;
1789 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1798 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1790 /* get "active" rate info */ 1799 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1791 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
1792 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index);
1793 } 1800 }
1794 return; 1801 return;
1795 } 1802 }
@@ -1806,6 +1813,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1806 index = lq_sta->max_rate_idx; 1813 index = lq_sta->max_rate_idx;
1807 update_lq = 1; 1814 update_lq = 1;
1808 window = &(tbl->win[index]); 1815 window = &(tbl->win[index]);
1816 IWL_DEBUG_RATE(mvm,
1817 "Forcing user max rate %d\n",
1818 index);
1809 goto lq_update; 1819 goto lq_update;
1810 } 1820 }
1811 1821
@@ -1822,8 +1832,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1822 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && 1832 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1823 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 1833 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
1824 IWL_DEBUG_RATE(mvm, 1834 IWL_DEBUG_RATE(mvm,
1825 "LQ: still below TH. succ=%d total=%d for index %d\n", 1835 "(%s: %d): Test Window: succ %d total %d\n",
1826 window->success_counter, window->counter, index); 1836 rs_pretty_lq_type(rate->type),
1837 index, window->success_counter, window->counter);
1827 1838
1828 /* Can't calculate this yet; not enough history */ 1839 /* Can't calculate this yet; not enough history */
1829 window->average_tpt = IWL_INVALID_VALUE; 1840 window->average_tpt = IWL_INVALID_VALUE;
@@ -1838,8 +1849,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1838 * actual average throughput */ 1849 * actual average throughput */
1839 if (window->average_tpt != ((window->success_ratio * 1850 if (window->average_tpt != ((window->success_ratio *
1840 tbl->expected_tpt[index] + 64) / 128)) { 1851 tbl->expected_tpt[index] + 64) / 128)) {
1841 IWL_ERR(mvm,
1842 "expected_tpt should have been calculated by now\n");
1843 window->average_tpt = ((window->success_ratio * 1852 window->average_tpt = ((window->success_ratio *
1844 tbl->expected_tpt[index] + 64) / 128); 1853 tbl->expected_tpt[index] + 64) / 128);
1845 } 1854 }
@@ -1851,34 +1860,33 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1851 * continuing to use the setup that we've been trying. */ 1860 * continuing to use the setup that we've been trying. */
1852 if (window->average_tpt > lq_sta->last_tpt) { 1861 if (window->average_tpt > lq_sta->last_tpt) {
1853 IWL_DEBUG_RATE(mvm, 1862 IWL_DEBUG_RATE(mvm,
1854 "LQ: SWITCHING TO NEW TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1863 "SWITCHING TO NEW TABLE SR: %d "
1864 "cur-tpt %d old-tpt %d\n",
1855 window->success_ratio, 1865 window->success_ratio,
1856 window->average_tpt, 1866 window->average_tpt,
1857 lq_sta->last_tpt); 1867 lq_sta->last_tpt);
1858 1868
1859 if (!is_legacy(tbl->lq_type))
1860 lq_sta->enable_counter = 1;
1861
1862 /* Swap tables; "search" becomes "active" */ 1869 /* Swap tables; "search" becomes "active" */
1863 lq_sta->active_tbl = active_tbl; 1870 lq_sta->active_tbl = active_tbl;
1864 current_tpt = window->average_tpt; 1871 current_tpt = window->average_tpt;
1865 /* Else poor success; go back to mode in "active" table */ 1872 /* Else poor success; go back to mode in "active" table */
1866 } else { 1873 } else {
1867 IWL_DEBUG_RATE(mvm, 1874 IWL_DEBUG_RATE(mvm,
1868 "LQ: GOING BACK TO THE OLD TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1875 "GOING BACK TO THE OLD TABLE: SR %d "
1876 "cur-tpt %d old-tpt %d\n",
1869 window->success_ratio, 1877 window->success_ratio,
1870 window->average_tpt, 1878 window->average_tpt,
1871 lq_sta->last_tpt); 1879 lq_sta->last_tpt);
1872 1880
1873 /* Nullify "search" table */ 1881 /* Nullify "search" table */
1874 tbl->lq_type = LQ_NONE; 1882 rate->type = LQ_NONE;
1875 1883
1876 /* Revert to "active" table */ 1884 /* Revert to "active" table */
1877 active_tbl = lq_sta->active_tbl; 1885 active_tbl = lq_sta->active_tbl;
1878 tbl = &(lq_sta->lq_info[active_tbl]); 1886 tbl = &(lq_sta->lq_info[active_tbl]);
1879 1887
1880 /* Revert to "active" rate and throughput info */ 1888 /* Revert to "active" rate and throughput info */
1881 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 1889 index = tbl->rate.index;
1882 current_tpt = lq_sta->last_tpt; 1890 current_tpt = lq_sta->last_tpt;
1883 1891
1884 /* Need to set up a new rate table in uCode */ 1892 /* Need to set up a new rate table in uCode */
@@ -1894,8 +1902,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1894 1902
1895 /* (Else) not in search of better modulation mode, try for better 1903 /* (Else) not in search of better modulation mode, try for better
1896 * starting rate, while staying in this mode. */ 1904 * starting rate, while staying in this mode. */
1897 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk, 1905 high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type);
1898 tbl->lq_type);
1899 low = high_low & 0xff; 1906 low = high_low & 0xff;
1900 high = (high_low >> 8) & 0xff; 1907 high = (high_low >> 8) & 0xff;
1901 1908
@@ -1913,118 +1920,58 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1913 if (high != IWL_RATE_INVALID) 1920 if (high != IWL_RATE_INVALID)
1914 high_tpt = tbl->win[high].average_tpt; 1921 high_tpt = tbl->win[high].average_tpt;
1915 1922
1916 scale_action = 0; 1923 IWL_DEBUG_RATE(mvm,
1917 1924 "(%s: %d): cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n",
1918 /* Too many failures, decrease rate */ 1925 rs_pretty_lq_type(rate->type), index, current_tpt, sr,
1919 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { 1926 low, high, low_tpt, high_tpt);
1920 IWL_DEBUG_RATE(mvm,
1921 "decrease rate because of low success_ratio\n");
1922 scale_action = -1;
1923 /* No throughput measured yet for adjacent rates; try increase. */
1924 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1925 (high_tpt == IWL_INVALID_VALUE)) {
1926 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
1927 scale_action = 1;
1928 else if (low != IWL_RATE_INVALID)
1929 scale_action = 0;
1930 }
1931
1932 /* Both adjacent throughputs are measured, but neither one has better
1933 * throughput; we're using the best rate, don't change it! */
1934 else if ((low_tpt != IWL_INVALID_VALUE) &&
1935 (high_tpt != IWL_INVALID_VALUE) &&
1936 (low_tpt < current_tpt) &&
1937 (high_tpt < current_tpt))
1938 scale_action = 0;
1939
1940 /* At least one adjacent rate's throughput is measured,
1941 * and may have better performance. */
1942 else {
1943 /* Higher adjacent rate's throughput is measured */
1944 if (high_tpt != IWL_INVALID_VALUE) {
1945 /* Higher rate has better throughput */
1946 if (high_tpt > current_tpt &&
1947 sr >= IWL_RATE_INCREASE_TH) {
1948 scale_action = 1;
1949 } else {
1950 scale_action = 0;
1951 }
1952
1953 /* Lower adjacent rate's throughput is measured */
1954 } else if (low_tpt != IWL_INVALID_VALUE) {
1955 /* Lower rate has better throughput */
1956 if (low_tpt > current_tpt) {
1957 IWL_DEBUG_RATE(mvm,
1958 "decrease rate because of low tpt\n");
1959 scale_action = -1;
1960 } else if (sr >= IWL_RATE_INCREASE_TH) {
1961 scale_action = 1;
1962 }
1963 }
1964 }
1965
1966 /* Sanity check; asked for decrease, but success rate or throughput
1967 * has been good at old rate. Don't change it. */
1968 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
1969 ((sr > IWL_RATE_HIGH_TH) ||
1970 (current_tpt > (100 * tbl->expected_tpt[low]))))
1971 scale_action = 0;
1972 1927
1973 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= 1928 scale_action = rs_get_rate_action(mvm, tbl, sr, low, high,
1974 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) { 1929 current_tpt, low_tpt, high_tpt);
1975 if (lq_sta->last_bt_traffic >
1976 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1977 /*
1978 * don't set scale_action, don't want to scale up if
1979 * the rate scale doesn't otherwise think that is a
1980 * good idea.
1981 */
1982 } else if (lq_sta->last_bt_traffic <=
1983 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1984 scale_action = -1;
1985 }
1986 }
1987 lq_sta->last_bt_traffic =
1988 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
1989 1930
1990 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= 1931 /* Force a search in case BT doesn't like us being in MIMO */
1991 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) { 1932 if (is_mimo(rate) &&
1992 /* search for a new modulation */ 1933 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {
1934 IWL_DEBUG_RATE(mvm,
1935 "BT Coex forbids MIMO. Search for new config\n");
1993 rs_stay_in_table(lq_sta, true); 1936 rs_stay_in_table(lq_sta, true);
1994 goto lq_update; 1937 goto lq_update;
1995 } 1938 }
1996 1939
1997 switch (scale_action) { 1940 switch (scale_action) {
1998 case -1: 1941 case RS_ACTION_DOWNSCALE:
1999 /* Decrease starting rate, update uCode's rate table */ 1942 /* Decrease starting rate, update uCode's rate table */
2000 if (low != IWL_RATE_INVALID) { 1943 if (low != IWL_RATE_INVALID) {
2001 update_lq = 1; 1944 update_lq = 1;
2002 index = low; 1945 index = low;
1946 } else {
1947 IWL_DEBUG_RATE(mvm,
1948 "At the bottom rate. Can't decrease\n");
2003 } 1949 }
2004 1950
2005 break; 1951 break;
2006 case 1: 1952 case RS_ACTION_UPSCALE:
2007 /* Increase starting rate, update uCode's rate table */ 1953 /* Increase starting rate, update uCode's rate table */
2008 if (high != IWL_RATE_INVALID) { 1954 if (high != IWL_RATE_INVALID) {
2009 update_lq = 1; 1955 update_lq = 1;
2010 index = high; 1956 index = high;
1957 } else {
1958 IWL_DEBUG_RATE(mvm,
1959 "At the top rate. Can't increase\n");
2011 } 1960 }
2012 1961
2013 break; 1962 break;
2014 case 0: 1963 case RS_ACTION_STAY:
2015 /* No change */ 1964 /* No change */
2016 default: 1965 default:
2017 break; 1966 break;
2018 } 1967 }
2019 1968
2020 IWL_DEBUG_RATE(mvm,
2021 "choose rate scale index %d action %d low %d high %d type %d\n",
2022 index, scale_action, low, high, tbl->lq_type);
2023
2024lq_update: 1969lq_update:
2025 /* Replace uCode's rate table for the destination station. */ 1970 /* Replace uCode's rate table for the destination station. */
2026 if (update_lq) 1971 if (update_lq) {
2027 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 1972 tbl->rate.index = index;
1973 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1974 }
2028 1975
2029 rs_stay_in_table(lq_sta, false); 1976 rs_stay_in_table(lq_sta, false);
2030 1977
@@ -2035,20 +1982,29 @@ lq_update:
2035 * 3) Allowing a new search 1982 * 3) Allowing a new search
2036 */ 1983 */
2037 if (!update_lq && !done_search && 1984 if (!update_lq && !done_search &&
2038 !lq_sta->stay_in_tbl && window->counter) { 1985 lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED
1986 && window->counter) {
1987 enum rs_column next_column;
1988
2039 /* Save current throughput to compare with "search" throughput*/ 1989 /* Save current throughput to compare with "search" throughput*/
2040 lq_sta->last_tpt = current_tpt; 1990 lq_sta->last_tpt = current_tpt;
2041 1991
2042 /* Select a new "search" modulation mode to try. 1992 IWL_DEBUG_RATE(mvm,
2043 * If one is found, set up the new "search" table. */ 1993 "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n",
2044 if (is_legacy(tbl->lq_type)) 1994 update_lq, done_search, lq_sta->rs_state,
2045 rs_move_legacy_other(mvm, lq_sta, sta, index); 1995 window->counter);
2046 else if (is_siso(tbl->lq_type)) 1996
2047 rs_move_siso_to_other(mvm, lq_sta, sta, index); 1997 next_column = rs_get_next_column(mvm, lq_sta, sta, tbl);
2048 else if (is_mimo2(tbl->lq_type)) 1998 if (next_column != RS_COLUMN_INVALID) {
2049 rs_move_mimo2_to_other(mvm, lq_sta, sta, index); 1999 int ret = rs_switch_to_column(mvm, lq_sta, sta,
2050 else 2000 next_column);
2051 WARN_ON_ONCE(1); 2001 if (!ret)
2002 lq_sta->search_better_tbl = 1;
2003 } else {
2004 IWL_DEBUG_RATE(mvm,
2005 "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n");
2006 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED;
2007 }
2052 2008
2053 /* If new "search" mode was selected, set up in uCode table */ 2009 /* If new "search" mode was selected, set up in uCode table */
2054 if (lq_sta->search_better_tbl) { 2010 if (lq_sta->search_better_tbl) {
@@ -2058,36 +2014,31 @@ lq_update:
2058 rs_rate_scale_clear_window(&(tbl->win[i])); 2014 rs_rate_scale_clear_window(&(tbl->win[i]));
2059 2015
2060 /* Use new "search" start rate */ 2016 /* Use new "search" start rate */
2061 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2017 index = tbl->rate.index;
2062 2018
2063 IWL_DEBUG_RATE(mvm, 2019 rs_dump_rate(mvm, &tbl->rate,
2064 "Switch current mcs: %X index: %d\n", 2020 "Switch to SEARCH TABLE:");
2065 tbl->current_rate, index); 2021 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);
2066 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate); 2022 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
2067 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2068 } else { 2023 } else {
2069 done_search = 1; 2024 done_search = 1;
2070 } 2025 }
2071 } 2026 }
2072 2027
2073 if (done_search && !lq_sta->stay_in_tbl) { 2028 if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
2074 /* If the "active" (non-search) mode was legacy, 2029 /* If the "active" (non-search) mode was legacy,
2075 * and we've tried switching antennas, 2030 * and we've tried switching antennas,
2076 * but we haven't been able to try HT modes (not available), 2031 * but we haven't been able to try HT modes (not available),
2077 * stay with best antenna legacy modulation for a while 2032 * stay with best antenna legacy modulation for a while
2078 * before next round of mode comparisons. */ 2033 * before next round of mode comparisons. */
2079 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2034 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2080 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported && 2035 if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) {
2081 lq_sta->action_counter > tbl1->max_search) {
2082 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n"); 2036 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2083 rs_set_stay_in_table(mvm, 1, lq_sta); 2037 rs_set_stay_in_table(mvm, 1, lq_sta);
2084 } 2038 } else {
2085
2086 /* If we're in an HT mode, and all 3 mode switch actions 2039 /* If we're in an HT mode, and all 3 mode switch actions
2087 * have been tried and compared, stay in this best modulation 2040 * have been tried and compared, stay in this best modulation
2088 * mode for a while before next round of mode comparisons. */ 2041 * mode for a while before next round of mode comparisons. */
2089 if (lq_sta->enable_counter &&
2090 (lq_sta->action_counter >= tbl1->max_search)) {
2091 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2042 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2092 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2043 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2093 (tid != IWL_MAX_TID_COUNT)) { 2044 (tid != IWL_MAX_TID_COUNT)) {
@@ -2105,7 +2056,6 @@ lq_update:
2105 } 2056 }
2106 2057
2107out: 2058out:
2108 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index);
2109 lq_sta->last_txrate_idx = index; 2059 lq_sta->last_txrate_idx = index;
2110} 2060}
2111 2061
@@ -2126,12 +2076,12 @@ out:
2126static void rs_initialize_lq(struct iwl_mvm *mvm, 2076static void rs_initialize_lq(struct iwl_mvm *mvm,
2127 struct ieee80211_sta *sta, 2077 struct ieee80211_sta *sta,
2128 struct iwl_lq_sta *lq_sta, 2078 struct iwl_lq_sta *lq_sta,
2129 enum ieee80211_band band) 2079 enum ieee80211_band band,
2080 bool init)
2130{ 2081{
2131 struct iwl_scale_tbl_info *tbl; 2082 struct iwl_scale_tbl_info *tbl;
2132 int rate_idx; 2083 struct rs_rate *rate;
2133 int i; 2084 int i;
2134 u32 rate;
2135 u8 active_tbl = 0; 2085 u8 active_tbl = 0;
2136 u8 valid_tx_ant; 2086 u8 valid_tx_ant;
2137 2087
@@ -2148,27 +2098,30 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2148 active_tbl = 1 - lq_sta->active_tbl; 2098 active_tbl = 1 - lq_sta->active_tbl;
2149 2099
2150 tbl = &(lq_sta->lq_info[active_tbl]); 2100 tbl = &(lq_sta->lq_info[active_tbl]);
2101 rate = &tbl->rate;
2151 2102
2152 if ((i < 0) || (i >= IWL_RATE_COUNT)) 2103 if ((i < 0) || (i >= IWL_RATE_COUNT))
2153 i = 0; 2104 i = 0;
2154 2105
2155 rate = iwl_rates[i].plcp; 2106 rate->index = i;
2156 tbl->ant_type = first_antenna(valid_tx_ant); 2107 rate->ant = first_antenna(valid_tx_ant);
2157 rate |= tbl->ant_type << RATE_MCS_ANT_POS; 2108 rate->sgi = false;
2158 2109 rate->bw = RATE_MCS_CHAN_WIDTH_20;
2159 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2110 if (band == IEEE80211_BAND_5GHZ)
2160 rate |= RATE_MCS_CCK_MSK; 2111 rate->type = LQ_LEGACY_A;
2112 else
2113 rate->type = LQ_LEGACY_G;
2161 2114
2162 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx); 2115 WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
2163 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) 2116 if (rate->ant == ANT_A)
2164 rs_toggle_antenna(valid_tx_ant, &rate, tbl); 2117 tbl->column = RS_COLUMN_LEGACY_ANT_A;
2118 else
2119 tbl->column = RS_COLUMN_LEGACY_ANT_B;
2165 2120
2166 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx);
2167 tbl->current_rate = rate;
2168 rs_set_expected_tpt_table(lq_sta, tbl); 2121 rs_set_expected_tpt_table(lq_sta, tbl);
2169 rs_fill_link_cmd(NULL, NULL, lq_sta, rate); 2122 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
2170 /* TODO restore station should remember the lq cmd */ 2123 /* TODO restore station should remember the lq cmd */
2171 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true); 2124 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
2172} 2125}
2173 2126
2174static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, 2127static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2182,8 +2135,6 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2182 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2135 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2183 struct iwl_lq_sta *lq_sta = mvm_sta; 2136 struct iwl_lq_sta *lq_sta = mvm_sta;
2184 2137
2185 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2186
2187 /* Get max rate if user set max rate */ 2138 /* Get max rate if user set max rate */
2188 if (lq_sta) { 2139 if (lq_sta) {
2189 lq_sta->max_rate_idx = txrc->max_rate_idx; 2140 lq_sta->max_rate_idx = txrc->max_rate_idx;
@@ -2242,11 +2193,59 @@ static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
2242 return -1; 2193 return -1;
2243} 2194}
2244 2195
2196static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2197 struct ieee80211_sta_vht_cap *vht_cap,
2198 struct iwl_lq_sta *lq_sta)
2199{
2200 int i;
2201 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
2202
2203 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2204 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2205 if (i == IWL_RATE_9M_INDEX)
2206 continue;
2207
2208 /* Disable MCS9 as a workaround */
2209 if (i == IWL_RATE_MCS_9_INDEX)
2210 continue;
2211
2212 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2213 if (i == IWL_RATE_MCS_9_INDEX &&
2214 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2215 continue;
2216
2217 lq_sta->active_siso_rate |= BIT(i);
2218 }
2219 }
2220
2221 if (sta->rx_nss < 2)
2222 return;
2223
2224 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2225 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2226 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2227 if (i == IWL_RATE_9M_INDEX)
2228 continue;
2229
2230 /* Disable MCS9 as a workaround */
2231 if (i == IWL_RATE_MCS_9_INDEX)
2232 continue;
2233
2234 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2235 if (i == IWL_RATE_MCS_9_INDEX &&
2236 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2237 continue;
2238
2239 lq_sta->active_mimo2_rate |= BIT(i);
2240 }
2241 }
2242}
2243
2245/* 2244/*
2246 * Called after adding a new station to initialize rate scaling 2245 * Called after adding a new station to initialize rate scaling
2247 */ 2246 */
2248void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 2247void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2249 enum ieee80211_band band) 2248 enum ieee80211_band band, bool init)
2250{ 2249{
2251 int i, j; 2250 int i, j;
2252 struct ieee80211_hw *hw = mvm->hw; 2251 struct ieee80211_hw *hw = mvm->hw;
@@ -2259,6 +2258,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2259 2258
2260 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2259 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2261 lq_sta = &sta_priv->lq_sta; 2260 lq_sta = &sta_priv->lq_sta;
2261 memset(lq_sta, 0, sizeof(*lq_sta));
2262
2262 sband = hw->wiphy->bands[band]; 2263 sband = hw->wiphy->bands[band];
2263 2264
2264 lq_sta->lq.sta_id = sta_priv->sta_id; 2265 lq_sta->lq.sta_id = sta_priv->sta_id;
@@ -2268,7 +2269,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2268 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2269 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2269 2270
2270 lq_sta->flush_timer = 0; 2271 lq_sta->flush_timer = 0;
2271 lq_sta->supp_rates = sta->supp_rates[sband->band];
2272 2272
2273 IWL_DEBUG_RATE(mvm, 2273 IWL_DEBUG_RATE(mvm,
2274 "LQ: *** rate scale station global init for station %d ***\n", 2274 "LQ: *** rate scale station global init for station %d ***\n",
@@ -2308,27 +2308,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2308 2308
2309 lq_sta->is_vht = false; 2309 lq_sta->is_vht = false;
2310 } else { 2310 } else {
2311 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1); 2311 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2312 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2313 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2314 if (i == IWL_RATE_9M_INDEX)
2315 continue;
2316
2317 lq_sta->active_siso_rate |= BIT(i);
2318 }
2319 }
2320
2321 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2322 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2323 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2324 if (i == IWL_RATE_9M_INDEX)
2325 continue;
2326
2327 lq_sta->active_mimo2_rate |= BIT(i);
2328 }
2329 }
2330
2331 /* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */
2332 lq_sta->is_vht = true; 2312 lq_sta->is_vht = true;
2333 } 2313 }
2334 2314
@@ -2341,15 +2321,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2341 /* These values will be overridden later */ 2321 /* These values will be overridden later */
2342 lq_sta->lq.single_stream_ant_msk = 2322 lq_sta->lq.single_stream_ant_msk =
2343 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 2323 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2344 lq_sta->lq.dual_stream_ant_msk = 2324 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2345 iwl_fw_valid_tx_ant(mvm->fw) &
2346 ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2347 if (!lq_sta->lq.dual_stream_ant_msk) {
2348 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2349 } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) {
2350 lq_sta->lq.dual_stream_ant_msk =
2351 iwl_fw_valid_tx_ant(mvm->fw);
2352 }
2353 2325
2354 /* as default allow aggregation for all tids */ 2326 /* as default allow aggregation for all tids */
2355 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2327 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
@@ -2364,121 +2336,184 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2364 lq_sta->dbg_fixed_rate = 0; 2336 lq_sta->dbg_fixed_rate = 0;
2365#endif 2337#endif
2366 2338
2367 rs_initialize_lq(mvm, sta, lq_sta, band); 2339 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2368} 2340}
2369 2341
2370static void rs_fill_link_cmd(struct iwl_mvm *mvm, 2342static void rs_rate_update(void *mvm_r,
2371 struct ieee80211_sta *sta, 2343 struct ieee80211_supported_band *sband,
2372 struct iwl_lq_sta *lq_sta, u32 new_rate) 2344 struct cfg80211_chan_def *chandef,
2345 struct ieee80211_sta *sta, void *priv_sta,
2346 u32 changed)
2347{
2348 u8 tid;
2349 struct iwl_op_mode *op_mode =
2350 (struct iwl_op_mode *)mvm_r;
2351 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2352
2353 /* Stop any ongoing aggregations as rs starts off assuming no agg */
2354 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
2355 ieee80211_stop_tx_ba_session(sta, tid);
2356
2357 iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
2358}
2359
2360#ifdef CONFIG_MAC80211_DEBUGFS
2361static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
2362 struct iwl_lq_cmd *lq_cmd,
2363 enum ieee80211_band band,
2364 u32 ucode_rate)
2365{
2366 struct rs_rate rate;
2367 int i;
2368 int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
2369 __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
2370
2371 for (i = 0; i < num_rates; i++)
2372 lq_cmd->rs_table[i] = ucode_rate_le32;
2373
2374 rs_rate_from_ucode_rate(ucode_rate, band, &rate);
2375
2376 if (is_mimo(&rate))
2377 lq_cmd->mimo_delim = num_rates - 1;
2378 else
2379 lq_cmd->mimo_delim = 0;
2380}
2381#endif /* CONFIG_MAC80211_DEBUGFS */
2382
2383static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2384 struct iwl_lq_sta *lq_sta,
2385 struct rs_rate *rate,
2386 __le32 *rs_table, int *rs_table_index,
2387 int num_rates, int num_retries,
2388 u8 valid_tx_ant, bool toggle_ant)
2389{
2390 int i, j;
2391 __le32 ucode_rate;
2392 bool bottom_reached = false;
2393 int prev_rate_idx = rate->index;
2394 int end = LINK_QUAL_MAX_RETRY_NUM;
2395 int index = *rs_table_index;
2396
2397 for (i = 0; i < num_rates && index < end; i++) {
2398 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate));
2399 for (j = 0; j < num_retries && index < end; j++, index++)
2400 rs_table[index] = ucode_rate;
2401
2402 if (toggle_ant)
2403 rs_toggle_antenna(valid_tx_ant, rate);
2404
2405 prev_rate_idx = rate->index;
2406 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);
2407 if (bottom_reached && !is_legacy(rate))
2408 break;
2409 }
2410
2411 if (!bottom_reached)
2412 rate->index = prev_rate_idx;
2413
2414 *rs_table_index = index;
2415}
2416
2417/* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI
2418 * column the rate table should look like this:
2419 *
2420 * rate[0] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
2421 * rate[1] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
2422 * rate[2] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
2423 * rate[3] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
2424 * rate[4] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
2425 * rate[5] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
2426 * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI
2427 * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI
2428 * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI
2429 * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps
2430 * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps
2431 * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps
2432 * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps
2433 * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps
2434 * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps
2435 * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps
2436 */
2437static void rs_build_rates_table(struct iwl_mvm *mvm,
2438 struct iwl_lq_sta *lq_sta,
2439 const struct rs_rate *initial_rate)
2373{ 2440{
2374 struct iwl_scale_tbl_info tbl_type; 2441 struct rs_rate rate;
2375 int index = 0; 2442 int num_rates, num_retries, index = 0;
2376 int rate_idx;
2377 int repeat_rate = 0;
2378 u8 ant_toggle_cnt = 0;
2379 u8 use_ht_possible = 1;
2380 u8 valid_tx_ant = 0; 2443 u8 valid_tx_ant = 0;
2381 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2444 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2445 bool toggle_ant = false;
2382 2446
2383 /* Override starting rate (index 0) if needed for debug purposes */ 2447 memcpy(&rate, initial_rate, sizeof(rate));
2384 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2385 2448
2386 /* Interpret new_rate (rate_n_flags) */ 2449 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2387 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2388 &tbl_type, &rate_idx);
2389 2450
2390 /* How many times should we repeat the initial rate? */ 2451 if (is_siso(&rate)) {
2391 if (is_legacy(tbl_type.lq_type)) { 2452 num_rates = RS_INITIAL_SISO_NUM_RATES;
2392 ant_toggle_cnt = 1; 2453 num_retries = RS_HT_VHT_RETRIES_PER_RATE;
2393 repeat_rate = IWL_NUMBER_TRY; 2454 } else if (is_mimo(&rate)) {
2455 num_rates = RS_INITIAL_MIMO_NUM_RATES;
2456 num_retries = RS_HT_VHT_RETRIES_PER_RATE;
2394 } else { 2457 } else {
2395 repeat_rate = min(IWL_HT_NUMBER_TRY, 2458 num_rates = RS_INITIAL_LEGACY_NUM_RATES;
2396 LINK_QUAL_AGG_DISABLE_START_DEF - 1); 2459 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2460 toggle_ant = true;
2397 } 2461 }
2398 2462
2399 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0; 2463 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2400 2464 num_rates, num_retries, valid_tx_ant,
2401 /* Fill 1st table entry (index 0) */ 2465 toggle_ant);
2402 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2403
2404 if (num_of_ant(tbl_type.ant_type) == 1)
2405 lq_cmd->single_stream_ant_msk = tbl_type.ant_type;
2406 else if (num_of_ant(tbl_type.ant_type) == 2)
2407 lq_cmd->dual_stream_ant_msk = tbl_type.ant_type;
2408 /* otherwise we don't modify the existing value */
2409
2410 index++;
2411 repeat_rate--;
2412 if (mvm)
2413 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2414
2415 /* Fill rest of rate table */
2416 while (index < LINK_QUAL_MAX_RETRY_NUM) {
2417 /* Repeat initial/next rate.
2418 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2419 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2420 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2421 if (is_legacy(tbl_type.lq_type)) {
2422 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2423 ant_toggle_cnt++;
2424 else if (mvm &&
2425 rs_toggle_antenna(valid_tx_ant,
2426 &new_rate, &tbl_type))
2427 ant_toggle_cnt = 1;
2428 }
2429 2466
2430 /* Override next rate if needed for debug purposes */ 2467 rs_get_lower_rate_down_column(lq_sta, &rate);
2431 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2432 2468
2433 /* Fill next table entry */ 2469 if (is_siso(&rate)) {
2434 lq_cmd->rs_table[index] = 2470 num_rates = RS_SECONDARY_SISO_NUM_RATES;
2435 cpu_to_le32(new_rate); 2471 num_retries = RS_SECONDARY_SISO_RETRIES;
2436 repeat_rate--; 2472 } else if (is_legacy(&rate)) {
2437 index++; 2473 num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
2438 } 2474 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2475 } else {
2476 WARN_ON_ONCE(1);
2477 }
2439 2478
2440 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2479 toggle_ant = true;
2441 &rate_idx);
2442
2443 /* Indicate to uCode which entries might be MIMO.
2444 * If initial rate was MIMO, this will finally end up
2445 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2446 if (is_mimo(tbl_type.lq_type))
2447 lq_cmd->mimo_delim = index;
2448
2449 /* Get next rate */
2450 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2451 use_ht_possible);
2452
2453 /* How many times should we repeat the next rate? */
2454 if (is_legacy(tbl_type.lq_type)) {
2455 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2456 ant_toggle_cnt++;
2457 else if (mvm &&
2458 rs_toggle_antenna(valid_tx_ant,
2459 &new_rate, &tbl_type))
2460 ant_toggle_cnt = 1;
2461
2462 repeat_rate = IWL_NUMBER_TRY;
2463 } else {
2464 repeat_rate = IWL_HT_NUMBER_TRY;
2465 }
2466 2480
2467 /* Don't allow HT rates after next pass. 2481 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2468 * rs_get_lower_rate() will change type to LQ_LEGACY_A 2482 num_rates, num_retries, valid_tx_ant,
2469 * or LQ_LEGACY_G. 2483 toggle_ant);
2470 */
2471 use_ht_possible = 0;
2472 2484
2473 /* Override next rate if needed for debug purposes */ 2485 rs_get_lower_rate_down_column(lq_sta, &rate);
2474 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2475 2486
2476 /* Fill next table entry */ 2487 num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
2477 lq_cmd->rs_table[index] = cpu_to_le32(new_rate); 2488 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2478 2489
2479 index++; 2490 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2480 repeat_rate--; 2491 num_rates, num_retries, valid_tx_ant,
2481 } 2492 toggle_ant);
2493
2494}
2495
2496static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2497 struct ieee80211_sta *sta,
2498 struct iwl_lq_sta *lq_sta,
2499 const struct rs_rate *initial_rate)
2500{
2501 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2502 u8 ant = initial_rate->ant;
2503
2504#ifdef CONFIG_MAC80211_DEBUGFS
2505 if (lq_sta->dbg_fixed_rate) {
2506 rs_build_rates_table_from_fixed(mvm, lq_cmd,
2507 lq_sta->band,
2508 lq_sta->dbg_fixed_rate);
2509 ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
2510 RATE_MCS_ANT_POS;
2511 } else
2512#endif
2513 rs_build_rates_table(mvm, lq_sta, initial_rate);
2514
2515 if (num_of_ant(ant) == 1)
2516 lq_cmd->single_stream_ant_msk = ant;
2482 2517
2483 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 2518 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2484 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 2519 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
@@ -2512,31 +2547,83 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2512} 2547}
2513 2548
2514#ifdef CONFIG_MAC80211_DEBUGFS 2549#ifdef CONFIG_MAC80211_DEBUGFS
2515static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 2550static int rs_pretty_print_rate(char *buf, const u32 rate)
2516 u32 *rate_n_flags)
2517{ 2551{
2518 struct iwl_mvm *mvm;
2519 u8 valid_tx_ant;
2520 u8 ant_sel_tx;
2521 2552
2522 mvm = lq_sta->drv; 2553 char *type, *bw;
2523 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); 2554 u8 mcs = 0, nss = 0;
2524 if (lq_sta->dbg_fixed_rate) { 2555 u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
2525 ant_sel_tx = 2556
2526 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) 2557 if (!(rate & RATE_MCS_HT_MSK) &&
2527 >> RATE_MCS_ANT_POS); 2558 !(rate & RATE_MCS_VHT_MSK)) {
2528 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) { 2559 int index = iwl_hwrate_to_plcp_idx(rate);
2529 *rate_n_flags = lq_sta->dbg_fixed_rate; 2560
2530 IWL_DEBUG_RATE(mvm, "Fixed rate ON\n"); 2561 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
2531 } else { 2562 rs_pretty_ant(ant),
2532 lq_sta->dbg_fixed_rate = 0; 2563 index == IWL_RATE_INVALID ? "BAD" :
2533 IWL_ERR(mvm, 2564 iwl_rate_mcs[index].mbps);
2534 "Invalid antenna selection 0x%X, Valid is 0x%X\n", 2565 }
2535 ant_sel_tx, valid_tx_ant); 2566
2536 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2567 if (rate & RATE_MCS_VHT_MSK) {
2537 } 2568 type = "VHT";
2569 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2570 nss = ((rate & RATE_VHT_MCS_NSS_MSK)
2571 >> RATE_VHT_MCS_NSS_POS) + 1;
2572 } else if (rate & RATE_MCS_HT_MSK) {
2573 type = "HT";
2574 mcs = rate & RATE_HT_MCS_INDEX_MSK;
2538 } else { 2575 } else {
2539 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2576 type = "Unknown"; /* shouldn't happen */
2577 }
2578
2579 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2580 case RATE_MCS_CHAN_WIDTH_20:
2581 bw = "20Mhz";
2582 break;
2583 case RATE_MCS_CHAN_WIDTH_40:
2584 bw = "40Mhz";
2585 break;
2586 case RATE_MCS_CHAN_WIDTH_80:
2587 bw = "80Mhz";
2588 break;
2589 case RATE_MCS_CHAN_WIDTH_160:
2590 bw = "160Mhz";
2591 break;
2592 default:
2593 bw = "BAD BW";
2594 }
2595
2596 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
2597 type, rs_pretty_ant(ant), bw, mcs, nss,
2598 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
2599 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
2600 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
2601 (rate & RATE_MCS_BF_MSK) ? "BF " : "",
2602 (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
2603}
2604
2605/**
2606 * Program the device to use fixed rate for frame transmit
2607 * This is for debugging/testing only
2608 * once the device start use fixed rate, we need to reload the module
2609 * to being back the normal operation.
2610 */
2611static void rs_program_fix_rate(struct iwl_mvm *mvm,
2612 struct iwl_lq_sta *lq_sta)
2613{
2614 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2615 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2616 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2617
2618 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
2619 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
2620
2621 if (lq_sta->dbg_fixed_rate) {
2622 struct rs_rate rate;
2623 rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate,
2624 lq_sta->band, &rate);
2625 rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
2626 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
2540 } 2627 }
2541} 2628}
2542 2629
@@ -2572,15 +2659,14 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2572 char *buff; 2659 char *buff;
2573 int desc = 0; 2660 int desc = 0;
2574 int i = 0; 2661 int i = 0;
2575 int index = 0;
2576 ssize_t ret; 2662 ssize_t ret;
2577 2663
2578 struct iwl_lq_sta *lq_sta = file->private_data; 2664 struct iwl_lq_sta *lq_sta = file->private_data;
2579 struct iwl_mvm *mvm; 2665 struct iwl_mvm *mvm;
2580 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2666 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2581 2667 struct rs_rate *rate = &tbl->rate;
2582 mvm = lq_sta->drv; 2668 mvm = lq_sta->drv;
2583 buff = kmalloc(1024, GFP_KERNEL); 2669 buff = kmalloc(2048, GFP_KERNEL);
2584 if (!buff) 2670 if (!buff)
2585 return -ENOMEM; 2671 return -ENOMEM;
2586 2672
@@ -2595,23 +2681,23 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2595 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", 2681 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2596 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2682 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2597 desc += sprintf(buff+desc, "lq type %s\n", 2683 desc += sprintf(buff+desc, "lq type %s\n",
2598 (is_legacy(tbl->lq_type)) ? "legacy" : 2684 (is_legacy(rate)) ? "legacy" :
2599 is_vht(tbl->lq_type) ? "VHT" : "HT"); 2685 is_vht(rate) ? "VHT" : "HT");
2600 if (is_ht(tbl->lq_type)) { 2686 if (!is_legacy(rate)) {
2601 desc += sprintf(buff+desc, " %s", 2687 desc += sprintf(buff+desc, " %s",
2602 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); 2688 (is_siso(rate)) ? "SISO" : "MIMO2");
2603 desc += sprintf(buff+desc, " %s", 2689 desc += sprintf(buff+desc, " %s",
2604 (is_ht20(tbl)) ? "20MHz" : 2690 (is_ht20(rate)) ? "20MHz" :
2605 (is_ht40(tbl)) ? "40MHz" : 2691 (is_ht40(rate)) ? "40MHz" :
2606 (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); 2692 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
2607 desc += sprintf(buff+desc, " %s %s\n", 2693 desc += sprintf(buff+desc, " %s %s\n",
2608 (tbl->is_SGI) ? "SGI" : "", 2694 (rate->sgi) ? "SGI" : "NGI",
2609 (lq_sta->is_agg) ? "AGG on" : ""); 2695 (lq_sta->is_agg) ? "AGG on" : "");
2610 } 2696 }
2611 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 2697 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2612 lq_sta->last_rate_n_flags); 2698 lq_sta->last_rate_n_flags);
2613 desc += sprintf(buff+desc, 2699 desc += sprintf(buff+desc,
2614 "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", 2700 "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n",
2615 lq_sta->lq.flags, 2701 lq_sta->lq.flags,
2616 lq_sta->lq.mimo_delim, 2702 lq_sta->lq.mimo_delim,
2617 lq_sta->lq.single_stream_ant_msk, 2703 lq_sta->lq.single_stream_ant_msk,
@@ -2631,19 +2717,10 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2631 lq_sta->lq.initial_rate_index[3]); 2717 lq_sta->lq.initial_rate_index[3]);
2632 2718
2633 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 2719 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2634 index = iwl_hwrate_to_plcp_idx( 2720 u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]);
2635 le32_to_cpu(lq_sta->lq.rs_table[i])); 2721
2636 if (is_legacy(tbl->lq_type)) { 2722 desc += sprintf(buff+desc, " rate[%d] 0x%X ", i, r);
2637 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n", 2723 desc += rs_pretty_print_rate(buff+desc, r);
2638 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2639 iwl_rate_mcs[index].mbps);
2640 } else {
2641 desc += sprintf(buff+desc,
2642 " rate[%d] 0x%X %smbps (%s)\n",
2643 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2644 iwl_rate_mcs[index].mbps,
2645 iwl_rate_mcs[index].mcs);
2646 }
2647 } 2724 }
2648 2725
2649 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2726 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
@@ -2665,6 +2742,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2665 int i, j; 2742 int i, j;
2666 ssize_t ret; 2743 ssize_t ret;
2667 struct iwl_scale_tbl_info *tbl; 2744 struct iwl_scale_tbl_info *tbl;
2745 struct rs_rate *rate;
2668 struct iwl_lq_sta *lq_sta = file->private_data; 2746 struct iwl_lq_sta *lq_sta = file->private_data;
2669 2747
2670 buff = kmalloc(1024, GFP_KERNEL); 2748 buff = kmalloc(1024, GFP_KERNEL);
@@ -2673,16 +2751,17 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2673 2751
2674 for (i = 0; i < LQ_SIZE; i++) { 2752 for (i = 0; i < LQ_SIZE; i++) {
2675 tbl = &(lq_sta->lq_info[i]); 2753 tbl = &(lq_sta->lq_info[i]);
2754 rate = &tbl->rate;
2676 desc += sprintf(buff+desc, 2755 desc += sprintf(buff+desc,
2677 "%s type=%d SGI=%d BW=%s DUP=0\n" 2756 "%s type=%d SGI=%d BW=%s DUP=0\n"
2678 "rate=0x%X\n", 2757 "index=%d\n",
2679 lq_sta->active_tbl == i ? "*" : "x", 2758 lq_sta->active_tbl == i ? "*" : "x",
2680 tbl->lq_type, 2759 rate->type,
2681 tbl->is_SGI, 2760 rate->sgi,
2682 is_ht20(tbl) ? "20Mhz" : 2761 is_ht20(rate) ? "20Mhz" :
2683 is_ht40(tbl) ? "40Mhz" : 2762 is_ht40(rate) ? "40Mhz" :
2684 is_ht80(tbl) ? "80Mhz" : "ERR", 2763 is_ht80(rate) ? "80Mhz" : "ERR",
2685 tbl->current_rate); 2764 rate->index);
2686 for (j = 0; j < IWL_RATE_COUNT; j++) { 2765 for (j = 0; j < IWL_RATE_COUNT; j++) {
2687 desc += sprintf(buff+desc, 2766 desc += sprintf(buff+desc,
2688 "counter=%d success=%d %%=%d\n", 2767 "counter=%d success=%d %%=%d\n",
@@ -2746,6 +2825,7 @@ static struct rate_control_ops rs_mvm_ops = {
2746 .free = rs_free, 2825 .free = rs_free,
2747 .alloc_sta = rs_alloc_sta, 2826 .alloc_sta = rs_alloc_sta,
2748 .free_sta = rs_free_sta, 2827 .free_sta = rs_free_sta,
2828 .rate_update = rs_rate_update,
2749#ifdef CONFIG_MAC80211_DEBUGFS 2829#ifdef CONFIG_MAC80211_DEBUGFS
2750 .add_sta_debugfs = rs_add_debugfs, 2830 .add_sta_debugfs = rs_add_debugfs,
2751 .remove_sta_debugfs = rs_remove_debugfs, 2831 .remove_sta_debugfs = rs_remove_debugfs,
@@ -2778,13 +2858,13 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
2778 2858
2779 if (enable) { 2859 if (enable) {
2780 if (mvmsta->tx_protection == 0) 2860 if (mvmsta->tx_protection == 0)
2781 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 2861 lq->flags |= LQ_FLAG_USE_RTS_MSK;
2782 mvmsta->tx_protection++; 2862 mvmsta->tx_protection++;
2783 } else { 2863 } else {
2784 mvmsta->tx_protection--; 2864 mvmsta->tx_protection--;
2785 if (mvmsta->tx_protection == 0) 2865 if (mvmsta->tx_protection == 0)
2786 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK; 2866 lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
2787 } 2867 }
2788 2868
2789 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false); 2869 return iwl_mvm_send_lq_cmd(mvm, lq, false);
2790} 2870}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 5d5344f7070b..7bc6404f6986 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -155,38 +155,7 @@ enum {
155#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */ 155#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
156#define IWL_RATE_HIGH_TH 10880 /* 85% */ 156#define IWL_RATE_HIGH_TH 10880 /* 85% */
157#define IWL_RATE_INCREASE_TH 6400 /* 50% */ 157#define IWL_RATE_INCREASE_TH 6400 /* 50% */
158#define IWL_RATE_DECREASE_TH 1920 /* 15% */ 158#define RS_SR_FORCE_DECREASE 1920 /* 15% */
159
160/* possible actions when in legacy mode */
161enum {
162 IWL_LEGACY_SWITCH_ANTENNA,
163 IWL_LEGACY_SWITCH_SISO,
164 IWL_LEGACY_SWITCH_MIMO2,
165 IWL_LEGACY_FIRST_ACTION = IWL_LEGACY_SWITCH_ANTENNA,
166 IWL_LEGACY_LAST_ACTION = IWL_LEGACY_SWITCH_MIMO2,
167};
168
169/* possible actions when in siso mode */
170enum {
171 IWL_SISO_SWITCH_ANTENNA,
172 IWL_SISO_SWITCH_MIMO2,
173 IWL_SISO_SWITCH_GI,
174 IWL_SISO_FIRST_ACTION = IWL_SISO_SWITCH_ANTENNA,
175 IWL_SISO_LAST_ACTION = IWL_SISO_SWITCH_GI,
176};
177
178/* possible actions when in mimo mode */
179enum {
180 IWL_MIMO2_SWITCH_SISO_A,
181 IWL_MIMO2_SWITCH_SISO_B,
182 IWL_MIMO2_SWITCH_GI,
183 IWL_MIMO2_FIRST_ACTION = IWL_MIMO2_SWITCH_SISO_A,
184 IWL_MIMO2_LAST_ACTION = IWL_MIMO2_SWITCH_GI,
185};
186
187#define IWL_MAX_SEARCH IWL_MIMO2_LAST_ACTION
188
189#define IWL_ACTION_LIMIT 3 /* # possible actions */
190 159
191#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ 160#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
192#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) 161#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
@@ -224,22 +193,45 @@ enum iwl_table_type {
224 LQ_MAX, 193 LQ_MAX,
225}; 194};
226 195
227#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A)) 196struct rs_rate {
228#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO) 197 int index;
229#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2) 198 enum iwl_table_type type;
230#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO) 199 u8 ant;
231#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2) 200 u32 bw;
232#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl)) 201 bool sgi;
233#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl)) 202};
234#define is_mimo(tbl) (is_mimo2(tbl)) 203
235#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl)) 204
236#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl)) 205#define is_type_legacy(type) (((type) == LQ_LEGACY_G) || \
237#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A) 206 ((type) == LQ_LEGACY_A))
238#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G) 207#define is_type_ht_siso(type) ((type) == LQ_HT_SISO)
239 208#define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2)
240#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20) 209#define is_type_vht_siso(type) ((type) == LQ_VHT_SISO)
241#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40) 210#define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2)
242#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80) 211#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type))
212#define is_type_mimo2(type) (is_type_ht_mimo2(type) || is_type_vht_mimo2(type))
213#define is_type_mimo(type) (is_type_mimo2(type))
214#define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type))
215#define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type))
216#define is_type_a_band(type) ((type) == LQ_LEGACY_A)
217#define is_type_g_band(type) ((type) == LQ_LEGACY_G)
218
219#define is_legacy(rate) is_type_legacy((rate)->type)
220#define is_ht_siso(rate) is_type_ht_siso((rate)->type)
221#define is_ht_mimo2(rate) is_type_ht_mimo2((rate)->type)
222#define is_vht_siso(rate) is_type_vht_siso((rate)->type)
223#define is_vht_mimo2(rate) is_type_vht_mimo2((rate)->type)
224#define is_siso(rate) is_type_siso((rate)->type)
225#define is_mimo2(rate) is_type_mimo2((rate)->type)
226#define is_mimo(rate) is_type_mimo((rate)->type)
227#define is_ht(rate) is_type_ht((rate)->type)
228#define is_vht(rate) is_type_vht((rate)->type)
229#define is_a_band(rate) is_type_a_band((rate)->type)
230#define is_g_band(rate) is_type_g_band((rate)->type)
231
232#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20)
233#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40)
234#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80)
243 235
244#define IWL_MAX_MCS_DISPLAY_SIZE 12 236#define IWL_MAX_MCS_DISPLAY_SIZE 12
245 237
@@ -257,7 +249,23 @@ struct iwl_rate_scale_data {
257 s32 success_ratio; /* per-cent * 128 */ 249 s32 success_ratio; /* per-cent * 128 */
258 s32 counter; /* number of frames attempted */ 250 s32 counter; /* number of frames attempted */
259 s32 average_tpt; /* success ratio * expected throughput */ 251 s32 average_tpt; /* success ratio * expected throughput */
260 unsigned long stamp; 252};
253
254/* Possible Tx columns
255 * Tx Column = a combo of legacy/siso/mimo x antenna x SGI
256 */
257enum rs_column {
258 RS_COLUMN_LEGACY_ANT_A = 0,
259 RS_COLUMN_LEGACY_ANT_B,
260 RS_COLUMN_SISO_ANT_A,
261 RS_COLUMN_SISO_ANT_B,
262 RS_COLUMN_SISO_ANT_A_SGI,
263 RS_COLUMN_SISO_ANT_B_SGI,
264 RS_COLUMN_MIMO2,
265 RS_COLUMN_MIMO2_SGI,
266
267 RS_COLUMN_LAST = RS_COLUMN_MIMO2_SGI,
268 RS_COLUMN_INVALID,
261}; 269};
262 270
263/** 271/**
@@ -267,17 +275,18 @@ struct iwl_rate_scale_data {
267 * one for "active", and one for "search". 275 * one for "active", and one for "search".
268 */ 276 */
269struct iwl_scale_tbl_info { 277struct iwl_scale_tbl_info {
270 enum iwl_table_type lq_type; 278 struct rs_rate rate;
271 u8 ant_type; 279 enum rs_column column;
272 u8 is_SGI; /* 1 = short guard interval */
273 u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */
274 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
275 u8 max_search; /* maximun number of tables we can search */
276 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 280 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
277 u32 current_rate; /* rate_n_flags, uCode API format */
278 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ 281 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
279}; 282};
280 283
284enum {
285 RS_STATE_SEARCH_CYCLE_STARTED,
286 RS_STATE_SEARCH_CYCLE_ENDED,
287 RS_STATE_STAY_IN_COLUMN,
288};
289
281/** 290/**
282 * struct iwl_lq_sta -- driver's rate scaling private structure 291 * struct iwl_lq_sta -- driver's rate scaling private structure
283 * 292 *
@@ -285,8 +294,7 @@ struct iwl_scale_tbl_info {
285 */ 294 */
286struct iwl_lq_sta { 295struct iwl_lq_sta {
287 u8 active_tbl; /* index of active table, range 0-1 */ 296 u8 active_tbl; /* index of active table, range 0-1 */
288 u8 enable_counter; /* indicates HT mode */ 297 u8 rs_state; /* RS_STATE_* */
289 u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
290 u8 search_better_tbl; /* 1: currently trying alternate mode */ 298 u8 search_better_tbl; /* 1: currently trying alternate mode */
291 s32 last_tpt; 299 s32 last_tpt;
292 300
@@ -299,12 +307,13 @@ struct iwl_lq_sta {
299 u32 total_success; /* total successful frames, any/all rates */ 307 u32 total_success; /* total successful frames, any/all rates */
300 u64 flush_timer; /* time staying in mode before new search */ 308 u64 flush_timer; /* time staying in mode before new search */
301 309
302 u8 action_counter; /* # mode-switch actions tried */ 310 u32 visited_columns; /* Bitmask marking which Tx columns were
311 * explored during a search cycle
312 */
303 bool is_vht; 313 bool is_vht;
304 enum ieee80211_band band; 314 enum ieee80211_band band;
305 315
306 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 316 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
307 u32 supp_rates;
308 u16 active_legacy_rate; 317 u16 active_legacy_rate;
309 u16 active_siso_rate; 318 u16 active_siso_rate;
310 u16 active_mimo2_rate; 319 u16 active_mimo2_rate;
@@ -328,32 +337,11 @@ struct iwl_lq_sta {
328 u32 last_rate_n_flags; 337 u32 last_rate_n_flags;
329 /* packets destined for this STA are aggregated */ 338 /* packets destined for this STA are aggregated */
330 u8 is_agg; 339 u8 is_agg;
331 /* BT traffic this sta was last updated in */
332 u8 last_bt_traffic;
333};
334
335enum iwl_bt_coex_profile_traffic_load {
336 IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
337 IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
338 IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
339 IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
340/*
341 * There are no more even though below is a u8, the
342 * indication from the BT device only has two bits.
343 */
344}; 340};
345 341
346
347static inline u8 num_of_ant(u8 mask)
348{
349 return !!((mask) & ANT_A) +
350 !!((mask) & ANT_B) +
351 !!((mask) & ANT_C);
352}
353
354/* Initialize station's rate scaling information after adding station */ 342/* Initialize station's rate scaling information after adding station */
355void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 343void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
356 enum ieee80211_band band); 344 enum ieee80211_band band, bool init);
357 345
358/** 346/**
359 * iwl_rate_control_register - Register the rate control algorithm callbacks 347 * iwl_rate_control_register - Register the rate control algorithm callbacks
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3a1f3982109d..a85b60f7e67e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -251,6 +251,12 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
251 stats->flag |= RX_FLAG_DECRYPTED; 251 stats->flag |= RX_FLAG_DECRYPTED;
252 return 0; 252 return 0;
253 253
254 case RX_MPDU_RES_STATUS_SEC_EXT_ENC:
255 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_MIC_OK))
256 return -1;
257 stats->flag |= RX_FLAG_DECRYPTED;
258 return 0;
259
254 default: 260 default:
255 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 261 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
256 } 262 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index dff7592e1ff8..0e0007960612 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,9 @@
70 70
71#define IWL_PLCP_QUIET_THRESH 1 71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10 72#define IWL_ACTIVE_QUIET_TIME 10
73#define LONG_OUT_TIME_PERIOD 600
74#define SHORT_OUT_TIME_PERIOD 200
75#define SUSPEND_TIME_PERIOD 100
73 76
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 77static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 78{
@@ -87,20 +90,22 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
87 return cpu_to_le16(rx_chain); 90 return cpu_to_le16(rx_chain);
88} 91}
89 92
90static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif) 93static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
94 u32 flags, bool is_assoc)
91{ 95{
92 if (vif->bss_conf.assoc) 96 if (!is_assoc)
93 return cpu_to_le32(200 * 1024);
94 else
95 return 0; 97 return 0;
98 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
99 return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
100 return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
96} 101}
97 102
98static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) 103static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
104 bool is_assoc)
99{ 105{
100 if (!vif->bss_conf.assoc) 106 if (!is_assoc)
101 return 0; 107 return 0;
102 108 return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
103 return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
104} 109}
105 110
106static inline __le32 111static inline __le32
@@ -192,7 +197,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
192 for (i = 0; i < cmd->channel_count; i++) { 197 for (i = 0; i < cmd->channel_count; i++) {
193 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 198 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
194 chan->type = cpu_to_le32(type); 199 chan->type = cpu_to_le32(type);
195 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 200 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 201 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
197 chan->active_dwell = cpu_to_le16(active_dwell); 202 chan->active_dwell = cpu_to_le16(active_dwell);
198 chan->passive_dwell = cpu_to_le16(passive_dwell); 203 chan->passive_dwell = cpu_to_le16(passive_dwell);
@@ -262,6 +267,15 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
262 return (u16)len; 267 return (u16)len;
263} 268}
264 269
270static void iwl_mvm_vif_assoc_iterator(void *data, u8 *mac,
271 struct ieee80211_vif *vif)
272{
273 bool *is_assoc = data;
274
275 if (vif->bss_conf.assoc)
276 *is_assoc = true;
277}
278
265int iwl_mvm_scan_request(struct iwl_mvm *mvm, 279int iwl_mvm_scan_request(struct iwl_mvm *mvm,
266 struct ieee80211_vif *vif, 280 struct ieee80211_vif *vif,
267 struct cfg80211_scan_request *req) 281 struct cfg80211_scan_request *req)
@@ -274,6 +288,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
274 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 288 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
275 }; 289 };
276 struct iwl_scan_cmd *cmd = mvm->scan_cmd; 290 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
291 bool is_assoc = false;
277 int ret; 292 int ret;
278 u32 status; 293 u32 status;
279 int ssid_len = 0; 294 int ssid_len = 0;
@@ -289,13 +304,17 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
289 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 304 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
290 mvm->fw->ucode_capa.max_probe_length + 305 mvm->fw->ucode_capa.max_probe_length +
291 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel))); 306 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
292 307 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
308 IEEE80211_IFACE_ITER_NORMAL,
309 iwl_mvm_vif_assoc_iterator,
310 &is_assoc);
293 cmd->channel_count = (u8)req->n_channels; 311 cmd->channel_count = (u8)req->n_channels;
294 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 312 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
295 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 313 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
296 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 314 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
297 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif); 315 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
298 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif); 316 is_assoc);
317 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
299 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 318 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
300 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 319 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
301 MAC_FILTER_IN_BEACON); 320 MAC_FILTER_IN_BEACON);
@@ -454,13 +473,18 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
454 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 473 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
455 return; 474 return;
456 475
476 if (iwl_mvm_is_radio_killed(mvm)) {
477 ieee80211_scan_completed(mvm->hw, true);
478 mvm->scan_status = IWL_MVM_SCAN_NONE;
479 return;
480 }
481
457 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, 482 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
458 scan_abort_notif, 483 scan_abort_notif,
459 ARRAY_SIZE(scan_abort_notif), 484 ARRAY_SIZE(scan_abort_notif),
460 iwl_mvm_scan_abort_notif, NULL); 485 iwl_mvm_scan_abort_notif, NULL);
461 486
462 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 487 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
463 CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL);
464 if (ret) { 488 if (ret) {
465 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); 489 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
466 /* mac80211's state will be cleaned in the fw_restart flow */ 490 /* mac80211's state will be cleaned in the fw_restart flow */
@@ -522,6 +546,12 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
522 struct cfg80211_sched_scan_request *req, 546 struct cfg80211_sched_scan_request *req,
523 struct iwl_scan_offload_cmd *scan) 547 struct iwl_scan_offload_cmd *scan)
524{ 548{
549 bool is_assoc = false;
550
551 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
552 IEEE80211_IFACE_ITER_NORMAL,
553 iwl_mvm_vif_assoc_iterator,
554 &is_assoc);
525 scan->channel_count = 555 scan->channel_count =
526 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 556 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
527 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 557 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -529,8 +559,9 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
529 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 559 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
530 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 560 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
531 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 561 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
532 scan->max_out_time = cpu_to_le32(200 * 1024); 562 scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
533 scan->suspend_time = iwl_mvm_scan_suspend_time(vif); 563 is_assoc);
564 scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
534 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 565 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
535 MAC_FILTER_IN_BEACON); 566 MAC_FILTER_IN_BEACON);
536 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 567 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
@@ -642,7 +673,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
642 channels->iter_count[index] = cpu_to_le16(1); 673 channels->iter_count[index] = cpu_to_le16(1);
643 channels->iter_interval[index] = 0; 674 channels->iter_interval[index] = 0;
644 675
645 if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) 676 if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
646 channels->type[index] |= 677 channels->type[index] |=
647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 678 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
648 679
@@ -817,11 +848,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
817 IWL_DEBUG_SCAN(mvm, 848 IWL_DEBUG_SCAN(mvm,
818 "Sending scheduled scan with filtering, filter len %d\n", 849 "Sending scheduled scan with filtering, filter len %d\n",
819 req->n_match_sets); 850 req->n_match_sets);
820 scan_req.flags |=
821 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID);
822 } else { 851 } else {
823 IWL_DEBUG_SCAN(mvm, 852 IWL_DEBUG_SCAN(mvm,
824 "Sending Scheduled scan without filtering\n"); 853 "Sending Scheduled scan without filtering\n");
854 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
825 } 855 }
826 856
827 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC, 857 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
new file mode 100644
index 000000000000..8401627c0030
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -0,0 +1,291 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "mvm.h"
64
65/* For counting bound interfaces */
66struct iwl_mvm_active_iface_iterator_data {
67 struct ieee80211_vif *ignore_vif;
68 u8 sta_vif_ap_sta_id;
69 enum iwl_sf_state sta_vif_state;
70 int num_active_macs;
71};
72
73/*
74 * Count bound interfaces which are not p2p, besides data->ignore_vif.
75 * data->station_vif will point to one bound vif of type station, if exists.
76 */
77static void iwl_mvm_bound_iface_iterator(void *_data, u8 *mac,
78 struct ieee80211_vif *vif)
79{
80 struct iwl_mvm_active_iface_iterator_data *data = _data;
81 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
82
83 if (vif == data->ignore_vif || !mvmvif->phy_ctxt ||
84 vif->type == NL80211_IFTYPE_P2P_DEVICE)
85 return;
86
87 data->num_active_macs++;
88
89 if (vif->type == NL80211_IFTYPE_STATION) {
90 data->sta_vif_ap_sta_id = mvmvif->ap_sta_id;
91 if (vif->bss_conf.assoc)
92 data->sta_vif_state = SF_FULL_ON;
93 else
94 data->sta_vif_state = SF_INIT_OFF;
95 }
96}
97
98/*
99 * Aging and idle timeouts for the different possible scenarios
100 * in SF_FULL_ON state.
101 */
102static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
103 {
104 cpu_to_le32(SF_SINGLE_UNICAST_AGING_TIMER),
105 cpu_to_le32(SF_SINGLE_UNICAST_IDLE_TIMER)
106 },
107 {
108 cpu_to_le32(SF_AGG_UNICAST_AGING_TIMER),
109 cpu_to_le32(SF_AGG_UNICAST_IDLE_TIMER)
110 },
111 {
112 cpu_to_le32(SF_MCAST_AGING_TIMER),
113 cpu_to_le32(SF_MCAST_IDLE_TIMER)
114 },
115 {
116 cpu_to_le32(SF_BA_AGING_TIMER),
117 cpu_to_le32(SF_BA_IDLE_TIMER)
118 },
119 {
120 cpu_to_le32(SF_TX_RE_AGING_TIMER),
121 cpu_to_le32(SF_TX_RE_IDLE_TIMER)
122 },
123};
124
125static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd,
126 struct ieee80211_sta *sta)
127{
128 int i, j, watermark;
129
130 sf_cmd->watermark[SF_LONG_DELAY_ON] = cpu_to_le32(SF_W_MARK_SCAN);
131
132 /*
133 * If we are in association flow - check antenna configuration
134 * capabilities of the AP station, and choose the watermark accordingly.
135 */
136 if (sta) {
137 if (sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) {
138 switch (sta->rx_nss) {
139 case 1:
140 watermark = SF_W_MARK_SISO;
141 break;
142 case 2:
143 watermark = SF_W_MARK_MIMO2;
144 break;
145 default:
146 watermark = SF_W_MARK_MIMO3;
147 break;
148 }
149 } else {
150 watermark = SF_W_MARK_LEGACY;
151 }
152 /* default watermark value for unassociated mode. */
153 } else {
154 watermark = SF_W_MARK_MIMO2;
155 }
156 sf_cmd->watermark[SF_FULL_ON] = cpu_to_le32(watermark);
157
158 for (i = 0; i < SF_NUM_SCENARIO; i++) {
159 for (j = 0; j < SF_NUM_TIMEOUT_TYPES; j++) {
160 sf_cmd->long_delay_timeouts[i][j] =
161 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER);
162 }
163 }
164 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
165 sizeof(__le32) * SF_NUM_SCENARIO * SF_NUM_TIMEOUT_TYPES);
166
167 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
168 sizeof(sf_full_timeout));
169}
170
171static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
172 enum iwl_sf_state new_state)
173{
174 struct iwl_sf_cfg_cmd sf_cmd = {
175 .state = new_state,
176 };
177 struct ieee80211_sta *sta;
178 int ret = 0;
179
180 /*
181 * If an associated AP sta changed its antenna configuration, the state
182 * will remain FULL_ON but SF parameters need to be reconsidered.
183 */
184 if (new_state != SF_FULL_ON && mvm->sf_state == new_state)
185 return 0;
186
187 switch (new_state) {
188 case SF_UNINIT:
189 break;
190 case SF_FULL_ON:
191 if (sta_id == IWL_MVM_STATION_COUNT) {
192 IWL_ERR(mvm,
193 "No station: Cannot switch SF to FULL_ON\n");
194 return -EINVAL;
195 }
196 rcu_read_lock();
197 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
198 if (IS_ERR_OR_NULL(sta)) {
199 IWL_ERR(mvm, "Invalid station id\n");
200 rcu_read_unlock();
201 return -EINVAL;
202 }
203 iwl_mvm_fill_sf_command(&sf_cmd, sta);
204 rcu_read_unlock();
205 break;
206 case SF_INIT_OFF:
207 iwl_mvm_fill_sf_command(&sf_cmd, NULL);
208 break;
209 default:
210 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n",
211 new_state);
212 return -EINVAL;
213 }
214
215 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_SF_CFG_CMD, CMD_ASYNC,
216 sizeof(sf_cmd), &sf_cmd);
217 if (!ret)
218 mvm->sf_state = new_state;
219
220 return ret;
221}
222
223/*
224 * Update Smart fifo:
225 * Count bound interfaces that are not to be removed, ignoring p2p devices,
226 * and set new state accordingly.
227 */
228int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif,
229 bool remove_vif)
230{
231 enum iwl_sf_state new_state;
232 u8 sta_id = IWL_MVM_STATION_COUNT;
233 struct iwl_mvm_vif *mvmvif = NULL;
234 struct iwl_mvm_active_iface_iterator_data data = {
235 .ignore_vif = changed_vif,
236 .sta_vif_state = SF_UNINIT,
237 .sta_vif_ap_sta_id = IWL_MVM_STATION_COUNT,
238 };
239
240 if (IWL_UCODE_API(mvm->fw->ucode_ver) < 8)
241 return 0;
242
243 /*
244 * Ignore the call if we are in HW Restart flow, or if the handled
245 * vif is a p2p device.
246 */
247 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
248 (changed_vif && changed_vif->type == NL80211_IFTYPE_P2P_DEVICE))
249 return 0;
250
251 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
252 IEEE80211_IFACE_ITER_NORMAL,
253 iwl_mvm_bound_iface_iterator,
254 &data);
255
256 /* If changed_vif exists and is not to be removed, add to the count */
257 if (changed_vif && !remove_vif)
258 data.num_active_macs++;
259
260 switch (data.num_active_macs) {
261 case 0:
262 /* If there are no active macs - change state to SF_INIT_OFF */
263 new_state = SF_INIT_OFF;
264 break;
265 case 1:
266 if (remove_vif) {
267 /* The one active mac left is of type station
268 * and we filled the relevant data during iteration
269 */
270 new_state = data.sta_vif_state;
271 sta_id = data.sta_vif_ap_sta_id;
272 } else {
273 if (WARN_ON(!changed_vif))
274 return -EINVAL;
275 if (changed_vif->type != NL80211_IFTYPE_STATION) {
276 new_state = SF_UNINIT;
277 } else if (changed_vif->bss_conf.assoc) {
278 mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
279 sta_id = mvmvif->ap_sta_id;
280 new_state = SF_FULL_ON;
281 } else {
282 new_state = SF_INIT_OFF;
283 }
284 }
285 break;
286 default:
287 /* If there are multiple active macs - change to SF_UNINIT */
288 new_state = SF_UNINIT;
289 }
290 return iwl_mvm_sf_config(mvm, sta_id, new_state);
291}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 329952363a54..ec1812133235 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -452,8 +452,15 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk)
452 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], 452 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
453 lockdep_is_held(&mvm->mutex)); 453 lockdep_is_held(&mvm->mutex));
454 454
455 /* This station is in use */ 455 /*
456 if (!IS_ERR(sta)) 456 * This station is in use or RCU-removed; the latter happens in
457 * managed mode, where mac80211 removes the station before we
458 * can remove it from firmware (we can only do that after the
459 * MAC is marked unassociated), and possibly while the deauth
460 * frame to disconnect from the AP is still queued. Then, the
461 * station pointer is -ENOENT when the last skb is reclaimed.
462 */
463 if (!IS_ERR(sta) || PTR_ERR(sta) == -ENOENT)
457 continue; 464 continue;
458 465
459 if (PTR_ERR(sta) == -EINVAL) { 466 if (PTR_ERR(sta) == -EINVAL) {
@@ -840,7 +847,7 @@ static const u8 tid_to_ac[] = {
840int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 847int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
841 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 848 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
842{ 849{
843 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 850 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
844 struct iwl_mvm_tid_data *tid_data; 851 struct iwl_mvm_tid_data *tid_data;
845 int txq_id; 852 int txq_id;
846 853
@@ -895,7 +902,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
895int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 902int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
896 struct ieee80211_sta *sta, u16 tid, u8 buf_size) 903 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
897{ 904{
898 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 905 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
899 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 906 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
900 int queue, fifo, ret; 907 int queue, fifo, ret;
901 u16 ssn; 908 u16 ssn;
@@ -932,26 +939,13 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
932 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n", 939 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
933 sta->addr, tid); 940 sta->addr, tid);
934 941
935 if (mvm->cfg->ht_params->use_rts_for_aggregation) { 942 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, false);
936 /*
937 * switch to RTS/CTS if it is the prefer protection
938 * method for HT traffic
939 * this function also sends the LQ command
940 */
941 return iwl_mvm_tx_protection(mvm, mvmsta, true);
942 /*
943 * TODO: remove the TLC_RTS flag when we tear down the last
944 * AGG session (agg_tids_count in DVM)
945 */
946 }
947
948 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
949} 943}
950 944
951int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 945int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
952 struct ieee80211_sta *sta, u16 tid) 946 struct ieee80211_sta *sta, u16 tid)
953{ 947{
954 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 948 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
955 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 949 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
956 u16 txq_id; 950 u16 txq_id;
957 int err; 951 int err;
@@ -1023,7 +1017,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1023int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1017int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1024 struct ieee80211_sta *sta, u16 tid) 1018 struct ieee80211_sta *sta, u16 tid)
1025{ 1019{
1026 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1020 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1027 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 1021 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
1028 u16 txq_id; 1022 u16 txq_id;
1029 enum iwl_mvm_agg_state old_state; 1023 enum iwl_mvm_agg_state old_state;
@@ -1123,8 +1117,8 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1123 memcpy(cmd.key, keyconf->key, keyconf->keylen); 1117 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1124 break; 1118 break;
1125 default: 1119 default:
1126 WARN_ON(1); 1120 key_flags |= cpu_to_le16(STA_KEY_FLG_EXT);
1127 return -EINVAL; 1121 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1128 } 1122 }
1129 1123
1130 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1124 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
@@ -1288,8 +1282,8 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1288 0, NULL, CMD_SYNC); 1282 0, NULL, CMD_SYNC);
1289 break; 1283 break;
1290 default: 1284 default:
1291 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher); 1285 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
1292 ret = -EINVAL; 1286 sta_id, 0, NULL, CMD_SYNC);
1293 } 1287 }
1294 1288
1295 if (ret) 1289 if (ret)
@@ -1416,7 +1410,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1416void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, 1410void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1417 struct ieee80211_sta *sta) 1411 struct ieee80211_sta *sta)
1418{ 1412{
1419 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1413 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1420 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1414 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1421 .add_modify = STA_MODE_MODIFY, 1415 .add_modify = STA_MODE_MODIFY,
1422 .sta_id = mvmsta->sta_id, 1416 .sta_id = mvmsta->sta_id,
@@ -1438,7 +1432,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1438 u16 sleep_state_flags = 1432 u16 sleep_state_flags =
1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1433 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1434 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1441 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1435 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1442 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1436 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1443 .add_modify = STA_MODE_MODIFY, 1437 .add_modify = STA_MODE_MODIFY,
1444 .sta_id = mvmsta->sta_id, 1438 .sta_id = mvmsta->sta_id,
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 4dfc359a4bdd..4968d0237dc5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -298,6 +298,12 @@ struct iwl_mvm_sta {
298 bool tt_tx_protection; 298 bool tt_tx_protection;
299}; 299};
300 300
301static inline struct iwl_mvm_sta *
302iwl_mvm_sta_from_mac80211(struct ieee80211_sta *sta)
303{
304 return (void *)sta->drv_priv;
305}
306
301/** 307/**
302 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or 308 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or
303 * broadcast) 309 * broadcast)
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h
index eb74391d91ca..0241665925f7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/testmode.h
+++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 95ce4b601fef..b4c2abaa297b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -249,12 +249,12 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
249 container_of(notif_wait, struct iwl_mvm, notif_wait); 249 container_of(notif_wait, struct iwl_mvm, notif_wait);
250 struct iwl_mvm_time_event_data *te_data = data; 250 struct iwl_mvm_time_event_data *te_data = data;
251 struct iwl_time_event_resp *resp; 251 struct iwl_time_event_resp *resp;
252 int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 252 int resp_len = iwl_rx_packet_payload_len(pkt);
253 253
254 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD)) 254 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))
255 return true; 255 return true;
256 256
257 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) { 257 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
258 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n"); 258 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n");
259 return true; 259 return true;
260 } 260 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index d9c8d6cfa2db..4a61c8c02372 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 1f3282dff513..3afa6b6bf835 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -340,7 +340,7 @@ static void check_exit_ctkill(struct work_struct *work)
340 340
341 iwl_trans_start_hw(mvm->trans); 341 iwl_trans_start_hw(mvm->trans);
342 temp = check_nic_temperature(mvm); 342 temp = check_nic_temperature(mvm);
343 iwl_trans_stop_hw(mvm->trans, false); 343 iwl_trans_stop_device(mvm->trans);
344 344
345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) { 345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n"); 346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
@@ -388,7 +388,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
388 lockdep_is_held(&mvm->mutex)); 388 lockdep_is_held(&mvm->mutex));
389 if (IS_ERR_OR_NULL(sta)) 389 if (IS_ERR_OR_NULL(sta))
390 continue; 390 continue;
391 mvmsta = (void *)sta->drv_priv; 391 mvmsta = iwl_mvm_sta_from_mac80211(sta);
392 if (enable == mvmsta->tt_tx_protection) 392 if (enable == mvmsta->tt_tx_protection)
393 continue; 393 continue;
394 err = iwl_mvm_tx_protection(mvm, mvmsta, enable); 394 err = iwl_mvm_tx_protection(mvm, mvmsta, enable);
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 43d97c33a75a..90378c217bc7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -253,8 +253,7 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
253 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen); 253 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
254 break; 254 break;
255 default: 255 default:
256 IWL_ERR(mvm, "Unknown encode cipher %x\n", keyconf->cipher); 256 tx_cmd->sec_ctl |= TX_CMD_SEC_EXT;
257 break;
258 } 257 }
259} 258}
260 259
@@ -276,6 +275,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
276 return NULL; 275 return NULL;
277 276
278 memset(dev_cmd, 0, sizeof(*dev_cmd)); 277 memset(dev_cmd, 0, sizeof(*dev_cmd));
278 dev_cmd->hdr.cmd = TX_CMD;
279 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; 279 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
280 280
281 if (info->control.hw_key) 281 if (info->control.hw_key)
@@ -361,7 +361,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
361 u8 txq_id = info->hw_queue; 361 u8 txq_id = info->hw_queue;
362 bool is_data_qos = false, is_ampdu = false; 362 bool is_data_qos = false, is_ampdu = false;
363 363
364 mvmsta = (void *)sta->drv_priv; 364 mvmsta = iwl_mvm_sta_from_mac80211(sta);
365 fc = hdr->frame_control; 365 fc = hdr->frame_control;
366 366
367 if (WARN_ON_ONCE(!mvmsta)) 367 if (WARN_ON_ONCE(!mvmsta))
@@ -390,7 +390,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
390 seq_number &= IEEE80211_SCTL_SEQ; 390 seq_number &= IEEE80211_SCTL_SEQ;
391 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 391 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
392 hdr->seq_ctrl |= cpu_to_le16(seq_number); 392 hdr->seq_ctrl |= cpu_to_le16(seq_number);
393 seq_number += 0x10;
394 is_data_qos = true; 393 is_data_qos = true;
395 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU; 394 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
396 } 395 }
@@ -407,13 +406,13 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
407 } 406 }
408 407
409 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id, 408 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
410 tid, txq_id, seq_number); 409 tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));
411 410
412 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id)) 411 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
413 goto drop_unlock_sta; 412 goto drop_unlock_sta;
414 413
415 if (is_data_qos && !ieee80211_has_morefrags(fc)) 414 if (is_data_qos && !ieee80211_has_morefrags(fc))
416 mvmsta->tid_data[tid].seq_number = seq_number; 415 mvmsta->tid_data[tid].seq_number = seq_number + 0x10;
417 416
418 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
419 418
@@ -432,7 +431,7 @@ drop:
432static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, 431static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
433 struct ieee80211_sta *sta, u8 tid) 432 struct ieee80211_sta *sta, u8 tid)
434{ 433{
435 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 434 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
436 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 435 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
437 struct ieee80211_vif *vif = mvmsta->vif; 436 struct ieee80211_vif *vif = mvmsta->vif;
438 437
@@ -662,7 +661,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
662 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 661 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
663 662
664 if (!IS_ERR_OR_NULL(sta)) { 663 if (!IS_ERR_OR_NULL(sta)) {
665 mvmsta = (void *)sta->drv_priv; 664 mvmsta = iwl_mvm_sta_from_mac80211(sta);
666 665
667 if (tid != IWL_TID_NON_QOS) { 666 if (tid != IWL_TID_NON_QOS) {
668 struct iwl_mvm_tid_data *tid_data = 667 struct iwl_mvm_tid_data *tid_data =
@@ -704,7 +703,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
704 */ 703 */
705 spin_lock_bh(&mvmsta->lock); 704 spin_lock_bh(&mvmsta->lock);
706 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 705 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
707 if (IS_ERR_OR_NULL(sta)) { 706 if (!sta || PTR_ERR(sta) == -EBUSY) {
708 /* 707 /*
709 * Station disappeared in the meantime: 708 * Station disappeared in the meantime:
710 * so we are draining. 709 * so we are draining.
@@ -713,7 +712,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
713 schedule_work(&mvm->sta_drained_wk); 712 schedule_work(&mvm->sta_drained_wk);
714 } 713 }
715 spin_unlock_bh(&mvmsta->lock); 714 spin_unlock_bh(&mvmsta->lock);
716 } else if (!mvmsta) { 715 } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) {
717 /* Tx response without STA, so we are draining */ 716 /* Tx response without STA, so we are draining */
718 set_bit(sta_id, mvm->sta_drained); 717 set_bit(sta_id, mvm->sta_drained);
719 schedule_work(&mvm->sta_drained_wk); 718 schedule_work(&mvm->sta_drained_wk);
@@ -793,7 +792,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
793 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 792 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
794 793
795 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) { 794 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
796 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 795 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
797 mvmsta->tid_data[tid].rate_n_flags = 796 mvmsta->tid_data[tid].rate_n_flags =
798 le32_to_cpu(tx_resp->initial_rate); 797 le32_to_cpu(tx_resp->initial_rate);
799 } 798 }
@@ -849,7 +848,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
849 return 0; 848 return 0;
850 } 849 }
851 850
852 mvmsta = (void *)sta->drv_priv; 851 mvmsta = iwl_mvm_sta_from_mac80211(sta);
853 tid_data = &mvmsta->tid_data[tid]; 852 tid_data = &mvmsta->tid_data[tid];
854 853
855 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d", 854 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index ed69e9b78e82..a4a5e25623c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -168,8 +168,8 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
168 goto out_free_resp; 168 goto out_free_resp;
169 } 169 }
170 170
171 resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 171 resp_len = iwl_rx_packet_payload_len(pkt);
172 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) { 172 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
173 ret = -EIO; 173 ret = -EIO;
174 goto out_free_resp; 174 goto out_free_resp;
175 } 175 }
@@ -486,22 +486,18 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
486 * this case to clear the state indicating that station creation is in 486 * this case to clear the state indicating that station creation is in
487 * progress. 487 * progress.
488 */ 488 */
489int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 489int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
490 u8 flags, bool init)
491{ 490{
492 struct iwl_host_cmd cmd = { 491 struct iwl_host_cmd cmd = {
493 .id = LQ_CMD, 492 .id = LQ_CMD,
494 .len = { sizeof(struct iwl_lq_cmd), }, 493 .len = { sizeof(struct iwl_lq_cmd), },
495 .flags = flags, 494 .flags = init ? CMD_SYNC : CMD_ASYNC,
496 .data = { lq, }, 495 .data = { lq, },
497 }; 496 };
498 497
499 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT)) 498 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
500 return -EINVAL; 499 return -EINVAL;
501 500
502 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
503 return -EINVAL;
504
505 return iwl_mvm_send_cmd(mvm, &cmd); 501 return iwl_mvm_send_cmd(mvm, &cmd);
506} 502}
507 503
@@ -522,6 +518,11 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
522 int i; 518 int i;
523 519
524 lockdep_assert_held(&mvm->mutex); 520 lockdep_assert_held(&mvm->mutex);
521
522 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
523 if (num_of_ant(iwl_fw_valid_rx_ant(mvm->fw)) == 1)
524 return;
525
525 mvmvif = iwl_mvm_vif_from_mac80211(vif); 526 mvmvif = iwl_mvm_vif_from_mac80211(vif);
526 mvmvif->smps_requests[req_type] = smps_request; 527 mvmvif->smps_requests[req_type] = smps_request;
527 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) { 528 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index e6272546395a..3040924f5f3c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -297,6 +297,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
297 {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)}, 297 {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
298 {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)}, 298 {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
299 {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)}, 299 {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)},
301 {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)},
302 {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, 303 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
301 {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)}, 304 {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
302 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, 305 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
@@ -350,6 +353,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
350 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, 353 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
351 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, 354 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
352 {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, 355 {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
356 {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
357 {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
353 358
354/* 7265 Series */ 359/* 7265 Series */
355 {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, 360 {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 051268c037b1..e851f26fd44c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -256,13 +256,13 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
256 * @hw_base: pci hardware address support 256 * @hw_base: pci hardware address support
257 * @ucode_write_complete: indicates that the ucode has been copied. 257 * @ucode_write_complete: indicates that the ucode has been copied.
258 * @ucode_write_waitq: wait queue for uCode load 258 * @ucode_write_waitq: wait queue for uCode load
259 * @status - transport specific status flags
260 * @cmd_queue - command queue number 259 * @cmd_queue - command queue number
261 * @rx_buf_size_8k: 8 kB RX buffer size 260 * @rx_buf_size_8k: 8 kB RX buffer size
262 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) 261 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
263 * @rx_page_order: page order for receive buffer size 262 * @rx_page_order: page order for receive buffer size
264 * @wd_timeout: queue watchdog timeout (jiffies) 263 * @wd_timeout: queue watchdog timeout (jiffies)
265 * @reg_lock: protect hw register access 264 * @reg_lock: protect hw register access
265 * @cmd_in_flight: true when we have a host command in flight
266 */ 266 */
267struct iwl_trans_pcie { 267struct iwl_trans_pcie {
268 struct iwl_rxq rxq; 268 struct iwl_rxq rxq;
@@ -274,7 +274,6 @@ struct iwl_trans_pcie {
274 __le32 *ict_tbl; 274 __le32 *ict_tbl;
275 dma_addr_t ict_tbl_dma; 275 dma_addr_t ict_tbl_dma;
276 int ict_index; 276 int ict_index;
277 u32 inta;
278 bool use_ict; 277 bool use_ict;
279 struct isr_statistics isr_stats; 278 struct isr_statistics isr_stats;
280 279
@@ -296,7 +295,6 @@ struct iwl_trans_pcie {
296 wait_queue_head_t ucode_write_waitq; 295 wait_queue_head_t ucode_write_waitq;
297 wait_queue_head_t wait_command_queue; 296 wait_queue_head_t wait_command_queue;
298 297
299 unsigned long status;
300 u8 cmd_queue; 298 u8 cmd_queue;
301 u8 cmd_fifo; 299 u8 cmd_fifo;
302 u8 n_no_reclaim_cmds; 300 u8 n_no_reclaim_cmds;
@@ -313,24 +311,7 @@ struct iwl_trans_pcie {
313 311
314 /*protect hw register */ 312 /*protect hw register */
315 spinlock_t reg_lock; 313 spinlock_t reg_lock;
316}; 314 bool cmd_in_flight;
317
318/**
319 * enum iwl_pcie_status: status of the PCIe transport
320 * @STATUS_HCMD_ACTIVE: a SYNC command is being processed
321 * @STATUS_DEVICE_ENABLED: APM is enabled
322 * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up)
323 * @STATUS_INT_ENABLED: interrupts are enabled
324 * @STATUS_RFKILL: the HW RFkill switch is in KILL position
325 * @STATUS_FW_ERROR: the fw is in error state
326 */
327enum iwl_pcie_status {
328 STATUS_HCMD_ACTIVE,
329 STATUS_DEVICE_ENABLED,
330 STATUS_TPOWER_PMI,
331 STATUS_INT_ENABLED,
332 STATUS_RFKILL,
333 STATUS_FW_ERROR,
334}; 315};
335 316
336#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 317#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
@@ -363,7 +344,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans);
363/***************************************************** 344/*****************************************************
364* ICT - interrupt handling 345* ICT - interrupt handling
365******************************************************/ 346******************************************************/
366irqreturn_t iwl_pcie_isr_ict(int irq, void *data); 347irqreturn_t iwl_pcie_isr(int irq, void *data);
367int iwl_pcie_alloc_ict(struct iwl_trans *trans); 348int iwl_pcie_alloc_ict(struct iwl_trans *trans);
368void iwl_pcie_free_ict(struct iwl_trans *trans); 349void iwl_pcie_free_ict(struct iwl_trans *trans);
369void iwl_pcie_reset_ict(struct iwl_trans *trans); 350void iwl_pcie_reset_ict(struct iwl_trans *trans);
@@ -399,8 +380,7 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans);
399******************************************************/ 380******************************************************/
400static inline void iwl_disable_interrupts(struct iwl_trans *trans) 381static inline void iwl_disable_interrupts(struct iwl_trans *trans)
401{ 382{
402 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 383 clear_bit(STATUS_INT_ENABLED, &trans->status);
403 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
404 384
405 /* disable interrupts from uCode/NIC to host */ 385 /* disable interrupts from uCode/NIC to host */
406 iwl_write32(trans, CSR_INT_MASK, 0x00000000); 386 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
@@ -417,14 +397,18 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans)
417 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 397 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
418 398
419 IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); 399 IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
420 set_bit(STATUS_INT_ENABLED, &trans_pcie->status); 400 set_bit(STATUS_INT_ENABLED, &trans->status);
401 trans_pcie->inta_mask = CSR_INI_SET_MASK;
421 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); 402 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
422} 403}
423 404
424static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) 405static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
425{ 406{
407 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
408
426 IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); 409 IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
427 iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); 410 trans_pcie->inta_mask = CSR_INT_BIT_RF_KILL;
411 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
428} 412}
429 413
430static inline void iwl_wake_queue(struct iwl_trans *trans, 414static inline void iwl_wake_queue(struct iwl_trans *trans,
@@ -477,12 +461,31 @@ static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
477 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); 461 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
478} 462}
479 463
480static inline void iwl_nic_error(struct iwl_trans *trans) 464static inline void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans,
465 u32 reg, u32 mask, u32 value)
481{ 466{
482 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 467 u32 v;
468
469#ifdef CONFIG_IWLWIFI_DEBUG
470 WARN_ON_ONCE(value & ~mask);
471#endif
472
473 v = iwl_read32(trans, reg);
474 v &= ~mask;
475 v |= value;
476 iwl_write32(trans, reg, v);
477}
483 478
484 set_bit(STATUS_FW_ERROR, &trans_pcie->status); 479static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans,
485 iwl_op_mode_nic_error(trans->op_mode); 480 u32 reg, u32 mask)
481{
482 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0);
483}
484
485static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
486 u32 reg, u32 mask)
487{
488 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
486} 489}
487 490
488#endif /* __iwl_trans_int_pcie_h__ */ 491#endif /* __iwl_trans_int_pcie_h__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index be3995afa9d0..08c23d497a02 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -148,10 +148,9 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans)
148static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, 148static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
149 struct iwl_rxq *rxq) 149 struct iwl_rxq *rxq)
150{ 150{
151 unsigned long flags;
152 u32 reg; 151 u32 reg;
153 152
154 spin_lock_irqsave(&rxq->lock, flags); 153 spin_lock(&rxq->lock);
155 154
156 if (rxq->need_update == 0) 155 if (rxq->need_update == 0)
157 goto exit_unlock; 156 goto exit_unlock;
@@ -162,11 +161,8 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
162 rxq->write_actual = (rxq->write & ~0x7); 161 rxq->write_actual = (rxq->write & ~0x7);
163 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual); 162 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
164 } else { 163 } else {
165 struct iwl_trans_pcie *trans_pcie =
166 IWL_TRANS_GET_PCIE_TRANS(trans);
167
168 /* If power-saving is in use, make sure device is awake */ 164 /* If power-saving is in use, make sure device is awake */
169 if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { 165 if (test_bit(STATUS_TPOWER_PMI, &trans->status)) {
170 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); 166 reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
171 167
172 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 168 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
@@ -193,7 +189,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
193 rxq->need_update = 0; 189 rxq->need_update = 0;
194 190
195 exit_unlock: 191 exit_unlock:
196 spin_unlock_irqrestore(&rxq->lock, flags); 192 spin_unlock(&rxq->lock);
197} 193}
198 194
199/* 195/*
@@ -212,7 +208,6 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
212 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 208 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
213 struct iwl_rxq *rxq = &trans_pcie->rxq; 209 struct iwl_rxq *rxq = &trans_pcie->rxq;
214 struct iwl_rx_mem_buffer *rxb; 210 struct iwl_rx_mem_buffer *rxb;
215 unsigned long flags;
216 211
217 /* 212 /*
218 * If the device isn't enabled - not need to try to add buffers... 213 * If the device isn't enabled - not need to try to add buffers...
@@ -222,10 +217,10 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
222 * stopped, we cannot access the HW (in particular not prph). 217 * stopped, we cannot access the HW (in particular not prph).
223 * So don't try to restock if the APM has been already stopped. 218 * So don't try to restock if the APM has been already stopped.
224 */ 219 */
225 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) 220 if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
226 return; 221 return;
227 222
228 spin_lock_irqsave(&rxq->lock, flags); 223 spin_lock(&rxq->lock);
229 while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) { 224 while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) {
230 /* The overwritten rxb must be a used one */ 225 /* The overwritten rxb must be a used one */
231 rxb = rxq->queue[rxq->write]; 226 rxb = rxq->queue[rxq->write];
@@ -242,7 +237,7 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
242 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; 237 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
243 rxq->free_count--; 238 rxq->free_count--;
244 } 239 }
245 spin_unlock_irqrestore(&rxq->lock, flags); 240 spin_unlock(&rxq->lock);
246 /* If the pre-allocated buffer pool is dropping low, schedule to 241 /* If the pre-allocated buffer pool is dropping low, schedule to
247 * refill it */ 242 * refill it */
248 if (rxq->free_count <= RX_LOW_WATERMARK) 243 if (rxq->free_count <= RX_LOW_WATERMARK)
@@ -251,9 +246,9 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans)
251 /* If we've added more space for the firmware to place data, tell it. 246 /* If we've added more space for the firmware to place data, tell it.
252 * Increment device's write pointer in multiples of 8. */ 247 * Increment device's write pointer in multiples of 8. */
253 if (rxq->write_actual != (rxq->write & ~0x7)) { 248 if (rxq->write_actual != (rxq->write & ~0x7)) {
254 spin_lock_irqsave(&rxq->lock, flags); 249 spin_lock(&rxq->lock);
255 rxq->need_update = 1; 250 rxq->need_update = 1;
256 spin_unlock_irqrestore(&rxq->lock, flags); 251 spin_unlock(&rxq->lock);
257 iwl_pcie_rxq_inc_wr_ptr(trans, rxq); 252 iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
258 } 253 }
259} 254}
@@ -273,16 +268,15 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority)
273 struct iwl_rxq *rxq = &trans_pcie->rxq; 268 struct iwl_rxq *rxq = &trans_pcie->rxq;
274 struct iwl_rx_mem_buffer *rxb; 269 struct iwl_rx_mem_buffer *rxb;
275 struct page *page; 270 struct page *page;
276 unsigned long flags;
277 gfp_t gfp_mask = priority; 271 gfp_t gfp_mask = priority;
278 272
279 while (1) { 273 while (1) {
280 spin_lock_irqsave(&rxq->lock, flags); 274 spin_lock(&rxq->lock);
281 if (list_empty(&rxq->rx_used)) { 275 if (list_empty(&rxq->rx_used)) {
282 spin_unlock_irqrestore(&rxq->lock, flags); 276 spin_unlock(&rxq->lock);
283 return; 277 return;
284 } 278 }
285 spin_unlock_irqrestore(&rxq->lock, flags); 279 spin_unlock(&rxq->lock);
286 280
287 if (rxq->free_count > RX_LOW_WATERMARK) 281 if (rxq->free_count > RX_LOW_WATERMARK)
288 gfp_mask |= __GFP_NOWARN; 282 gfp_mask |= __GFP_NOWARN;
@@ -311,17 +305,17 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority)
311 return; 305 return;
312 } 306 }
313 307
314 spin_lock_irqsave(&rxq->lock, flags); 308 spin_lock(&rxq->lock);
315 309
316 if (list_empty(&rxq->rx_used)) { 310 if (list_empty(&rxq->rx_used)) {
317 spin_unlock_irqrestore(&rxq->lock, flags); 311 spin_unlock(&rxq->lock);
318 __free_pages(page, trans_pcie->rx_page_order); 312 __free_pages(page, trans_pcie->rx_page_order);
319 return; 313 return;
320 } 314 }
321 rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer, 315 rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer,
322 list); 316 list);
323 list_del(&rxb->list); 317 list_del(&rxb->list);
324 spin_unlock_irqrestore(&rxq->lock, flags); 318 spin_unlock(&rxq->lock);
325 319
326 BUG_ON(rxb->page); 320 BUG_ON(rxb->page);
327 rxb->page = page; 321 rxb->page = page;
@@ -332,9 +326,9 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority)
332 DMA_FROM_DEVICE); 326 DMA_FROM_DEVICE);
333 if (dma_mapping_error(trans->dev, rxb->page_dma)) { 327 if (dma_mapping_error(trans->dev, rxb->page_dma)) {
334 rxb->page = NULL; 328 rxb->page = NULL;
335 spin_lock_irqsave(&rxq->lock, flags); 329 spin_lock(&rxq->lock);
336 list_add(&rxb->list, &rxq->rx_used); 330 list_add(&rxb->list, &rxq->rx_used);
337 spin_unlock_irqrestore(&rxq->lock, flags); 331 spin_unlock(&rxq->lock);
338 __free_pages(page, trans_pcie->rx_page_order); 332 __free_pages(page, trans_pcie->rx_page_order);
339 return; 333 return;
340 } 334 }
@@ -343,12 +337,12 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority)
343 /* and also 256 byte aligned! */ 337 /* and also 256 byte aligned! */
344 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); 338 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
345 339
346 spin_lock_irqsave(&rxq->lock, flags); 340 spin_lock(&rxq->lock);
347 341
348 list_add_tail(&rxb->list, &rxq->rx_free); 342 list_add_tail(&rxb->list, &rxq->rx_free);
349 rxq->free_count++; 343 rxq->free_count++;
350 344
351 spin_unlock_irqrestore(&rxq->lock, flags); 345 spin_unlock(&rxq->lock);
352 } 346 }
353} 347}
354 348
@@ -382,13 +376,12 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans)
382static void iwl_pcie_rx_replenish(struct iwl_trans *trans) 376static void iwl_pcie_rx_replenish(struct iwl_trans *trans)
383{ 377{
384 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 378 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
385 unsigned long flags;
386 379
387 iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); 380 iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL);
388 381
389 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 382 spin_lock(&trans_pcie->irq_lock);
390 iwl_pcie_rxq_restock(trans); 383 iwl_pcie_rxq_restock(trans);
391 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 384 spin_unlock(&trans_pcie->irq_lock);
392} 385}
393 386
394static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) 387static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans)
@@ -514,7 +507,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
514 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 507 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
515 struct iwl_rxq *rxq = &trans_pcie->rxq; 508 struct iwl_rxq *rxq = &trans_pcie->rxq;
516 int i, err; 509 int i, err;
517 unsigned long flags;
518 510
519 if (!rxq->bd) { 511 if (!rxq->bd) {
520 err = iwl_pcie_rx_alloc(trans); 512 err = iwl_pcie_rx_alloc(trans);
@@ -522,7 +514,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
522 return err; 514 return err;
523 } 515 }
524 516
525 spin_lock_irqsave(&rxq->lock, flags); 517 spin_lock(&rxq->lock);
526 518
527 INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work); 519 INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work);
528 520
@@ -538,16 +530,16 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
538 rxq->read = rxq->write = 0; 530 rxq->read = rxq->write = 0;
539 rxq->write_actual = 0; 531 rxq->write_actual = 0;
540 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); 532 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
541 spin_unlock_irqrestore(&rxq->lock, flags); 533 spin_unlock(&rxq->lock);
542 534
543 iwl_pcie_rx_replenish(trans); 535 iwl_pcie_rx_replenish(trans);
544 536
545 iwl_pcie_rx_hw_init(trans, rxq); 537 iwl_pcie_rx_hw_init(trans, rxq);
546 538
547 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 539 spin_lock(&trans_pcie->irq_lock);
548 rxq->need_update = 1; 540 rxq->need_update = 1;
549 iwl_pcie_rxq_inc_wr_ptr(trans, rxq); 541 iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
550 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 542 spin_unlock(&trans_pcie->irq_lock);
551 543
552 return 0; 544 return 0;
553} 545}
@@ -556,7 +548,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
556{ 548{
557 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 549 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
558 struct iwl_rxq *rxq = &trans_pcie->rxq; 550 struct iwl_rxq *rxq = &trans_pcie->rxq;
559 unsigned long flags;
560 551
561 /*if rxq->bd is NULL, it means that nothing has been allocated, 552 /*if rxq->bd is NULL, it means that nothing has been allocated,
562 * exit now */ 553 * exit now */
@@ -567,9 +558,9 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
567 558
568 cancel_work_sync(&trans_pcie->rx_replenish); 559 cancel_work_sync(&trans_pcie->rx_replenish);
569 560
570 spin_lock_irqsave(&rxq->lock, flags); 561 spin_lock(&rxq->lock);
571 iwl_pcie_rxq_free_rbs(trans); 562 iwl_pcie_rxq_free_rbs(trans);
572 spin_unlock_irqrestore(&rxq->lock, flags); 563 spin_unlock(&rxq->lock);
573 564
574 dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, 565 dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
575 rxq->bd, rxq->bd_dma); 566 rxq->bd, rxq->bd_dma);
@@ -592,7 +583,6 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
592 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 583 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
593 struct iwl_rxq *rxq = &trans_pcie->rxq; 584 struct iwl_rxq *rxq = &trans_pcie->rxq;
594 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; 585 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
595 unsigned long flags;
596 bool page_stolen = false; 586 bool page_stolen = false;
597 int max_len = PAGE_SIZE << trans_pcie->rx_page_order; 587 int max_len = PAGE_SIZE << trans_pcie->rx_page_order;
598 u32 offset = 0; 588 u32 offset = 0;
@@ -625,7 +615,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
625 rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), 615 rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd),
626 pkt->hdr.cmd); 616 pkt->hdr.cmd);
627 617
628 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 618 len = iwl_rx_packet_len(pkt);
629 len += sizeof(u32); /* account for status word */ 619 len += sizeof(u32); /* account for status word */
630 trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len); 620 trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
631 trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len); 621 trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
@@ -694,7 +684,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
694 /* Reuse the page if possible. For notification packets and 684 /* Reuse the page if possible. For notification packets and
695 * SKBs that fail to Rx correctly, add them back into the 685 * SKBs that fail to Rx correctly, add them back into the
696 * rx_free list for reuse later. */ 686 * rx_free list for reuse later. */
697 spin_lock_irqsave(&rxq->lock, flags); 687 spin_lock(&rxq->lock);
698 if (rxb->page != NULL) { 688 if (rxb->page != NULL) {
699 rxb->page_dma = 689 rxb->page_dma =
700 dma_map_page(trans->dev, rxb->page, 0, 690 dma_map_page(trans->dev, rxb->page, 0,
@@ -715,7 +705,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
715 } 705 }
716 } else 706 } else
717 list_add_tail(&rxb->list, &rxq->rx_used); 707 list_add_tail(&rxb->list, &rxq->rx_used);
718 spin_unlock_irqrestore(&rxq->lock, flags); 708 spin_unlock(&rxq->lock);
719} 709}
720 710
721/* 711/*
@@ -791,7 +781,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
791 APMS_CLK_VAL_MRB_FUNC_MODE) || 781 APMS_CLK_VAL_MRB_FUNC_MODE) ||
792 (iwl_read_prph(trans, APMG_PS_CTRL_REG) & 782 (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
793 APMG_PS_CTRL_VAL_RESET_REQ))) { 783 APMG_PS_CTRL_VAL_RESET_REQ))) {
794 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 784 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
795 iwl_op_mode_wimax_active(trans->op_mode); 785 iwl_op_mode_wimax_active(trans->op_mode);
796 wake_up(&trans_pcie->wait_command_queue); 786 wake_up(&trans_pcie->wait_command_queue);
797 return; 787 return;
@@ -800,14 +790,95 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
800 iwl_pcie_dump_csr(trans); 790 iwl_pcie_dump_csr(trans);
801 iwl_dump_fh(trans, NULL); 791 iwl_dump_fh(trans, NULL);
802 792
803 /* set the ERROR bit before we wake up the caller */
804 set_bit(STATUS_FW_ERROR, &trans_pcie->status);
805 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
806 wake_up(&trans_pcie->wait_command_queue);
807
808 local_bh_disable(); 793 local_bh_disable();
809 iwl_nic_error(trans); 794 /* The STATUS_FW_ERROR bit is set in this function. This must happen
795 * before we wake up the command caller, to ensure a proper cleanup. */
796 iwl_trans_fw_error(trans);
810 local_bh_enable(); 797 local_bh_enable();
798
799 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
800 wake_up(&trans_pcie->wait_command_queue);
801}
802
803static u32 iwl_pcie_int_cause_non_ict(struct iwl_trans *trans)
804{
805 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
806 u32 inta;
807
808 lockdep_assert_held(&trans_pcie->irq_lock);
809
810 trace_iwlwifi_dev_irq(trans->dev);
811
812 /* Discover which interrupts are active/pending */
813 inta = iwl_read32(trans, CSR_INT);
814
815 /* the thread will service interrupts and re-enable them */
816 return inta;
817}
818
819/* a device (PCI-E) page is 4096 bytes long */
820#define ICT_SHIFT 12
821#define ICT_SIZE (1 << ICT_SHIFT)
822#define ICT_COUNT (ICT_SIZE / sizeof(u32))
823
824/* interrupt handler using ict table, with this interrupt driver will
825 * stop using INTA register to get device's interrupt, reading this register
826 * is expensive, device will write interrupts in ICT dram table, increment
827 * index then will fire interrupt to driver, driver will OR all ICT table
828 * entries from current index up to table entry with 0 value. the result is
829 * the interrupt we need to service, driver will set the entries back to 0 and
830 * set index.
831 */
832static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans)
833{
834 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
835 u32 inta;
836 u32 val = 0;
837 u32 read;
838
839 trace_iwlwifi_dev_irq(trans->dev);
840
841 /* Ignore interrupt if there's nothing in NIC to service.
842 * This may be due to IRQ shared with another device,
843 * or due to sporadic interrupts thrown from our NIC. */
844 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
845 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read);
846 if (!read)
847 return 0;
848
849 /*
850 * Collect all entries up to the first 0, starting from ict_index;
851 * note we already read at ict_index.
852 */
853 do {
854 val |= read;
855 IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n",
856 trans_pcie->ict_index, read);
857 trans_pcie->ict_tbl[trans_pcie->ict_index] = 0;
858 trans_pcie->ict_index =
859 iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT);
860
861 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
862 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index,
863 read);
864 } while (read);
865
866 /* We should not get this value, just ignore it. */
867 if (val == 0xffffffff)
868 val = 0;
869
870 /*
871 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
872 * (bit 15 before shifting it to 31) to clear when using interrupt
873 * coalescing. fortunately, bits 18 and 19 stay set when this happens
874 * so we use them to decide on the real state of the Rx bit.
875 * In order words, bit 15 is set if bit 18 or bit 19 are set.
876 */
877 if (val & 0xC0000)
878 val |= 0x8000;
879
880 inta = (0xff & val) | ((0xff00 & val) << 16);
881 return inta;
811} 882}
812 883
813irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) 884irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
@@ -817,12 +888,61 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
817 struct isr_statistics *isr_stats = &trans_pcie->isr_stats; 888 struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
818 u32 inta = 0; 889 u32 inta = 0;
819 u32 handled = 0; 890 u32 handled = 0;
820 unsigned long flags;
821 u32 i; 891 u32 i;
822 892
823 lock_map_acquire(&trans->sync_cmd_lockdep_map); 893 lock_map_acquire(&trans->sync_cmd_lockdep_map);
824 894
825 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 895 spin_lock(&trans_pcie->irq_lock);
896
897 /* dram interrupt table not set yet,
898 * use legacy interrupt.
899 */
900 if (likely(trans_pcie->use_ict))
901 inta = iwl_pcie_int_cause_ict(trans);
902 else
903 inta = iwl_pcie_int_cause_non_ict(trans);
904
905 if (iwl_have_debug_level(IWL_DL_ISR)) {
906 IWL_DEBUG_ISR(trans,
907 "ISR inta 0x%08x, enabled 0x%08x(sw), enabled(hw) 0x%08x, fh 0x%08x\n",
908 inta, trans_pcie->inta_mask,
909 iwl_read32(trans, CSR_INT_MASK),
910 iwl_read32(trans, CSR_FH_INT_STATUS));
911 if (inta & (~trans_pcie->inta_mask))
912 IWL_DEBUG_ISR(trans,
913 "We got a masked interrupt (0x%08x)\n",
914 inta & (~trans_pcie->inta_mask));
915 }
916
917 inta &= trans_pcie->inta_mask;
918
919 /*
920 * Ignore interrupt if there's nothing in NIC to service.
921 * This may be due to IRQ shared with another device,
922 * or due to sporadic interrupts thrown from our NIC.
923 */
924 if (unlikely(!inta)) {
925 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
926 /*
927 * Re-enable interrupts here since we don't
928 * have anything to service
929 */
930 if (test_bit(STATUS_INT_ENABLED, &trans->status))
931 iwl_enable_interrupts(trans);
932 spin_unlock(&trans_pcie->irq_lock);
933 lock_map_release(&trans->sync_cmd_lockdep_map);
934 return IRQ_NONE;
935 }
936
937 if (unlikely(inta == 0xFFFFFFFF || (inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
938 /*
939 * Hardware disappeared. It might have
940 * already raised an interrupt.
941 */
942 IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
943 spin_unlock(&trans_pcie->irq_lock);
944 goto out;
945 }
826 946
827 /* Ack/clear/reset pending uCode interrupts. 947 /* Ack/clear/reset pending uCode interrupts.
828 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, 948 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
@@ -835,19 +955,13 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
835 * hardware bugs here by ACKing all the possible interrupts so that 955 * hardware bugs here by ACKing all the possible interrupts so that
836 * interrupt coalescing can still be achieved. 956 * interrupt coalescing can still be achieved.
837 */ 957 */
838 iwl_write32(trans, CSR_INT, 958 iwl_write32(trans, CSR_INT, inta | ~trans_pcie->inta_mask);
839 trans_pcie->inta | ~trans_pcie->inta_mask);
840
841 inta = trans_pcie->inta;
842 959
843 if (iwl_have_debug_level(IWL_DL_ISR)) 960 if (iwl_have_debug_level(IWL_DL_ISR))
844 IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", 961 IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n",
845 inta, iwl_read32(trans, CSR_INT_MASK)); 962 inta, iwl_read32(trans, CSR_INT_MASK));
846 963
847 /* saved interrupt in inta variable now we can reset trans_pcie->inta */ 964 spin_unlock(&trans_pcie->irq_lock);
848 trans_pcie->inta = 0;
849
850 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
851 965
852 /* Now service all interrupt bits discovered above. */ 966 /* Now service all interrupt bits discovered above. */
853 if (inta & CSR_INT_BIT_HW_ERR) { 967 if (inta & CSR_INT_BIT_HW_ERR) {
@@ -894,14 +1008,14 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
894 1008
895 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 1009 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
896 if (hw_rfkill) { 1010 if (hw_rfkill) {
897 set_bit(STATUS_RFKILL, &trans_pcie->status); 1011 set_bit(STATUS_RFKILL, &trans->status);
898 if (test_and_clear_bit(STATUS_HCMD_ACTIVE, 1012 if (test_and_clear_bit(STATUS_SYNC_HCMD_ACTIVE,
899 &trans_pcie->status)) 1013 &trans->status))
900 IWL_DEBUG_RF_KILL(trans, 1014 IWL_DEBUG_RF_KILL(trans,
901 "Rfkill while SYNC HCMD in flight\n"); 1015 "Rfkill while SYNC HCMD in flight\n");
902 wake_up(&trans_pcie->wait_command_queue); 1016 wake_up(&trans_pcie->wait_command_queue);
903 } else { 1017 } else {
904 clear_bit(STATUS_RFKILL, &trans_pcie->status); 1018 clear_bit(STATUS_RFKILL, &trans->status);
905 } 1019 }
906 1020
907 handled |= CSR_INT_BIT_RF_KILL; 1021 handled |= CSR_INT_BIT_RF_KILL;
@@ -1005,7 +1119,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
1005 1119
1006 /* Re-enable all interrupts */ 1120 /* Re-enable all interrupts */
1007 /* only Re-enable if disabled by irq */ 1121 /* only Re-enable if disabled by irq */
1008 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) 1122 if (test_bit(STATUS_INT_ENABLED, &trans->status))
1009 iwl_enable_interrupts(trans); 1123 iwl_enable_interrupts(trans);
1010 /* Re-enable RF_KILL if it occurred */ 1124 /* Re-enable RF_KILL if it occurred */
1011 else if (handled & CSR_INT_BIT_RF_KILL) 1125 else if (handled & CSR_INT_BIT_RF_KILL)
@@ -1022,11 +1136,6 @@ out:
1022 * 1136 *
1023 ******************************************************************************/ 1137 ******************************************************************************/
1024 1138
1025/* a device (PCI-E) page is 4096 bytes long */
1026#define ICT_SHIFT 12
1027#define ICT_SIZE (1 << ICT_SHIFT)
1028#define ICT_COUNT (ICT_SIZE / sizeof(u32))
1029
1030/* Free dram table */ 1139/* Free dram table */
1031void iwl_pcie_free_ict(struct iwl_trans *trans) 1140void iwl_pcie_free_ict(struct iwl_trans *trans)
1032{ 1141{
@@ -1051,7 +1160,7 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans)
1051 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1160 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1052 1161
1053 trans_pcie->ict_tbl = 1162 trans_pcie->ict_tbl =
1054 dma_alloc_coherent(trans->dev, ICT_SIZE, 1163 dma_zalloc_coherent(trans->dev, ICT_SIZE,
1055 &trans_pcie->ict_tbl_dma, 1164 &trans_pcie->ict_tbl_dma,
1056 GFP_KERNEL); 1165 GFP_KERNEL);
1057 if (!trans_pcie->ict_tbl) 1166 if (!trans_pcie->ict_tbl)
@@ -1063,17 +1172,10 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans)
1063 return -EINVAL; 1172 return -EINVAL;
1064 } 1173 }
1065 1174
1066 IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n", 1175 IWL_DEBUG_ISR(trans, "ict dma addr %Lx ict vir addr %p\n",
1067 (unsigned long long)trans_pcie->ict_tbl_dma); 1176 (unsigned long long)trans_pcie->ict_tbl_dma,
1068 1177 trans_pcie->ict_tbl);
1069 IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl);
1070
1071 /* reset table and index to all 0 */
1072 memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
1073 trans_pcie->ict_index = 0;
1074 1178
1075 /* add periodic RX interrupt */
1076 trans_pcie->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
1077 return 0; 1179 return 0;
1078} 1180}
1079 1181
@@ -1084,12 +1186,11 @@ void iwl_pcie_reset_ict(struct iwl_trans *trans)
1084{ 1186{
1085 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1187 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1086 u32 val; 1188 u32 val;
1087 unsigned long flags;
1088 1189
1089 if (!trans_pcie->ict_tbl) 1190 if (!trans_pcie->ict_tbl)
1090 return; 1191 return;
1091 1192
1092 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 1193 spin_lock(&trans_pcie->irq_lock);
1093 iwl_disable_interrupts(trans); 1194 iwl_disable_interrupts(trans);
1094 1195
1095 memset(trans_pcie->ict_tbl, 0, ICT_SIZE); 1196 memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
@@ -1106,124 +1207,26 @@ void iwl_pcie_reset_ict(struct iwl_trans *trans)
1106 trans_pcie->ict_index = 0; 1207 trans_pcie->ict_index = 0;
1107 iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); 1208 iwl_write32(trans, CSR_INT, trans_pcie->inta_mask);
1108 iwl_enable_interrupts(trans); 1209 iwl_enable_interrupts(trans);
1109 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1210 spin_unlock(&trans_pcie->irq_lock);
1110} 1211}
1111 1212
1112/* Device is going down disable ict interrupt usage */ 1213/* Device is going down disable ict interrupt usage */
1113void iwl_pcie_disable_ict(struct iwl_trans *trans) 1214void iwl_pcie_disable_ict(struct iwl_trans *trans)
1114{ 1215{
1115 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1216 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1116 unsigned long flags;
1117 1217
1118 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 1218 spin_lock(&trans_pcie->irq_lock);
1119 trans_pcie->use_ict = false; 1219 trans_pcie->use_ict = false;
1120 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1220 spin_unlock(&trans_pcie->irq_lock);
1121} 1221}
1122 1222
1123/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ 1223irqreturn_t iwl_pcie_isr(int irq, void *data)
1124static irqreturn_t iwl_pcie_isr(int irq, void *data)
1125{ 1224{
1126 struct iwl_trans *trans = data; 1225 struct iwl_trans *trans = data;
1127 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1128 u32 inta, inta_mask;
1129 irqreturn_t ret = IRQ_NONE;
1130
1131 lockdep_assert_held(&trans_pcie->irq_lock);
1132
1133 trace_iwlwifi_dev_irq(trans->dev);
1134
1135 /* Disable (but don't clear!) interrupts here to avoid
1136 * back-to-back ISRs and sporadic interrupts from our NIC.
1137 * If we have something to service, the irq thread will re-enable ints.
1138 * If we *don't* have something, we'll re-enable before leaving here. */
1139 inta_mask = iwl_read32(trans, CSR_INT_MASK);
1140 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
1141
1142 /* Discover which interrupts are active/pending */
1143 inta = iwl_read32(trans, CSR_INT);
1144
1145 if (inta & (~inta_mask)) {
1146 IWL_DEBUG_ISR(trans,
1147 "We got a masked interrupt (0x%08x)...Ack and ignore\n",
1148 inta & (~inta_mask));
1149 iwl_write32(trans, CSR_INT, inta & (~inta_mask));
1150 inta &= inta_mask;
1151 }
1152
1153 /* Ignore interrupt if there's nothing in NIC to service.
1154 * This may be due to IRQ shared with another device,
1155 * or due to sporadic interrupts thrown from our NIC. */
1156 if (!inta) {
1157 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
1158 goto none;
1159 }
1160
1161 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
1162 /* Hardware disappeared. It might have already raised
1163 * an interrupt */
1164 IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
1165 return IRQ_HANDLED;
1166 }
1167
1168 if (iwl_have_debug_level(IWL_DL_ISR))
1169 IWL_DEBUG_ISR(trans,
1170 "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
1171 inta, inta_mask,
1172 iwl_read32(trans, CSR_FH_INT_STATUS));
1173
1174 trans_pcie->inta |= inta;
1175 /* the thread will service interrupts and re-enable them */
1176 if (likely(inta))
1177 return IRQ_WAKE_THREAD;
1178
1179 ret = IRQ_HANDLED;
1180
1181none:
1182 /* re-enable interrupts here since we don't have anything to service. */
1183 /* only Re-enable if disabled by irq and no schedules tasklet. */
1184 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1185 !trans_pcie->inta)
1186 iwl_enable_interrupts(trans);
1187
1188 return ret;
1189}
1190
1191/* interrupt handler using ict table, with this interrupt driver will
1192 * stop using INTA register to get device's interrupt, reading this register
1193 * is expensive, device will write interrupts in ICT dram table, increment
1194 * index then will fire interrupt to driver, driver will OR all ICT table
1195 * entries from current index up to table entry with 0 value. the result is
1196 * the interrupt we need to service, driver will set the entries back to 0 and
1197 * set index.
1198 */
1199irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1200{
1201 struct iwl_trans *trans = data;
1202 struct iwl_trans_pcie *trans_pcie;
1203 u32 inta;
1204 u32 val = 0;
1205 u32 read;
1206 unsigned long flags;
1207 irqreturn_t ret = IRQ_NONE;
1208 1226
1209 if (!trans) 1227 if (!trans)
1210 return IRQ_NONE; 1228 return IRQ_NONE;
1211 1229
1212 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1213
1214 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
1215
1216 /* dram interrupt table not set yet,
1217 * use legacy interrupt.
1218 */
1219 if (unlikely(!trans_pcie->use_ict)) {
1220 ret = iwl_pcie_isr(irq, data);
1221 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1222 return ret;
1223 }
1224
1225 trace_iwlwifi_dev_irq(trans->dev);
1226
1227 /* Disable (but don't clear!) interrupts here to avoid 1230 /* Disable (but don't clear!) interrupts here to avoid
1228 * back-to-back ISRs and sporadic interrupts from our NIC. 1231 * back-to-back ISRs and sporadic interrupts from our NIC.
1229 * If we have something to service, the tasklet will re-enable ints. 1232 * If we have something to service, the tasklet will re-enable ints.
@@ -1231,73 +1234,5 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data)
1231 */ 1234 */
1232 iwl_write32(trans, CSR_INT_MASK, 0x00000000); 1235 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
1233 1236
1234 /* Ignore interrupt if there's nothing in NIC to service. 1237 return IRQ_WAKE_THREAD;
1235 * This may be due to IRQ shared with another device,
1236 * or due to sporadic interrupts thrown from our NIC. */
1237 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
1238 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read);
1239 if (!read) {
1240 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
1241 goto none;
1242 }
1243
1244 /*
1245 * Collect all entries up to the first 0, starting from ict_index;
1246 * note we already read at ict_index.
1247 */
1248 do {
1249 val |= read;
1250 IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n",
1251 trans_pcie->ict_index, read);
1252 trans_pcie->ict_tbl[trans_pcie->ict_index] = 0;
1253 trans_pcie->ict_index =
1254 iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT);
1255
1256 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
1257 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index,
1258 read);
1259 } while (read);
1260
1261 /* We should not get this value, just ignore it. */
1262 if (val == 0xffffffff)
1263 val = 0;
1264
1265 /*
1266 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1267 * (bit 15 before shifting it to 31) to clear when using interrupt
1268 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1269 * so we use them to decide on the real state of the Rx bit.
1270 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1271 */
1272 if (val & 0xC0000)
1273 val |= 0x8000;
1274
1275 inta = (0xff & val) | ((0xff00 & val) << 16);
1276 IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled(sw) 0x%08x ict 0x%08x\n",
1277 inta, trans_pcie->inta_mask, val);
1278 if (iwl_have_debug_level(IWL_DL_ISR))
1279 IWL_DEBUG_ISR(trans, "enabled(hw) 0x%08x\n",
1280 iwl_read32(trans, CSR_INT_MASK));
1281
1282 inta &= trans_pcie->inta_mask;
1283 trans_pcie->inta |= inta;
1284
1285 /* iwl_pcie_tasklet() will service interrupts and re-enable them */
1286 if (likely(inta)) {
1287 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1288 return IRQ_WAKE_THREAD;
1289 }
1290
1291 ret = IRQ_HANDLED;
1292
1293 none:
1294 /* re-enable interrupts here since we don't have anything to service.
1295 * only Re-enable if disabled by irq.
1296 */
1297 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1298 !trans_pcie->inta)
1299 iwl_enable_interrupts(trans);
1300
1301 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1302 return ret;
1303} 1238}
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index cde9c16f6e4f..f9507807b486 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -75,33 +75,6 @@
75#include "iwl-agn-hw.h" 75#include "iwl-agn-hw.h"
76#include "internal.h" 76#include "internal.h"
77 77
78static void __iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans,
79 u32 reg, u32 mask, u32 value)
80{
81 u32 v;
82
83#ifdef CONFIG_IWLWIFI_DEBUG
84 WARN_ON_ONCE(value & ~mask);
85#endif
86
87 v = iwl_read32(trans, reg);
88 v &= ~mask;
89 v |= value;
90 iwl_write32(trans, reg, v);
91}
92
93static inline void __iwl_trans_pcie_clear_bit(struct iwl_trans *trans,
94 u32 reg, u32 mask)
95{
96 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, 0);
97}
98
99static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
100 u32 reg, u32 mask)
101{
102 __iwl_trans_pcie_set_bits_mask(trans, reg, mask, mask);
103}
104
105static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux) 78static void iwl_pcie_set_pwr(struct iwl_trans *trans, bool vaux)
106{ 79{
107 if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold)) 80 if (vaux && pci_pme_capable(to_pci_dev(trans->dev), PCI_D3cold))
@@ -150,7 +123,6 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans)
150 */ 123 */
151static int iwl_pcie_apm_init(struct iwl_trans *trans) 124static int iwl_pcie_apm_init(struct iwl_trans *trans)
152{ 125{
153 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
154 int ret = 0; 126 int ret = 0;
155 IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); 127 IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
156 128
@@ -206,6 +178,28 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
206 goto out; 178 goto out;
207 } 179 }
208 180
181 if (trans->cfg->host_interrupt_operation_mode) {
182 /*
183 * This is a bit of an abuse - This is needed for 7260 / 3160
184 * only check host_interrupt_operation_mode even if this is
185 * not related to host_interrupt_operation_mode.
186 *
187 * Enable the oscillator to count wake up time for L1 exit. This
188 * consumes slightly more power (100uA) - but allows to be sure
189 * that we wake up from L1 on time.
190 *
191 * This looks weird: read twice the same register, discard the
192 * value, set a bit, and yet again, read that same register
193 * just to discard the value. But that's the way the hardware
194 * seems to like it.
195 */
196 iwl_read_prph(trans, OSC_CLK);
197 iwl_read_prph(trans, OSC_CLK);
198 iwl_set_bits_prph(trans, OSC_CLK, OSC_CLK_FORCE_CONTROL);
199 iwl_read_prph(trans, OSC_CLK);
200 iwl_read_prph(trans, OSC_CLK);
201 }
202
209 /* 203 /*
210 * Enable DMA clock and wait for it to stabilize. 204 * Enable DMA clock and wait for it to stabilize.
211 * 205 *
@@ -223,7 +217,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
223 /* Clear the interrupt in APMG if the NIC is in RFKILL */ 217 /* Clear the interrupt in APMG if the NIC is in RFKILL */
224 iwl_write_prph(trans, APMG_RTC_INT_STT_REG, APMG_RTC_INT_STT_RFKILL); 218 iwl_write_prph(trans, APMG_RTC_INT_STT_REG, APMG_RTC_INT_STT_RFKILL);
225 219
226 set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 220 set_bit(STATUS_DEVICE_ENABLED, &trans->status);
227 221
228out: 222out:
229 return ret; 223 return ret;
@@ -249,10 +243,9 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
249 243
250static void iwl_pcie_apm_stop(struct iwl_trans *trans) 244static void iwl_pcie_apm_stop(struct iwl_trans *trans)
251{ 245{
252 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
253 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); 246 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
254 247
255 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 248 clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
256 249
257 /* Stop device's DMA activity */ 250 /* Stop device's DMA activity */
258 iwl_pcie_apm_stop_master(trans); 251 iwl_pcie_apm_stop_master(trans);
@@ -273,13 +266,12 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans)
273static int iwl_pcie_nic_init(struct iwl_trans *trans) 266static int iwl_pcie_nic_init(struct iwl_trans *trans)
274{ 267{
275 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 268 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
276 unsigned long flags;
277 269
278 /* nic_init */ 270 /* nic_init */
279 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 271 spin_lock(&trans_pcie->irq_lock);
280 iwl_pcie_apm_init(trans); 272 iwl_pcie_apm_init(trans);
281 273
282 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 274 spin_unlock(&trans_pcie->irq_lock);
283 275
284 iwl_pcie_set_pwr(trans, false); 276 iwl_pcie_set_pwr(trans, false);
285 277
@@ -582,7 +574,6 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
582static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 574static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
583 const struct fw_img *fw, bool run_in_rfkill) 575 const struct fw_img *fw, bool run_in_rfkill)
584{ 576{
585 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
586 int ret; 577 int ret;
587 bool hw_rfkill; 578 bool hw_rfkill;
588 579
@@ -592,16 +583,14 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
592 return -EIO; 583 return -EIO;
593 } 584 }
594 585
595 clear_bit(STATUS_FW_ERROR, &trans_pcie->status);
596
597 iwl_enable_rfkill_int(trans); 586 iwl_enable_rfkill_int(trans);
598 587
599 /* If platform's RF_KILL switch is NOT set to KILL */ 588 /* If platform's RF_KILL switch is NOT set to KILL */
600 hw_rfkill = iwl_is_rfkill_set(trans); 589 hw_rfkill = iwl_is_rfkill_set(trans);
601 if (hw_rfkill) 590 if (hw_rfkill)
602 set_bit(STATUS_RFKILL, &trans_pcie->status); 591 set_bit(STATUS_RFKILL, &trans->status);
603 else 592 else
604 clear_bit(STATUS_RFKILL, &trans_pcie->status); 593 clear_bit(STATUS_RFKILL, &trans->status);
605 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 594 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
606 if (hw_rfkill && !run_in_rfkill) 595 if (hw_rfkill && !run_in_rfkill)
607 return -ERFKILL; 596 return -ERFKILL;
@@ -640,12 +629,14 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
640static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) 629static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
641{ 630{
642 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 631 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
643 unsigned long flags; 632 bool hw_rfkill, was_hw_rfkill;
633
634 was_hw_rfkill = iwl_is_rfkill_set(trans);
644 635
645 /* tell the device to stop sending interrupts */ 636 /* tell the device to stop sending interrupts */
646 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 637 spin_lock(&trans_pcie->irq_lock);
647 iwl_disable_interrupts(trans); 638 iwl_disable_interrupts(trans);
648 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 639 spin_unlock(&trans_pcie->irq_lock);
649 640
650 /* device going down, Stop using ICT table */ 641 /* device going down, Stop using ICT table */
651 iwl_pcie_disable_ict(trans); 642 iwl_pcie_disable_ict(trans);
@@ -657,7 +648,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
657 * restart. So don't process again if the device is 648 * restart. So don't process again if the device is
658 * already dead. 649 * already dead.
659 */ 650 */
660 if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { 651 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
661 iwl_pcie_tx_stop(trans); 652 iwl_pcie_tx_stop(trans);
662 iwl_pcie_rx_stop(trans); 653 iwl_pcie_rx_stop(trans);
663 654
@@ -677,21 +668,45 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
677 /* Upon stop, the APM issues an interrupt if HW RF kill is set. 668 /* Upon stop, the APM issues an interrupt if HW RF kill is set.
678 * Clean again the interrupt here 669 * Clean again the interrupt here
679 */ 670 */
680 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 671 spin_lock(&trans_pcie->irq_lock);
681 iwl_disable_interrupts(trans); 672 iwl_disable_interrupts(trans);
682 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 673 spin_unlock(&trans_pcie->irq_lock);
683
684 iwl_enable_rfkill_int(trans);
685 674
686 /* stop and reset the on-board processor */ 675 /* stop and reset the on-board processor */
687 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 676 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
688 677
689 /* clear all status bits */ 678 /* clear all status bits */
690 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 679 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
691 clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); 680 clear_bit(STATUS_INT_ENABLED, &trans->status);
692 clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); 681 clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
693 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); 682 clear_bit(STATUS_TPOWER_PMI, &trans->status);
694 clear_bit(STATUS_RFKILL, &trans_pcie->status); 683 clear_bit(STATUS_RFKILL, &trans->status);
684
685 /*
686 * Even if we stop the HW, we still want the RF kill
687 * interrupt
688 */
689 iwl_enable_rfkill_int(trans);
690
691 /*
692 * Check again since the RF kill state may have changed while
693 * all the interrupts were disabled, in this case we couldn't
694 * receive the RF kill interrupt and update the state in the
695 * op_mode.
696 * Don't call the op_mode if the rkfill state hasn't changed.
697 * This allows the op_mode to call stop_device from the rfkill
698 * notification without endless recursion. Under very rare
699 * circumstances, we might have a small recursion if the rfkill
700 * state changed exactly now while we were called from stop_device.
701 * This is very unlikely but can happen and is supported.
702 */
703 hw_rfkill = iwl_is_rfkill_set(trans);
704 if (hw_rfkill)
705 set_bit(STATUS_RFKILL, &trans->status);
706 else
707 clear_bit(STATUS_RFKILL, &trans->status);
708 if (hw_rfkill != was_hw_rfkill)
709 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
695} 710}
696 711
697static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test) 712static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
@@ -776,7 +791,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
776 791
777static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) 792static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
778{ 793{
779 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
780 bool hw_rfkill; 794 bool hw_rfkill;
781 int err; 795 int err;
782 796
@@ -787,7 +801,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
787 } 801 }
788 802
789 /* Reset the entire device */ 803 /* Reset the entire device */
790 iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 804 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
791 805
792 usleep_range(10, 15); 806 usleep_range(10, 15);
793 807
@@ -798,53 +812,30 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
798 812
799 hw_rfkill = iwl_is_rfkill_set(trans); 813 hw_rfkill = iwl_is_rfkill_set(trans);
800 if (hw_rfkill) 814 if (hw_rfkill)
801 set_bit(STATUS_RFKILL, &trans_pcie->status); 815 set_bit(STATUS_RFKILL, &trans->status);
802 else 816 else
803 clear_bit(STATUS_RFKILL, &trans_pcie->status); 817 clear_bit(STATUS_RFKILL, &trans->status);
804 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 818 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
805 819
806 return 0; 820 return 0;
807} 821}
808 822
809static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, 823static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans)
810 bool op_mode_leaving)
811{ 824{
812 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 825 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
813 bool hw_rfkill;
814 unsigned long flags;
815 826
816 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 827 /* disable interrupts - don't enable HW RF kill interrupt */
828 spin_lock(&trans_pcie->irq_lock);
817 iwl_disable_interrupts(trans); 829 iwl_disable_interrupts(trans);
818 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 830 spin_unlock(&trans_pcie->irq_lock);
819 831
820 iwl_pcie_apm_stop(trans); 832 iwl_pcie_apm_stop(trans);
821 833
822 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 834 spin_lock(&trans_pcie->irq_lock);
823 iwl_disable_interrupts(trans); 835 iwl_disable_interrupts(trans);
824 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 836 spin_unlock(&trans_pcie->irq_lock);
825 837
826 iwl_pcie_disable_ict(trans); 838 iwl_pcie_disable_ict(trans);
827
828 if (!op_mode_leaving) {
829 /*
830 * Even if we stop the HW, we still want the RF kill
831 * interrupt
832 */
833 iwl_enable_rfkill_int(trans);
834
835 /*
836 * Check again since the RF kill state may have changed while
837 * all the interrupts were disabled, in this case we couldn't
838 * receive the RF kill interrupt and update the state in the
839 * op_mode.
840 */
841 hw_rfkill = iwl_is_rfkill_set(trans);
842 if (hw_rfkill)
843 set_bit(STATUS_RFKILL, &trans_pcie->status);
844 else
845 clear_bit(STATUS_RFKILL, &trans_pcie->status);
846 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
847 }
848} 839}
849 840
850static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) 841static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
@@ -928,12 +919,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
928 919
929static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state) 920static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state)
930{ 921{
931 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
932
933 if (state) 922 if (state)
934 set_bit(STATUS_TPOWER_PMI, &trans_pcie->status); 923 set_bit(STATUS_TPOWER_PMI, &trans->status);
935 else 924 else
936 clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); 925 clear_bit(STATUS_TPOWER_PMI, &trans->status);
937} 926}
938 927
939static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent, 928static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
@@ -944,6 +933,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
944 933
945 spin_lock_irqsave(&trans_pcie->reg_lock, *flags); 934 spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
946 935
936 if (trans_pcie->cmd_in_flight)
937 goto out;
938
947 /* this bit wakes up the NIC */ 939 /* this bit wakes up the NIC */
948 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 940 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
949 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 941 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -983,6 +975,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
983 } 975 }
984 } 976 }
985 977
978out:
986 /* 979 /*
987 * Fool sparse by faking we release the lock - sparse will 980 * Fool sparse by faking we release the lock - sparse will
988 * track nic_access anyway. 981 * track nic_access anyway.
@@ -1004,6 +997,9 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
1004 */ 997 */
1005 __acquire(&trans_pcie->reg_lock); 998 __acquire(&trans_pcie->reg_lock);
1006 999
1000 if (trans_pcie->cmd_in_flight)
1001 goto out;
1002
1007 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 1003 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1008 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1004 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1009 /* 1005 /*
@@ -1013,6 +1009,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
1013 * scheduled on different CPUs (after we drop reg_lock). 1009 * scheduled on different CPUs (after we drop reg_lock).
1014 */ 1010 */
1015 mmiowb(); 1011 mmiowb();
1012out:
1016 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); 1013 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
1017} 1014}
1018 1015
@@ -1457,7 +1454,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
1457 1454
1458static const struct iwl_trans_ops trans_ops_pcie = { 1455static const struct iwl_trans_ops trans_ops_pcie = {
1459 .start_hw = iwl_trans_pcie_start_hw, 1456 .start_hw = iwl_trans_pcie_start_hw,
1460 .stop_hw = iwl_trans_pcie_stop_hw, 1457 .op_mode_leave = iwl_trans_pcie_op_mode_leave,
1461 .fw_alive = iwl_trans_pcie_fw_alive, 1458 .fw_alive = iwl_trans_pcie_fw_alive,
1462 .start_fw = iwl_trans_pcie_start_fw, 1459 .start_fw = iwl_trans_pcie_start_fw,
1463 .stop_device = iwl_trans_pcie_stop_device, 1460 .stop_device = iwl_trans_pcie_stop_device,
@@ -1609,7 +1606,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1609 if (iwl_pcie_alloc_ict(trans)) 1606 if (iwl_pcie_alloc_ict(trans))
1610 goto out_free_cmd_pool; 1607 goto out_free_cmd_pool;
1611 1608
1612 err = request_threaded_irq(pdev->irq, iwl_pcie_isr_ict, 1609 err = request_threaded_irq(pdev->irq, iwl_pcie_isr,
1613 iwl_pcie_irq_handler, 1610 iwl_pcie_irq_handler,
1614 IRQF_SHARED, DRV_NAME, trans); 1611 IRQF_SHARED, DRV_NAME, trans);
1615 if (err) { 1612 if (err) {
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 0adde919a258..3d549008b3e2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
207 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 207 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
208 le32_to_cpu(txq->scratchbufs[i].scratch)); 208 le32_to_cpu(txq->scratchbufs[i].scratch));
209 209
210 iwl_nic_error(trans); 210 iwl_trans_fw_error(trans);
211} 211}
212 212
213/* 213/*
@@ -289,21 +289,21 @@ static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
289 */ 289 */
290void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) 290void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
291{ 291{
292 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
292 u32 reg = 0; 293 u32 reg = 0;
293 int txq_id = txq->q.id; 294 int txq_id = txq->q.id;
294 295
295 if (txq->need_update == 0) 296 if (txq->need_update == 0)
296 return; 297 return;
297 298
298 if (trans->cfg->base_params->shadow_reg_enable) { 299 if (trans->cfg->base_params->shadow_reg_enable ||
300 txq_id == trans_pcie->cmd_queue) {
299 /* shadow register enabled */ 301 /* shadow register enabled */
300 iwl_write32(trans, HBUS_TARG_WRPTR, 302 iwl_write32(trans, HBUS_TARG_WRPTR,
301 txq->q.write_ptr | (txq_id << 8)); 303 txq->q.write_ptr | (txq_id << 8));
302 } else { 304 } else {
303 struct iwl_trans_pcie *trans_pcie =
304 IWL_TRANS_GET_PCIE_TRANS(trans);
305 /* if we're trying to save power */ 305 /* if we're trying to save power */
306 if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { 306 if (test_bit(STATUS_TPOWER_PMI, &trans->status)) {
307 /* wake up nic if it's powered down ... 307 /* wake up nic if it's powered down ...
308 * uCode will wake up, and interrupt us again, so next 308 * uCode will wake up, and interrupt us again, so next
309 * time we'll skip this part. */ 309 * time we'll skip this part. */
@@ -739,10 +739,9 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans)
739{ 739{
740 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 740 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
741 int ch, txq_id, ret; 741 int ch, txq_id, ret;
742 unsigned long flags;
743 742
744 /* Turn off all Tx DMA fifos */ 743 /* Turn off all Tx DMA fifos */
745 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 744 spin_lock(&trans_pcie->irq_lock);
746 745
747 iwl_pcie_txq_set_sched(trans, 0); 746 iwl_pcie_txq_set_sched(trans, 0);
748 747
@@ -759,13 +758,19 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans)
759 iwl_read_direct32(trans, 758 iwl_read_direct32(trans,
760 FH_TSSR_TX_STATUS_REG)); 759 FH_TSSR_TX_STATUS_REG));
761 } 760 }
762 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 761 spin_unlock(&trans_pcie->irq_lock);
763 762
764 if (!trans_pcie->txq) { 763 /*
765 IWL_WARN(trans, 764 * This function can be called before the op_mode disabled the
766 "Stopping tx queues that aren't allocated...\n"); 765 * queues. This happens when we have an rfkill interrupt.
766 * Since we stop Tx altogether - mark the queues as stopped.
767 */
768 memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
769 memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
770
771 /* This can happen: start_hw, stop_device */
772 if (!trans_pcie->txq)
767 return 0; 773 return 0;
768 }
769 774
770 /* Unmap DMA from host system and free skb's */ 775 /* Unmap DMA from host system and free skb's */
771 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; 776 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
@@ -867,7 +872,6 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
867 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 872 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
868 int ret; 873 int ret;
869 int txq_id, slots_num; 874 int txq_id, slots_num;
870 unsigned long flags;
871 bool alloc = false; 875 bool alloc = false;
872 876
873 if (!trans_pcie->txq) { 877 if (!trans_pcie->txq) {
@@ -877,7 +881,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
877 alloc = true; 881 alloc = true;
878 } 882 }
879 883
880 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 884 spin_lock(&trans_pcie->irq_lock);
881 885
882 /* Turn off all Tx DMA fifos */ 886 /* Turn off all Tx DMA fifos */
883 iwl_write_prph(trans, SCD_TXFACT, 0); 887 iwl_write_prph(trans, SCD_TXFACT, 0);
@@ -886,7 +890,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
886 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, 890 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
887 trans_pcie->kw.dma >> 4); 891 trans_pcie->kw.dma >> 4);
888 892
889 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 893 spin_unlock(&trans_pcie->irq_lock);
890 894
891 /* Alloc and init all Tx queues, including the command queue (#4/#9) */ 895 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
892 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; 896 for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
@@ -1005,6 +1009,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1005 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1009 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1006 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 1010 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
1007 struct iwl_queue *q = &txq->q; 1011 struct iwl_queue *q = &txq->q;
1012 unsigned long flags;
1008 int nfreed = 0; 1013 int nfreed = 0;
1009 1014
1010 lockdep_assert_held(&txq->lock); 1015 lockdep_assert_held(&txq->lock);
@@ -1023,10 +1028,20 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1023 if (nfreed++ > 0) { 1028 if (nfreed++ > 0) {
1024 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", 1029 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
1025 idx, q->write_ptr, q->read_ptr); 1030 idx, q->write_ptr, q->read_ptr);
1026 iwl_nic_error(trans); 1031 iwl_trans_fw_error(trans);
1027 } 1032 }
1028 } 1033 }
1029 1034
1035 if (q->read_ptr == q->write_ptr) {
1036 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1037 WARN_ON(!trans_pcie->cmd_in_flight);
1038 trans_pcie->cmd_in_flight = false;
1039 __iwl_trans_pcie_clear_bit(trans,
1040 CSR_GP_CNTRL,
1041 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1042 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1043 }
1044
1030 iwl_pcie_txq_progress(trans_pcie, txq); 1045 iwl_pcie_txq_progress(trans_pcie, txq);
1031} 1046}
1032 1047
@@ -1143,8 +1158,15 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
1143 SCD_TX_STTS_QUEUE_OFFSET(txq_id); 1158 SCD_TX_STTS_QUEUE_OFFSET(txq_id);
1144 static const u32 zero_val[4] = {}; 1159 static const u32 zero_val[4] = {};
1145 1160
1161 /*
1162 * Upon HW Rfkill - we stop the device, and then stop the queues
1163 * in the op_mode. Just for the sake of the simplicity of the op_mode,
1164 * allow the op_mode to call txq_disable after it already called
1165 * stop_device.
1166 */
1146 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { 1167 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
1147 WARN_ONCE(1, "queue %d not used", txq_id); 1168 WARN_ONCE(test_bit(STATUS_DEVICE_ENABLED, &trans->status),
1169 "queue %d not used", txq_id);
1148 return; 1170 return;
1149 } 1171 }
1150 1172
@@ -1178,12 +1200,13 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1178 struct iwl_queue *q = &txq->q; 1200 struct iwl_queue *q = &txq->q;
1179 struct iwl_device_cmd *out_cmd; 1201 struct iwl_device_cmd *out_cmd;
1180 struct iwl_cmd_meta *out_meta; 1202 struct iwl_cmd_meta *out_meta;
1203 unsigned long flags;
1181 void *dup_buf = NULL; 1204 void *dup_buf = NULL;
1182 dma_addr_t phys_addr; 1205 dma_addr_t phys_addr;
1183 int idx; 1206 int idx;
1184 u16 copy_size, cmd_size, scratch_size; 1207 u16 copy_size, cmd_size, scratch_size;
1185 bool had_nocopy = false; 1208 bool had_nocopy = false;
1186 int i; 1209 int i, ret;
1187 u32 cmd_pos; 1210 u32 cmd_pos;
1188 const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; 1211 const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
1189 u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; 1212 u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
@@ -1381,10 +1404,38 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1381 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1404 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
1382 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1405 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1383 1406
1407 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1408
1409 /*
1410 * wake up the NIC to make sure that the firmware will see the host
1411 * command - we will let the NIC sleep once all the host commands
1412 * returned.
1413 */
1414 if (!trans_pcie->cmd_in_flight) {
1415 trans_pcie->cmd_in_flight = true;
1416 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1417 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1418 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1419 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1420 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1421 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1422 15000);
1423 if (ret < 0) {
1424 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1425 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1426 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1427 trans_pcie->cmd_in_flight = false;
1428 idx = -EIO;
1429 goto out;
1430 }
1431 }
1432
1384 /* Increment and update queue's write index */ 1433 /* Increment and update queue's write index */
1385 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1434 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1386 iwl_pcie_txq_inc_wr_ptr(trans, txq); 1435 iwl_pcie_txq_inc_wr_ptr(trans, txq);
1387 1436
1437 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1438
1388 out: 1439 out:
1389 spin_unlock_bh(&txq->lock); 1440 spin_unlock_bh(&txq->lock);
1390 free_dup_buf: 1441 free_dup_buf:
@@ -1449,12 +1500,12 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1449 iwl_pcie_cmdq_reclaim(trans, txq_id, index); 1500 iwl_pcie_cmdq_reclaim(trans, txq_id, index);
1450 1501
1451 if (!(meta->flags & CMD_ASYNC)) { 1502 if (!(meta->flags & CMD_ASYNC)) {
1452 if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1503 if (!test_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status)) {
1453 IWL_WARN(trans, 1504 IWL_WARN(trans,
1454 "HCMD_ACTIVE already clear for command %s\n", 1505 "HCMD_ACTIVE already clear for command %s\n",
1455 get_cmd_string(trans_pcie, cmd->hdr.cmd)); 1506 get_cmd_string(trans_pcie, cmd->hdr.cmd));
1456 } 1507 }
1457 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1508 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
1458 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", 1509 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
1459 get_cmd_string(trans_pcie, cmd->hdr.cmd)); 1510 get_cmd_string(trans_pcie, cmd->hdr.cmd));
1460 wake_up(&trans_pcie->wait_command_queue); 1511 wake_up(&trans_pcie->wait_command_queue);
@@ -1466,7 +1517,6 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1466} 1517}
1467 1518
1468#define HOST_COMPLETE_TIMEOUT (2 * HZ) 1519#define HOST_COMPLETE_TIMEOUT (2 * HZ)
1469#define COMMAND_POKE_TIMEOUT (HZ / 10)
1470 1520
1471static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, 1521static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans,
1472 struct iwl_host_cmd *cmd) 1522 struct iwl_host_cmd *cmd)
@@ -1494,13 +1544,12 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1494 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1544 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1495 int cmd_idx; 1545 int cmd_idx;
1496 int ret; 1546 int ret;
1497 int timeout = HOST_COMPLETE_TIMEOUT;
1498 1547
1499 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 1548 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
1500 get_cmd_string(trans_pcie, cmd->id)); 1549 get_cmd_string(trans_pcie, cmd->id));
1501 1550
1502 if (WARN(test_and_set_bit(STATUS_HCMD_ACTIVE, 1551 if (WARN(test_and_set_bit(STATUS_SYNC_HCMD_ACTIVE,
1503 &trans_pcie->status), 1552 &trans->status),
1504 "Command %s: a command is already active!\n", 1553 "Command %s: a command is already active!\n",
1505 get_cmd_string(trans_pcie, cmd->id))) 1554 get_cmd_string(trans_pcie, cmd->id)))
1506 return -EIO; 1555 return -EIO;
@@ -1511,64 +1560,39 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1511 cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); 1560 cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd);
1512 if (cmd_idx < 0) { 1561 if (cmd_idx < 0) {
1513 ret = cmd_idx; 1562 ret = cmd_idx;
1514 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1563 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
1515 IWL_ERR(trans, 1564 IWL_ERR(trans,
1516 "Error sending %s: enqueue_hcmd failed: %d\n", 1565 "Error sending %s: enqueue_hcmd failed: %d\n",
1517 get_cmd_string(trans_pcie, cmd->id), ret); 1566 get_cmd_string(trans_pcie, cmd->id), ret);
1518 return ret; 1567 return ret;
1519 } 1568 }
1520 1569
1521 while (timeout > 0) { 1570 ret = wait_event_timeout(trans_pcie->wait_command_queue,
1522 unsigned long flags; 1571 !test_bit(STATUS_SYNC_HCMD_ACTIVE,
1523 1572 &trans->status),
1524 timeout -= COMMAND_POKE_TIMEOUT; 1573 HOST_COMPLETE_TIMEOUT);
1525 ret = wait_event_timeout(trans_pcie->wait_command_queue,
1526 !test_bit(STATUS_HCMD_ACTIVE,
1527 &trans_pcie->status),
1528 COMMAND_POKE_TIMEOUT);
1529 if (ret)
1530 break;
1531 /* poke the device - it may have lost the command */
1532 if (iwl_trans_grab_nic_access(trans, true, &flags)) {
1533 iwl_trans_release_nic_access(trans, &flags);
1534 IWL_DEBUG_INFO(trans,
1535 "Tried to wake NIC for command %s\n",
1536 get_cmd_string(trans_pcie, cmd->id));
1537 } else {
1538 IWL_ERR(trans, "Failed to poke NIC for command %s\n",
1539 get_cmd_string(trans_pcie, cmd->id));
1540 break;
1541 }
1542 }
1543
1544 if (!ret) { 1574 if (!ret) {
1545 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1575 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
1546 struct iwl_txq *txq = 1576 struct iwl_queue *q = &txq->q;
1547 &trans_pcie->txq[trans_pcie->cmd_queue];
1548 struct iwl_queue *q = &txq->q;
1549 1577
1550 IWL_ERR(trans, 1578 IWL_ERR(trans, "Error sending %s: time out after %dms.\n",
1551 "Error sending %s: time out after %dms.\n", 1579 get_cmd_string(trans_pcie, cmd->id),
1552 get_cmd_string(trans_pcie, cmd->id), 1580 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1553 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1554 1581
1555 IWL_ERR(trans, 1582 IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n",
1556 "Current CMD queue read_ptr %d write_ptr %d\n", 1583 q->read_ptr, q->write_ptr);
1557 q->read_ptr, q->write_ptr);
1558 1584
1559 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1585 clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
1560 IWL_DEBUG_INFO(trans, 1586 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
1561 "Clearing HCMD_ACTIVE for command %s\n", 1587 get_cmd_string(trans_pcie, cmd->id));
1562 get_cmd_string(trans_pcie, cmd->id)); 1588 ret = -ETIMEDOUT;
1563 ret = -ETIMEDOUT;
1564 1589
1565 iwl_nic_error(trans); 1590 iwl_trans_fw_error(trans);
1566 1591
1567 goto cancel; 1592 goto cancel;
1568 }
1569 } 1593 }
1570 1594
1571 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { 1595 if (test_bit(STATUS_FW_ERROR, &trans->status)) {
1572 IWL_ERR(trans, "FW error in SYNC CMD %s\n", 1596 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
1573 get_cmd_string(trans_pcie, cmd->id)); 1597 get_cmd_string(trans_pcie, cmd->id));
1574 dump_stack(); 1598 dump_stack();
@@ -1577,7 +1601,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1577 } 1601 }
1578 1602
1579 if (!(cmd->flags & CMD_SEND_IN_RFKILL) && 1603 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1580 test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1604 test_bit(STATUS_RFKILL, &trans->status)) {
1581 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n"); 1605 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
1582 ret = -ERFKILL; 1606 ret = -ERFKILL;
1583 goto cancel; 1607 goto cancel;
@@ -1614,13 +1638,8 @@ cancel:
1614 1638
1615int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) 1639int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1616{ 1640{
1617 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1618
1619 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1620 return -EIO;
1621
1622 if (!(cmd->flags & CMD_SEND_IN_RFKILL) && 1641 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1623 test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1642 test_bit(STATUS_RFKILL, &trans->status)) {
1624 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", 1643 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1625 cmd->id); 1644 cmd->id);
1626 return -ERFKILL; 1645 return -ERFKILL;
@@ -1674,7 +1693,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1674 txq->entries[q->write_ptr].skb = skb; 1693 txq->entries[q->write_ptr].skb = skb;
1675 txq->entries[q->write_ptr].cmd = dev_cmd; 1694 txq->entries[q->write_ptr].cmd = dev_cmd;
1676 1695
1677 dev_cmd->hdr.cmd = REPLY_TX;
1678 dev_cmd->hdr.sequence = 1696 dev_cmd->hdr.sequence =
1679 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1697 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1680 INDEX_TO_SEQ(q->write_ptr))); 1698 INDEX_TO_SEQ(q->write_ptr)));
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 91f2ca90c70f..1a554a685e91 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -8,9 +8,8 @@
8 Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 Ltd. under the terms of the GNU General Public License Version 2, June 1991
9 (the "License"). You may use, redistribute and/or modify this File in 9 (the "License"). You may use, redistribute and/or modify this File in
10 accordance with the terms and conditions of the License, a copy of which 10 accordance with the terms and conditions of the License, a copy of which
11 is available along with the File in the license.txt file or by writing to 11 is available along with the File in the license.txt file or on the worldwide
12 the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 12 web at http://www.gnu.org/licenses/gpl.txt.
13 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
14 13
15 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 14 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 15 IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 116f4aba08d6..32f75007a825 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1268,14 +1268,9 @@ static struct cfg80211_scan_request *
1268_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme) 1268_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
1269{ 1269{
1270 struct cfg80211_scan_request *creq = NULL; 1270 struct cfg80211_scan_request *creq = NULL;
1271 int i, n_channels = 0; 1271 int i, n_channels = ieee80211_get_num_supported_channels(wiphy);
1272 enum ieee80211_band band; 1272 enum ieee80211_band band;
1273 1273
1274 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1275 if (wiphy->bands[band])
1276 n_channels += wiphy->bands[band]->n_channels;
1277 }
1278
1279 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + 1274 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1280 n_channels * sizeof(void *), 1275 n_channels * sizeof(void *),
1281 GFP_ATOMIC); 1276 GFP_ATOMIC);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 991238afd1b6..58c6ee5de98f 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -849,7 +849,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
849 card->started = true; 849 card->started = true;
850 /* Tell PM core that we don't need the card to be 850 /* Tell PM core that we don't need the card to be
851 * powered now */ 851 * powered now */
852 pm_runtime_put_noidle(&func->dev); 852 pm_runtime_put(&func->dev);
853 } 853 }
854 } 854 }
855 855
@@ -907,8 +907,8 @@ static int if_sdio_power_on(struct if_sdio_card *card)
907 sdio_release_host(func); 907 sdio_release_host(func);
908 ret = if_sdio_prog_firmware(card); 908 ret = if_sdio_prog_firmware(card);
909 if (ret) { 909 if (ret) {
910 sdio_disable_func(func); 910 sdio_claim_host(func);
911 return ret; 911 goto disable;
912 } 912 }
913 913
914 return 0; 914 return 0;
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 83669151bb82..f11728a866ff 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -93,7 +93,6 @@ static void free_if_spi_card(struct if_spi_card *card)
93 list_del(&packet->list); 93 list_del(&packet->list);
94 kfree(packet); 94 kfree(packet);
95 } 95 }
96 spi_set_drvdata(card->spi, NULL);
97 kfree(card); 96 kfree(card);
98} 97}
99 98
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index a1b32ee9594a..69d4c3179d04 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -159,10 +159,15 @@ static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
159 .reg_rules = { 159 .reg_rules = {
160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0), 160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
161 REG_RULE(5725-10, 5850+10, 40, 0, 30, 161 REG_RULE(5725-10, 5850+10, 40, 0, 30,
162 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 162 NL80211_RRF_NO_IR),
163 } 163 }
164}; 164};
165 165
166static const struct ieee80211_regdomain *hwsim_world_regdom_custom[] = {
167 &hwsim_world_regdom_custom_01,
168 &hwsim_world_regdom_custom_02,
169};
170
166struct hwsim_vif_priv { 171struct hwsim_vif_priv {
167 u32 magic; 172 u32 magic;
168 u8 bssid[ETH_ALEN]; 173 u8 bssid[ETH_ALEN];
@@ -321,8 +326,52 @@ static const struct ieee80211_rate hwsim_rates[] = {
321 { .bitrate = 540 } 326 { .bitrate = 540 }
322}; 327};
323 328
329static const struct ieee80211_iface_limit hwsim_if_limits[] = {
330 { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
331 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
332 BIT(NL80211_IFTYPE_P2P_CLIENT) |
333#ifdef CONFIG_MAC80211_MESH
334 BIT(NL80211_IFTYPE_MESH_POINT) |
335#endif
336 BIT(NL80211_IFTYPE_AP) |
337 BIT(NL80211_IFTYPE_P2P_GO) },
338 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
339};
340
341static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = {
342 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
343};
344
345static const struct ieee80211_iface_combination hwsim_if_comb[] = {
346 {
347 .limits = hwsim_if_limits,
348 .n_limits = ARRAY_SIZE(hwsim_if_limits),
349 .max_interfaces = 2048,
350 .num_different_channels = 1,
351 },
352 {
353 .limits = hwsim_if_dfs_limits,
354 .n_limits = ARRAY_SIZE(hwsim_if_dfs_limits),
355 .max_interfaces = 8,
356 .num_different_channels = 1,
357 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
358 BIT(NL80211_CHAN_WIDTH_20) |
359 BIT(NL80211_CHAN_WIDTH_40) |
360 BIT(NL80211_CHAN_WIDTH_80) |
361 BIT(NL80211_CHAN_WIDTH_160),
362 }
363};
364
324static spinlock_t hwsim_radio_lock; 365static spinlock_t hwsim_radio_lock;
325static struct list_head hwsim_radios; 366static struct list_head hwsim_radios;
367static int hwsim_radio_idx;
368
369static struct platform_driver mac80211_hwsim_driver = {
370 .driver = {
371 .name = "mac80211_hwsim",
372 .owner = THIS_MODULE,
373 },
374};
326 375
327struct mac80211_hwsim_data { 376struct mac80211_hwsim_data {
328 struct list_head list; 377 struct list_head list;
@@ -332,8 +381,10 @@ struct mac80211_hwsim_data {
332 struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)]; 381 struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
333 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; 382 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
334 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 383 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
384 struct ieee80211_iface_combination if_combination;
335 385
336 struct mac_address addresses[2]; 386 struct mac_address addresses[2];
387 int channels, idx;
337 388
338 struct ieee80211_channel *tmp_chan; 389 struct ieee80211_channel *tmp_chan;
339 struct delayed_work roc_done; 390 struct delayed_work roc_done;
@@ -353,7 +404,6 @@ struct mac80211_hwsim_data {
353 } ps; 404 } ps;
354 bool ps_poll_pending; 405 bool ps_poll_pending;
355 struct dentry *debugfs; 406 struct dentry *debugfs;
356 struct dentry *debugfs_ps;
357 407
358 struct sk_buff_head pending; /* packets pending */ 408 struct sk_buff_head pending; /* packets pending */
359 /* 409 /*
@@ -362,7 +412,6 @@ struct mac80211_hwsim_data {
362 * radio can be in more then one group. 412 * radio can be in more then one group.
363 */ 413 */
364 u64 group; 414 u64 group;
365 struct dentry *debugfs_group;
366 415
367 int power_level; 416 int power_level;
368 417
@@ -403,21 +452,179 @@ static struct genl_family hwsim_genl_family = {
403/* MAC80211_HWSIM netlink policy */ 452/* MAC80211_HWSIM netlink policy */
404 453
405static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { 454static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
406 [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC, 455 [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
407 .len = 6*sizeof(u8) }, 456 [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
408 [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC,
409 .len = 6*sizeof(u8) },
410 [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY, 457 [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY,
411 .len = IEEE80211_MAX_DATA_LEN }, 458 .len = IEEE80211_MAX_DATA_LEN },
412 [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 }, 459 [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 },
413 [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 }, 460 [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 },
414 [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 }, 461 [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 },
415 [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC, 462 [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC,
416 .len = IEEE80211_TX_MAX_RATES*sizeof( 463 .len = IEEE80211_TX_MAX_RATES *
417 struct hwsim_tx_rate)}, 464 sizeof(struct hwsim_tx_rate)},
418 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, 465 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
466 [HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 },
467 [HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
468 [HWSIM_ATTR_REG_HINT_ALPHA2] = { .type = NLA_STRING, .len = 2 },
469 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 },
470 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG },
419}; 471};
420 472
473static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
474 struct sk_buff *skb,
475 struct ieee80211_channel *chan);
476
477/* sysfs attributes */
478static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
479{
480 struct mac80211_hwsim_data *data = dat;
481 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
482 struct sk_buff *skb;
483 struct ieee80211_pspoll *pspoll;
484
485 if (!vp->assoc)
486 return;
487
488 wiphy_debug(data->hw->wiphy,
489 "%s: send PS-Poll to %pM for aid %d\n",
490 __func__, vp->bssid, vp->aid);
491
492 skb = dev_alloc_skb(sizeof(*pspoll));
493 if (!skb)
494 return;
495 pspoll = (void *) skb_put(skb, sizeof(*pspoll));
496 pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
497 IEEE80211_STYPE_PSPOLL |
498 IEEE80211_FCTL_PM);
499 pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
500 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
501 memcpy(pspoll->ta, mac, ETH_ALEN);
502
503 rcu_read_lock();
504 mac80211_hwsim_tx_frame(data->hw, skb,
505 rcu_dereference(vif->chanctx_conf)->def.chan);
506 rcu_read_unlock();
507}
508
509static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
510 struct ieee80211_vif *vif, int ps)
511{
512 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
513 struct sk_buff *skb;
514 struct ieee80211_hdr *hdr;
515
516 if (!vp->assoc)
517 return;
518
519 wiphy_debug(data->hw->wiphy,
520 "%s: send data::nullfunc to %pM ps=%d\n",
521 __func__, vp->bssid, ps);
522
523 skb = dev_alloc_skb(sizeof(*hdr));
524 if (!skb)
525 return;
526 hdr = (void *) skb_put(skb, sizeof(*hdr) - ETH_ALEN);
527 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
528 IEEE80211_STYPE_NULLFUNC |
529 (ps ? IEEE80211_FCTL_PM : 0));
530 hdr->duration_id = cpu_to_le16(0);
531 memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
532 memcpy(hdr->addr2, mac, ETH_ALEN);
533 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
534
535 rcu_read_lock();
536 mac80211_hwsim_tx_frame(data->hw, skb,
537 rcu_dereference(vif->chanctx_conf)->def.chan);
538 rcu_read_unlock();
539}
540
541
542static void hwsim_send_nullfunc_ps(void *dat, u8 *mac,
543 struct ieee80211_vif *vif)
544{
545 struct mac80211_hwsim_data *data = dat;
546 hwsim_send_nullfunc(data, mac, vif, 1);
547}
548
549static void hwsim_send_nullfunc_no_ps(void *dat, u8 *mac,
550 struct ieee80211_vif *vif)
551{
552 struct mac80211_hwsim_data *data = dat;
553 hwsim_send_nullfunc(data, mac, vif, 0);
554}
555
556static int hwsim_fops_ps_read(void *dat, u64 *val)
557{
558 struct mac80211_hwsim_data *data = dat;
559 *val = data->ps;
560 return 0;
561}
562
563static int hwsim_fops_ps_write(void *dat, u64 val)
564{
565 struct mac80211_hwsim_data *data = dat;
566 enum ps_mode old_ps;
567
568 if (val != PS_DISABLED && val != PS_ENABLED && val != PS_AUTO_POLL &&
569 val != PS_MANUAL_POLL)
570 return -EINVAL;
571
572 old_ps = data->ps;
573 data->ps = val;
574
575 if (val == PS_MANUAL_POLL) {
576 ieee80211_iterate_active_interfaces(data->hw,
577 IEEE80211_IFACE_ITER_NORMAL,
578 hwsim_send_ps_poll, data);
579 data->ps_poll_pending = true;
580 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
581 ieee80211_iterate_active_interfaces(data->hw,
582 IEEE80211_IFACE_ITER_NORMAL,
583 hwsim_send_nullfunc_ps,
584 data);
585 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
586 ieee80211_iterate_active_interfaces(data->hw,
587 IEEE80211_IFACE_ITER_NORMAL,
588 hwsim_send_nullfunc_no_ps,
589 data);
590 }
591
592 return 0;
593}
594
595DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
596 "%llu\n");
597
598static int hwsim_write_simulate_radar(void *dat, u64 val)
599{
600 struct mac80211_hwsim_data *data = dat;
601
602 ieee80211_radar_detected(data->hw);
603
604 return 0;
605}
606
607DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL,
608 hwsim_write_simulate_radar, "%llu\n");
609
610static int hwsim_fops_group_read(void *dat, u64 *val)
611{
612 struct mac80211_hwsim_data *data = dat;
613 *val = data->group;
614 return 0;
615}
616
617static int hwsim_fops_group_write(void *dat, u64 val)
618{
619 struct mac80211_hwsim_data *data = dat;
620 data->group = val;
621 return 0;
622}
623
624DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
625 hwsim_fops_group_read, hwsim_fops_group_write,
626 "%llx\n");
627
421static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, 628static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
422 struct net_device *dev) 629 struct net_device *dev)
423{ 630{
@@ -641,7 +848,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
641 } 848 }
642 849
643 if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, 850 if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
644 sizeof(struct mac_address), data->addresses[1].addr)) 851 ETH_ALEN, data->addresses[1].addr))
645 goto nla_put_failure; 852 goto nla_put_failure;
646 853
647 /* We get the skb->data */ 854 /* We get the skb->data */
@@ -880,7 +1087,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
880 return; 1087 return;
881 } 1088 }
882 1089
883 if (channels == 1) { 1090 if (data->channels == 1) {
884 channel = data->channel; 1091 channel = data->channel;
885 } else if (txi->hw_queue == 4) { 1092 } else if (txi->hw_queue == 4) {
886 channel = data->tmp_chan; 1093 channel = data->tmp_chan;
@@ -908,7 +1115,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
908 if (control->sta) 1115 if (control->sta)
909 hwsim_check_sta_magic(control->sta); 1116 hwsim_check_sta_magic(control->sta);
910 1117
911 if (rctbl) 1118 if (hw->flags & IEEE80211_HW_SUPPORTS_RC_TABLE)
912 ieee80211_get_tx_rates(txi->control.vif, control->sta, skb, 1119 ieee80211_get_tx_rates(txi->control.vif, control->sta, skb,
913 txi->control.rates, 1120 txi->control.rates,
914 ARRAY_SIZE(txi->control.rates)); 1121 ARRAY_SIZE(txi->control.rates));
@@ -1015,7 +1222,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
1015{ 1222{
1016 u32 _pid = ACCESS_ONCE(wmediumd_portid); 1223 u32 _pid = ACCESS_ONCE(wmediumd_portid);
1017 1224
1018 if (rctbl) { 1225 if (hw->flags & IEEE80211_HW_SUPPORTS_RC_TABLE) {
1019 struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); 1226 struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
1020 ieee80211_get_tx_rates(txi->control.vif, NULL, skb, 1227 ieee80211_get_tx_rates(txi->control.vif, NULL, skb,
1021 txi->control.rates, 1228 txi->control.rates,
@@ -1052,7 +1259,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
1052 if (skb == NULL) 1259 if (skb == NULL)
1053 return; 1260 return;
1054 info = IEEE80211_SKB_CB(skb); 1261 info = IEEE80211_SKB_CB(skb);
1055 if (rctbl) 1262 if (hw->flags & IEEE80211_HW_SUPPORTS_RC_TABLE)
1056 ieee80211_get_tx_rates(vif, NULL, skb, 1263 ieee80211_get_tx_rates(vif, NULL, skb,
1057 info->control.rates, 1264 info->control.rates,
1058 ARRAY_SIZE(info->control.rates)); 1265 ARRAY_SIZE(info->control.rates));
@@ -1143,7 +1350,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
1143 1350
1144 data->channel = conf->chandef.chan; 1351 data->channel = conf->chandef.chan;
1145 1352
1146 WARN_ON(data->channel && channels > 1); 1353 WARN_ON(data->channel && data->channels > 1);
1147 1354
1148 data->power_level = conf->power_level; 1355 data->power_level = conf->power_level;
1149 if (!data->started || !data->beacon_int) 1356 if (!data->started || !data->beacon_int)
@@ -1390,8 +1597,6 @@ static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
1390 [HWSIM_TM_ATTR_PS] = { .type = NLA_U32 }, 1597 [HWSIM_TM_ATTR_PS] = { .type = NLA_U32 },
1391}; 1598};
1392 1599
1393static int hwsim_fops_ps_write(void *dat, u64 val);
1394
1395static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, 1600static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
1396 struct ieee80211_vif *vif, 1601 struct ieee80211_vif *vif,
1397 void *data, int len) 1602 void *data, int len)
@@ -1493,7 +1698,7 @@ static void hw_scan_work(struct work_struct *work)
1493 req->channels[hwsim->scan_chan_idx]->center_freq); 1698 req->channels[hwsim->scan_chan_idx]->center_freq);
1494 1699
1495 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; 1700 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
1496 if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || 1701 if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR ||
1497 !req->n_ssids) { 1702 !req->n_ssids) {
1498 dwell = 120; 1703 dwell = 120;
1499 } else { 1704 } else {
@@ -1702,8 +1907,7 @@ static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
1702 hwsim_check_chanctx_magic(ctx); 1907 hwsim_check_chanctx_magic(ctx);
1703} 1908}
1704 1909
1705static struct ieee80211_ops mac80211_hwsim_ops = 1910static const struct ieee80211_ops mac80211_hwsim_ops = {
1706{
1707 .tx = mac80211_hwsim_tx, 1911 .tx = mac80211_hwsim_tx,
1708 .start = mac80211_hwsim_start, 1912 .start = mac80211_hwsim_start,
1709 .stop = mac80211_hwsim_stop, 1913 .stop = mac80211_hwsim_stop,
@@ -1728,208 +1932,290 @@ static struct ieee80211_ops mac80211_hwsim_ops =
1728 .set_tsf = mac80211_hwsim_set_tsf, 1932 .set_tsf = mac80211_hwsim_set_tsf,
1729}; 1933};
1730 1934
1935static struct ieee80211_ops mac80211_hwsim_mchan_ops;
1731 1936
1732static void mac80211_hwsim_free(void) 1937static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
1938 const struct ieee80211_regdomain *regd,
1939 bool reg_strict)
1733{ 1940{
1734 struct list_head tmplist, *i, *tmp; 1941 int err;
1735 struct mac80211_hwsim_data *data, *tmpdata; 1942 u8 addr[ETH_ALEN];
1736 1943 struct mac80211_hwsim_data *data;
1737 INIT_LIST_HEAD(&tmplist); 1944 struct ieee80211_hw *hw;
1945 enum ieee80211_band band;
1946 const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
1947 int idx;
1738 1948
1739 spin_lock_bh(&hwsim_radio_lock); 1949 spin_lock_bh(&hwsim_radio_lock);
1740 list_for_each_safe(i, tmp, &hwsim_radios) 1950 idx = hwsim_radio_idx++;
1741 list_move(i, &tmplist);
1742 spin_unlock_bh(&hwsim_radio_lock); 1951 spin_unlock_bh(&hwsim_radio_lock);
1743 1952
1744 list_for_each_entry_safe(data, tmpdata, &tmplist, list) { 1953 if (channels > 1)
1745 debugfs_remove(data->debugfs_group); 1954 ops = &mac80211_hwsim_mchan_ops;
1746 debugfs_remove(data->debugfs_ps); 1955 hw = ieee80211_alloc_hw(sizeof(*data), ops);
1747 debugfs_remove(data->debugfs); 1956 if (!hw) {
1748 ieee80211_unregister_hw(data->hw); 1957 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n");
1749 device_release_driver(data->dev); 1958 err = -ENOMEM;
1750 device_unregister(data->dev); 1959 goto failed;
1751 ieee80211_free_hw(data->hw); 1960 }
1961 data = hw->priv;
1962 data->hw = hw;
1963
1964 data->dev = device_create(hwsim_class, NULL, 0, hw, "hwsim%d", idx);
1965 if (IS_ERR(data->dev)) {
1966 printk(KERN_DEBUG
1967 "mac80211_hwsim: device_create failed (%ld)\n",
1968 PTR_ERR(data->dev));
1969 err = -ENOMEM;
1970 goto failed_drvdata;
1971 }
1972 data->dev->driver = &mac80211_hwsim_driver.driver;
1973 err = device_bind_driver(data->dev);
1974 if (err != 0) {
1975 printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n",
1976 err);
1977 goto failed_hw;
1752 } 1978 }
1753 class_destroy(hwsim_class);
1754}
1755
1756static struct platform_driver mac80211_hwsim_driver = {
1757 .driver = {
1758 .name = "mac80211_hwsim",
1759 .owner = THIS_MODULE,
1760 },
1761};
1762
1763static const struct net_device_ops hwsim_netdev_ops = {
1764 .ndo_start_xmit = hwsim_mon_xmit,
1765 .ndo_change_mtu = eth_change_mtu,
1766 .ndo_set_mac_address = eth_mac_addr,
1767 .ndo_validate_addr = eth_validate_addr,
1768};
1769
1770static void hwsim_mon_setup(struct net_device *dev)
1771{
1772 dev->netdev_ops = &hwsim_netdev_ops;
1773 dev->destructor = free_netdev;
1774 ether_setup(dev);
1775 dev->tx_queue_len = 0;
1776 dev->type = ARPHRD_IEEE80211_RADIOTAP;
1777 memset(dev->dev_addr, 0, ETH_ALEN);
1778 dev->dev_addr[0] = 0x12;
1779}
1780 1979
1980 skb_queue_head_init(&data->pending);
1781 1981
1782static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) 1982 SET_IEEE80211_DEV(hw, data->dev);
1783{ 1983 memset(addr, 0, ETH_ALEN);
1784 struct mac80211_hwsim_data *data = dat; 1984 addr[0] = 0x02;
1785 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 1985 addr[3] = idx >> 8;
1786 struct sk_buff *skb; 1986 addr[4] = idx;
1787 struct ieee80211_pspoll *pspoll; 1987 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
1988 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
1989 data->addresses[1].addr[0] |= 0x40;
1990 hw->wiphy->n_addresses = 2;
1991 hw->wiphy->addresses = data->addresses;
1992
1993 data->channels = channels;
1994 data->idx = idx;
1995
1996 if (data->channels > 1) {
1997 hw->wiphy->max_scan_ssids = 255;
1998 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
1999 hw->wiphy->max_remain_on_channel_duration = 1000;
2000 /* For channels > 1 DFS is not allowed */
2001 hw->wiphy->n_iface_combinations = 1;
2002 hw->wiphy->iface_combinations = &data->if_combination;
2003 data->if_combination = hwsim_if_comb[0];
2004 data->if_combination.num_different_channels = data->channels;
2005 } else {
2006 hw->wiphy->iface_combinations = hwsim_if_comb;
2007 hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
2008 }
1788 2009
1789 if (!vp->assoc) 2010 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
1790 return; 2011 INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
2012
2013 hw->queues = 5;
2014 hw->offchannel_tx_hw_queue = 4;
2015 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2016 BIT(NL80211_IFTYPE_AP) |
2017 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2018 BIT(NL80211_IFTYPE_P2P_GO) |
2019 BIT(NL80211_IFTYPE_ADHOC) |
2020 BIT(NL80211_IFTYPE_MESH_POINT) |
2021 BIT(NL80211_IFTYPE_P2P_DEVICE);
2022
2023 hw->flags = IEEE80211_HW_MFP_CAPABLE |
2024 IEEE80211_HW_SIGNAL_DBM |
2025 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
2026 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2027 IEEE80211_HW_AMPDU_AGGREGATION |
2028 IEEE80211_HW_WANT_MONITOR_VIF |
2029 IEEE80211_HW_QUEUE_CONTROL |
2030 IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
2031 if (rctbl)
2032 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2033
2034 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2035 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2036 WIPHY_FLAG_AP_UAPSD;
2037 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2038
2039 /* ask mac80211 to reserve space for magic */
2040 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
2041 hw->sta_data_size = sizeof(struct hwsim_sta_priv);
2042 hw->chanctx_data_size = sizeof(struct hwsim_chanctx_priv);
2043
2044 memcpy(data->channels_2ghz, hwsim_channels_2ghz,
2045 sizeof(hwsim_channels_2ghz));
2046 memcpy(data->channels_5ghz, hwsim_channels_5ghz,
2047 sizeof(hwsim_channels_5ghz));
2048 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
2049
2050 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
2051 struct ieee80211_supported_band *sband = &data->bands[band];
2052 switch (band) {
2053 case IEEE80211_BAND_2GHZ:
2054 sband->channels = data->channels_2ghz;
2055 sband->n_channels = ARRAY_SIZE(hwsim_channels_2ghz);
2056 sband->bitrates = data->rates;
2057 sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
2058 break;
2059 case IEEE80211_BAND_5GHZ:
2060 sband->channels = data->channels_5ghz;
2061 sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz);
2062 sband->bitrates = data->rates + 4;
2063 sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
2064 break;
2065 default:
2066 continue;
2067 }
1791 2068
1792 wiphy_debug(data->hw->wiphy, 2069 sband->ht_cap.ht_supported = true;
1793 "%s: send PS-Poll to %pM for aid %d\n", 2070 sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1794 __func__, vp->bssid, vp->aid); 2071 IEEE80211_HT_CAP_GRN_FLD |
2072 IEEE80211_HT_CAP_SGI_40 |
2073 IEEE80211_HT_CAP_DSSSCCK40;
2074 sband->ht_cap.ampdu_factor = 0x3;
2075 sband->ht_cap.ampdu_density = 0x6;
2076 memset(&sband->ht_cap.mcs, 0,
2077 sizeof(sband->ht_cap.mcs));
2078 sband->ht_cap.mcs.rx_mask[0] = 0xff;
2079 sband->ht_cap.mcs.rx_mask[1] = 0xff;
2080 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2081
2082 hw->wiphy->bands[band] = sband;
2083
2084 sband->vht_cap.vht_supported = true;
2085 sband->vht_cap.cap =
2086 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2087 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2088 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
2089 IEEE80211_VHT_CAP_RXLDPC |
2090 IEEE80211_VHT_CAP_SHORT_GI_80 |
2091 IEEE80211_VHT_CAP_SHORT_GI_160 |
2092 IEEE80211_VHT_CAP_TXSTBC |
2093 IEEE80211_VHT_CAP_RXSTBC_1 |
2094 IEEE80211_VHT_CAP_RXSTBC_2 |
2095 IEEE80211_VHT_CAP_RXSTBC_3 |
2096 IEEE80211_VHT_CAP_RXSTBC_4 |
2097 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
2098 sband->vht_cap.vht_mcs.rx_mcs_map =
2099 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2100 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2101 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2102 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2103 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2104 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2105 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2106 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2107 sband->vht_cap.vht_mcs.tx_mcs_map =
2108 sband->vht_cap.vht_mcs.rx_mcs_map;
2109 }
1795 2110
1796 skb = dev_alloc_skb(sizeof(*pspoll)); 2111 /* By default all radios belong to the first group */
1797 if (!skb) 2112 data->group = 1;
1798 return; 2113 mutex_init(&data->mutex);
1799 pspoll = (void *) skb_put(skb, sizeof(*pspoll));
1800 pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
1801 IEEE80211_STYPE_PSPOLL |
1802 IEEE80211_FCTL_PM);
1803 pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
1804 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
1805 memcpy(pspoll->ta, mac, ETH_ALEN);
1806 2114
1807 rcu_read_lock(); 2115 /* Enable frame retransmissions for lossy channels */
1808 mac80211_hwsim_tx_frame(data->hw, skb, 2116 hw->max_rates = 4;
1809 rcu_dereference(vif->chanctx_conf)->def.chan); 2117 hw->max_rate_tries = 11;
1810 rcu_read_unlock();
1811}
1812 2118
1813static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, 2119 if (reg_strict)
1814 struct ieee80211_vif *vif, int ps) 2120 hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
1815{ 2121 if (regd) {
1816 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 2122 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
1817 struct sk_buff *skb; 2123 wiphy_apply_custom_regulatory(hw->wiphy, regd);
1818 struct ieee80211_hdr *hdr; 2124 /* give the regulatory workqueue a chance to run */
2125 schedule_timeout_interruptible(1);
2126 }
1819 2127
1820 if (!vp->assoc) 2128 err = ieee80211_register_hw(hw);
1821 return; 2129 if (err < 0) {
2130 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
2131 err);
2132 goto failed_hw;
2133 }
1822 2134
1823 wiphy_debug(data->hw->wiphy, 2135 wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
1824 "%s: send data::nullfunc to %pM ps=%d\n",
1825 __func__, vp->bssid, ps);
1826 2136
1827 skb = dev_alloc_skb(sizeof(*hdr)); 2137 if (reg_alpha2)
1828 if (!skb) 2138 regulatory_hint(hw->wiphy, reg_alpha2);
1829 return;
1830 hdr = (void *) skb_put(skb, sizeof(*hdr) - ETH_ALEN);
1831 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
1832 IEEE80211_STYPE_NULLFUNC |
1833 (ps ? IEEE80211_FCTL_PM : 0));
1834 hdr->duration_id = cpu_to_le16(0);
1835 memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
1836 memcpy(hdr->addr2, mac, ETH_ALEN);
1837 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
1838 2139
1839 rcu_read_lock(); 2140 data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir);
1840 mac80211_hwsim_tx_frame(data->hw, skb, 2141 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
1841 rcu_dereference(vif->chanctx_conf)->def.chan); 2142 debugfs_create_file("group", 0666, data->debugfs, data,
1842 rcu_read_unlock(); 2143 &hwsim_fops_group);
1843} 2144 if (data->channels == 1)
2145 debugfs_create_file("dfs_simulate_radar", 0222,
2146 data->debugfs,
2147 data, &hwsim_simulate_radar);
1844 2148
2149 tasklet_hrtimer_init(&data->beacon_timer,
2150 mac80211_hwsim_beacon,
2151 CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
1845 2152
1846static void hwsim_send_nullfunc_ps(void *dat, u8 *mac, 2153 spin_lock_bh(&hwsim_radio_lock);
1847 struct ieee80211_vif *vif) 2154 list_add_tail(&data->list, &hwsim_radios);
1848{ 2155 spin_unlock_bh(&hwsim_radio_lock);
1849 struct mac80211_hwsim_data *data = dat;
1850 hwsim_send_nullfunc(data, mac, vif, 1);
1851}
1852 2156
2157 return idx;
1853 2158
1854static void hwsim_send_nullfunc_no_ps(void *dat, u8 *mac, 2159failed_hw:
1855 struct ieee80211_vif *vif) 2160 device_unregister(data->dev);
1856{ 2161failed_drvdata:
1857 struct mac80211_hwsim_data *data = dat; 2162 ieee80211_free_hw(hw);
1858 hwsim_send_nullfunc(data, mac, vif, 0); 2163failed:
2164 return err;
1859} 2165}
1860 2166
1861 2167static void mac80211_hwsim_destroy_radio(struct mac80211_hwsim_data *data)
1862static int hwsim_fops_ps_read(void *dat, u64 *val)
1863{ 2168{
1864 struct mac80211_hwsim_data *data = dat; 2169 debugfs_remove_recursive(data->debugfs);
1865 *val = data->ps; 2170 ieee80211_unregister_hw(data->hw);
1866 return 0; 2171 device_release_driver(data->dev);
2172 device_unregister(data->dev);
2173 ieee80211_free_hw(data->hw);
1867} 2174}
1868 2175
1869static int hwsim_fops_ps_write(void *dat, u64 val) 2176static void mac80211_hwsim_free(void)
1870{ 2177{
1871 struct mac80211_hwsim_data *data = dat; 2178 struct mac80211_hwsim_data *data;
1872 enum ps_mode old_ps;
1873
1874 if (val != PS_DISABLED && val != PS_ENABLED && val != PS_AUTO_POLL &&
1875 val != PS_MANUAL_POLL)
1876 return -EINVAL;
1877
1878 old_ps = data->ps;
1879 data->ps = val;
1880 2179
1881 if (val == PS_MANUAL_POLL) { 2180 spin_lock_bh(&hwsim_radio_lock);
1882 ieee80211_iterate_active_interfaces(data->hw, 2181 while ((data = list_first_entry_or_null(&hwsim_radios,
1883 IEEE80211_IFACE_ITER_NORMAL, 2182 struct mac80211_hwsim_data,
1884 hwsim_send_ps_poll, data); 2183 list))) {
1885 data->ps_poll_pending = true; 2184 list_del(&data->list);
1886 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { 2185 spin_unlock_bh(&hwsim_radio_lock);
1887 ieee80211_iterate_active_interfaces(data->hw, 2186 mac80211_hwsim_destroy_radio(data);
1888 IEEE80211_IFACE_ITER_NORMAL, 2187 spin_lock_bh(&hwsim_radio_lock);
1889 hwsim_send_nullfunc_ps,
1890 data);
1891 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
1892 ieee80211_iterate_active_interfaces(data->hw,
1893 IEEE80211_IFACE_ITER_NORMAL,
1894 hwsim_send_nullfunc_no_ps,
1895 data);
1896 } 2188 }
1897 2189 spin_unlock_bh(&hwsim_radio_lock);
1898 return 0; 2190 class_destroy(hwsim_class);
1899} 2191}
1900 2192
1901DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write, 2193static const struct net_device_ops hwsim_netdev_ops = {
1902 "%llu\n"); 2194 .ndo_start_xmit = hwsim_mon_xmit,
1903 2195 .ndo_change_mtu = eth_change_mtu,
1904 2196 .ndo_set_mac_address = eth_mac_addr,
1905static int hwsim_fops_group_read(void *dat, u64 *val) 2197 .ndo_validate_addr = eth_validate_addr,
1906{ 2198};
1907 struct mac80211_hwsim_data *data = dat;
1908 *val = data->group;
1909 return 0;
1910}
1911 2199
1912static int hwsim_fops_group_write(void *dat, u64 val) 2200static void hwsim_mon_setup(struct net_device *dev)
1913{ 2201{
1914 struct mac80211_hwsim_data *data = dat; 2202 dev->netdev_ops = &hwsim_netdev_ops;
1915 data->group = val; 2203 dev->destructor = free_netdev;
1916 return 0; 2204 ether_setup(dev);
2205 dev->tx_queue_len = 0;
2206 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2207 memset(dev->dev_addr, 0, ETH_ALEN);
2208 dev->dev_addr[0] = 0x12;
1917} 2209}
1918 2210
1919DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group, 2211static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
1920 hwsim_fops_group_read, hwsim_fops_group_write,
1921 "%llx\n");
1922
1923static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(
1924 struct mac_address *addr)
1925{ 2212{
1926 struct mac80211_hwsim_data *data; 2213 struct mac80211_hwsim_data *data;
1927 bool _found = false; 2214 bool _found = false;
1928 2215
1929 spin_lock_bh(&hwsim_radio_lock); 2216 spin_lock_bh(&hwsim_radio_lock);
1930 list_for_each_entry(data, &hwsim_radios, list) { 2217 list_for_each_entry(data, &hwsim_radios, list) {
1931 if (memcmp(data->addresses[1].addr, addr, 2218 if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
1932 sizeof(struct mac_address)) == 0) {
1933 _found = true; 2219 _found = true;
1934 break; 2220 break;
1935 } 2221 }
@@ -1952,27 +2238,26 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
1952 struct hwsim_tx_rate *tx_attempts; 2238 struct hwsim_tx_rate *tx_attempts;
1953 unsigned long ret_skb_ptr; 2239 unsigned long ret_skb_ptr;
1954 struct sk_buff *skb, *tmp; 2240 struct sk_buff *skb, *tmp;
1955 struct mac_address *src; 2241 const u8 *src;
1956 unsigned int hwsim_flags; 2242 unsigned int hwsim_flags;
1957
1958 int i; 2243 int i;
1959 bool found = false; 2244 bool found = false;
1960 2245
2246 if (info->snd_portid != wmediumd_portid)
2247 return -EINVAL;
2248
1961 if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || 2249 if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
1962 !info->attrs[HWSIM_ATTR_FLAGS] || 2250 !info->attrs[HWSIM_ATTR_FLAGS] ||
1963 !info->attrs[HWSIM_ATTR_COOKIE] || 2251 !info->attrs[HWSIM_ATTR_COOKIE] ||
1964 !info->attrs[HWSIM_ATTR_TX_INFO]) 2252 !info->attrs[HWSIM_ATTR_TX_INFO])
1965 goto out; 2253 goto out;
1966 2254
1967 src = (struct mac_address *)nla_data( 2255 src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
1968 info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
1969 hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); 2256 hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
1970
1971 ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); 2257 ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
1972 2258
1973 data2 = get_hwsim_data_ref_from_addr(src); 2259 data2 = get_hwsim_data_ref_from_addr(src);
1974 2260 if (!data2)
1975 if (data2 == NULL)
1976 goto out; 2261 goto out;
1977 2262
1978 /* look for the skb matching the cookie passed back from user */ 2263 /* look for the skb matching the cookie passed back from user */
@@ -2029,38 +2314,37 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
2029 2314
2030 struct mac80211_hwsim_data *data2; 2315 struct mac80211_hwsim_data *data2;
2031 struct ieee80211_rx_status rx_status; 2316 struct ieee80211_rx_status rx_status;
2032 struct mac_address *dst; 2317 const u8 *dst;
2033 int frame_data_len; 2318 int frame_data_len;
2034 char *frame_data; 2319 void *frame_data;
2035 struct sk_buff *skb = NULL; 2320 struct sk_buff *skb = NULL;
2036 2321
2322 if (info->snd_portid != wmediumd_portid)
2323 return -EINVAL;
2324
2037 if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || 2325 if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
2038 !info->attrs[HWSIM_ATTR_FRAME] || 2326 !info->attrs[HWSIM_ATTR_FRAME] ||
2039 !info->attrs[HWSIM_ATTR_RX_RATE] || 2327 !info->attrs[HWSIM_ATTR_RX_RATE] ||
2040 !info->attrs[HWSIM_ATTR_SIGNAL]) 2328 !info->attrs[HWSIM_ATTR_SIGNAL])
2041 goto out; 2329 goto out;
2042 2330
2043 dst = (struct mac_address *)nla_data( 2331 dst = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
2044 info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
2045
2046 frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); 2332 frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
2047 frame_data = (char *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); 2333 frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
2048 2334
2049 /* Allocate new skb here */ 2335 /* Allocate new skb here */
2050 skb = alloc_skb(frame_data_len, GFP_KERNEL); 2336 skb = alloc_skb(frame_data_len, GFP_KERNEL);
2051 if (skb == NULL) 2337 if (skb == NULL)
2052 goto err; 2338 goto err;
2053 2339
2054 if (frame_data_len <= IEEE80211_MAX_DATA_LEN) { 2340 if (frame_data_len > IEEE80211_MAX_DATA_LEN)
2055 /* Copy the data */
2056 memcpy(skb_put(skb, frame_data_len), frame_data,
2057 frame_data_len);
2058 } else
2059 goto err; 2341 goto err;
2060 2342
2061 data2 = get_hwsim_data_ref_from_addr(dst); 2343 /* Copy the data */
2344 memcpy(skb_put(skb, frame_data_len), frame_data, frame_data_len);
2062 2345
2063 if (data2 == NULL) 2346 data2 = get_hwsim_data_ref_from_addr(dst);
2347 if (!data2)
2064 goto out; 2348 goto out;
2065 2349
2066 /* check if radio is configured properly */ 2350 /* check if radio is configured properly */
@@ -2068,7 +2352,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
2068 if (data2->idle || !data2->started) 2352 if (data2->idle || !data2->started)
2069 goto out; 2353 goto out;
2070 2354
2071 /*A frame is received from user space*/ 2355 /* A frame is received from user space */
2072 memset(&rx_status, 0, sizeof(rx_status)); 2356 memset(&rx_status, 0, sizeof(rx_status));
2073 rx_status.freq = data2->channel->center_freq; 2357 rx_status.freq = data2->channel->center_freq;
2074 rx_status.band = data2->channel->band; 2358 rx_status.band = data2->channel->band;
@@ -2090,8 +2374,24 @@ out:
2090static int hwsim_register_received_nl(struct sk_buff *skb_2, 2374static int hwsim_register_received_nl(struct sk_buff *skb_2,
2091 struct genl_info *info) 2375 struct genl_info *info)
2092{ 2376{
2093 if (info == NULL) 2377 struct mac80211_hwsim_data *data;
2094 goto out; 2378 int chans = 1;
2379
2380 spin_lock_bh(&hwsim_radio_lock);
2381 list_for_each_entry(data, &hwsim_radios, list)
2382 chans = max(chans, data->channels);
2383 spin_unlock_bh(&hwsim_radio_lock);
2384
2385 /* In the future we should revise the userspace API and allow it
2386 * to set a flag that it does support multi-channel, then we can
2387 * let this pass conditionally on the flag.
2388 * For current userspace, prohibit it since it won't work right.
2389 */
2390 if (chans > 1)
2391 return -EOPNOTSUPP;
2392
2393 if (wmediumd_portid)
2394 return -EBUSY;
2095 2395
2096 wmediumd_portid = info->snd_portid; 2396 wmediumd_portid = info->snd_portid;
2097 2397
@@ -2099,9 +2399,53 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
2099 "switching to wmediumd mode with pid %d\n", info->snd_portid); 2399 "switching to wmediumd mode with pid %d\n", info->snd_portid);
2100 2400
2101 return 0; 2401 return 0;
2102out: 2402}
2103 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 2403
2104 return -EINVAL; 2404static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info)
2405{
2406 unsigned int chans = channels;
2407 const char *alpha2 = NULL;
2408 const struct ieee80211_regdomain *regd = NULL;
2409 bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
2410
2411 if (info->attrs[HWSIM_ATTR_CHANNELS])
2412 chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
2413
2414 if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
2415 alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
2416
2417 if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) {
2418 u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]);
2419
2420 if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom))
2421 return -EINVAL;
2422 regd = hwsim_world_regdom_custom[idx];
2423 }
2424
2425 return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict);
2426}
2427
2428static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info)
2429{
2430 struct mac80211_hwsim_data *data;
2431 int idx;
2432
2433 if (!info->attrs[HWSIM_ATTR_RADIO_ID])
2434 return -EINVAL;
2435 idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
2436
2437 spin_lock_bh(&hwsim_radio_lock);
2438 list_for_each_entry(data, &hwsim_radios, list) {
2439 if (data->idx != idx)
2440 continue;
2441 list_del(&data->list);
2442 spin_unlock_bh(&hwsim_radio_lock);
2443 mac80211_hwsim_destroy_radio(data);
2444 return 0;
2445 }
2446 spin_unlock_bh(&hwsim_radio_lock);
2447
2448 return -ENODEV;
2105} 2449}
2106 2450
2107/* Generic Netlink operations array */ 2451/* Generic Netlink operations array */
@@ -2122,6 +2466,18 @@ static const struct genl_ops hwsim_ops[] = {
2122 .policy = hwsim_genl_policy, 2466 .policy = hwsim_genl_policy,
2123 .doit = hwsim_tx_info_frame_received_nl, 2467 .doit = hwsim_tx_info_frame_received_nl,
2124 }, 2468 },
2469 {
2470 .cmd = HWSIM_CMD_CREATE_RADIO,
2471 .policy = hwsim_genl_policy,
2472 .doit = hwsim_create_radio_nl,
2473 .flags = GENL_ADMIN_PERM,
2474 },
2475 {
2476 .cmd = HWSIM_CMD_DESTROY_RADIO,
2477 .policy = hwsim_genl_policy,
2478 .doit = hwsim_destroy_radio_nl,
2479 .flags = GENL_ADMIN_PERM,
2480 },
2125}; 2481};
2126 2482
2127static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, 2483static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
@@ -2150,10 +2506,6 @@ static int hwsim_init_netlink(void)
2150{ 2506{
2151 int rc; 2507 int rc;
2152 2508
2153 /* userspace test API hasn't been adjusted for multi-channel */
2154 if (channels > 1)
2155 return 0;
2156
2157 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); 2509 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
2158 2510
2159 rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops); 2511 rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops);
@@ -2173,77 +2525,36 @@ failure:
2173 2525
2174static void hwsim_exit_netlink(void) 2526static void hwsim_exit_netlink(void)
2175{ 2527{
2176 int ret;
2177
2178 /* userspace test API hasn't been adjusted for multi-channel */
2179 if (channels > 1)
2180 return;
2181
2182 printk(KERN_INFO "mac80211_hwsim: closing netlink\n");
2183 /* unregister the notifier */ 2528 /* unregister the notifier */
2184 netlink_unregister_notifier(&hwsim_netlink_notifier); 2529 netlink_unregister_notifier(&hwsim_netlink_notifier);
2185 /* unregister the family */ 2530 /* unregister the family */
2186 ret = genl_unregister_family(&hwsim_genl_family); 2531 genl_unregister_family(&hwsim_genl_family);
2187 if (ret)
2188 printk(KERN_DEBUG "mac80211_hwsim: "
2189 "unregister family %i\n", ret);
2190} 2532}
2191 2533
2192static const struct ieee80211_iface_limit hwsim_if_limits[] = {
2193 { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
2194 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
2195 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2196#ifdef CONFIG_MAC80211_MESH
2197 BIT(NL80211_IFTYPE_MESH_POINT) |
2198#endif
2199 BIT(NL80211_IFTYPE_AP) |
2200 BIT(NL80211_IFTYPE_P2P_GO) },
2201 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
2202};
2203
2204static struct ieee80211_iface_combination hwsim_if_comb = {
2205 .limits = hwsim_if_limits,
2206 .n_limits = ARRAY_SIZE(hwsim_if_limits),
2207 .max_interfaces = 2048,
2208 .num_different_channels = 1,
2209};
2210
2211static int __init init_mac80211_hwsim(void) 2534static int __init init_mac80211_hwsim(void)
2212{ 2535{
2213 int i, err = 0; 2536 int i, err;
2214 u8 addr[ETH_ALEN];
2215 struct mac80211_hwsim_data *data;
2216 struct ieee80211_hw *hw;
2217 enum ieee80211_band band;
2218 2537
2219 if (radios < 1 || radios > 100) 2538 if (radios < 0 || radios > 100)
2220 return -EINVAL; 2539 return -EINVAL;
2221 2540
2222 if (channels < 1) 2541 if (channels < 1)
2223 return -EINVAL; 2542 return -EINVAL;
2224 2543
2225 if (channels > 1) { 2544 mac80211_hwsim_mchan_ops = mac80211_hwsim_ops;
2226 hwsim_if_comb.num_different_channels = channels; 2545 mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan;
2227 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 2546 mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan;
2228 mac80211_hwsim_ops.cancel_hw_scan = 2547 mac80211_hwsim_mchan_ops.sw_scan_start = NULL;
2229 mac80211_hwsim_cancel_hw_scan; 2548 mac80211_hwsim_mchan_ops.sw_scan_complete = NULL;
2230 mac80211_hwsim_ops.sw_scan_start = NULL; 2549 mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc;
2231 mac80211_hwsim_ops.sw_scan_complete = NULL; 2550 mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc;
2232 mac80211_hwsim_ops.remain_on_channel = 2551 mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx;
2233 mac80211_hwsim_roc; 2552 mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx;
2234 mac80211_hwsim_ops.cancel_remain_on_channel = 2553 mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx;
2235 mac80211_hwsim_croc; 2554 mac80211_hwsim_mchan_ops.assign_vif_chanctx =
2236 mac80211_hwsim_ops.add_chanctx = 2555 mac80211_hwsim_assign_vif_chanctx;
2237 mac80211_hwsim_add_chanctx; 2556 mac80211_hwsim_mchan_ops.unassign_vif_chanctx =
2238 mac80211_hwsim_ops.remove_chanctx = 2557 mac80211_hwsim_unassign_vif_chanctx;
2239 mac80211_hwsim_remove_chanctx;
2240 mac80211_hwsim_ops.change_chanctx =
2241 mac80211_hwsim_change_chanctx;
2242 mac80211_hwsim_ops.assign_vif_chanctx =
2243 mac80211_hwsim_assign_vif_chanctx;
2244 mac80211_hwsim_ops.unassign_vif_chanctx =
2245 mac80211_hwsim_unassign_vif_chanctx;
2246 }
2247 2558
2248 spin_lock_init(&hwsim_radio_lock); 2559 spin_lock_init(&hwsim_radio_lock);
2249 INIT_LIST_HEAD(&hwsim_radios); 2560 INIT_LIST_HEAD(&hwsim_radios);
@@ -2255,348 +2566,116 @@ static int __init init_mac80211_hwsim(void)
2255 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); 2566 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
2256 if (IS_ERR(hwsim_class)) { 2567 if (IS_ERR(hwsim_class)) {
2257 err = PTR_ERR(hwsim_class); 2568 err = PTR_ERR(hwsim_class);
2258 goto failed_unregister_driver; 2569 goto out_unregister_driver;
2259 } 2570 }
2260 2571
2261 memset(addr, 0, ETH_ALEN);
2262 addr[0] = 0x02;
2263
2264 for (i = 0; i < radios; i++) { 2572 for (i = 0; i < radios; i++) {
2265 printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", 2573 const char *reg_alpha2 = NULL;
2266 i); 2574 const struct ieee80211_regdomain *regd = NULL;
2267 hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); 2575 bool reg_strict = false;
2268 if (!hw) {
2269 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
2270 "failed\n");
2271 err = -ENOMEM;
2272 goto failed;
2273 }
2274 data = hw->priv;
2275 data->hw = hw;
2276
2277 data->dev = device_create(hwsim_class, NULL, 0, hw,
2278 "hwsim%d", i);
2279 if (IS_ERR(data->dev)) {
2280 printk(KERN_DEBUG
2281 "mac80211_hwsim: device_create failed (%ld)\n",
2282 PTR_ERR(data->dev));
2283 err = -ENOMEM;
2284 goto failed_drvdata;
2285 }
2286 data->dev->driver = &mac80211_hwsim_driver.driver;
2287 err = device_bind_driver(data->dev);
2288 if (err != 0) {
2289 printk(KERN_DEBUG
2290 "mac80211_hwsim: device_bind_driver failed (%d)\n",
2291 err);
2292 goto failed_hw;
2293 }
2294
2295 skb_queue_head_init(&data->pending);
2296 2576
2297 SET_IEEE80211_DEV(hw, data->dev);
2298 addr[3] = i >> 8;
2299 addr[4] = i;
2300 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
2301 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
2302 data->addresses[1].addr[0] |= 0x40;
2303 hw->wiphy->n_addresses = 2;
2304 hw->wiphy->addresses = data->addresses;
2305
2306 hw->wiphy->iface_combinations = &hwsim_if_comb;
2307 hw->wiphy->n_iface_combinations = 1;
2308
2309 if (channels > 1) {
2310 hw->wiphy->max_scan_ssids = 255;
2311 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2312 hw->wiphy->max_remain_on_channel_duration = 1000;
2313 }
2314
2315 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
2316 INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
2317
2318 hw->channel_change_time = 1;
2319 hw->queues = 5;
2320 hw->offchannel_tx_hw_queue = 4;
2321 hw->wiphy->interface_modes =
2322 BIT(NL80211_IFTYPE_STATION) |
2323 BIT(NL80211_IFTYPE_AP) |
2324 BIT(NL80211_IFTYPE_P2P_CLIENT) |
2325 BIT(NL80211_IFTYPE_P2P_GO) |
2326 BIT(NL80211_IFTYPE_ADHOC) |
2327 BIT(NL80211_IFTYPE_MESH_POINT) |
2328 BIT(NL80211_IFTYPE_P2P_DEVICE);
2329
2330 hw->flags = IEEE80211_HW_MFP_CAPABLE |
2331 IEEE80211_HW_SIGNAL_DBM |
2332 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
2333 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2334 IEEE80211_HW_AMPDU_AGGREGATION |
2335 IEEE80211_HW_WANT_MONITOR_VIF |
2336 IEEE80211_HW_QUEUE_CONTROL;
2337 if (rctbl)
2338 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2339
2340 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2341 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2342 WIPHY_FLAG_AP_UAPSD;
2343 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2344
2345 /* ask mac80211 to reserve space for magic */
2346 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
2347 hw->sta_data_size = sizeof(struct hwsim_sta_priv);
2348 hw->chanctx_data_size = sizeof(struct hwsim_chanctx_priv);
2349
2350 memcpy(data->channels_2ghz, hwsim_channels_2ghz,
2351 sizeof(hwsim_channels_2ghz));
2352 memcpy(data->channels_5ghz, hwsim_channels_5ghz,
2353 sizeof(hwsim_channels_5ghz));
2354 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
2355
2356 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
2357 struct ieee80211_supported_band *sband = &data->bands[band];
2358 switch (band) {
2359 case IEEE80211_BAND_2GHZ:
2360 sband->channels = data->channels_2ghz;
2361 sband->n_channels =
2362 ARRAY_SIZE(hwsim_channels_2ghz);
2363 sband->bitrates = data->rates;
2364 sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
2365 break;
2366 case IEEE80211_BAND_5GHZ:
2367 sband->channels = data->channels_5ghz;
2368 sband->n_channels =
2369 ARRAY_SIZE(hwsim_channels_5ghz);
2370 sband->bitrates = data->rates + 4;
2371 sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
2372 break;
2373 default:
2374 continue;
2375 }
2376
2377 sband->ht_cap.ht_supported = true;
2378 sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2379 IEEE80211_HT_CAP_GRN_FLD |
2380 IEEE80211_HT_CAP_SGI_40 |
2381 IEEE80211_HT_CAP_DSSSCCK40;
2382 sband->ht_cap.ampdu_factor = 0x3;
2383 sband->ht_cap.ampdu_density = 0x6;
2384 memset(&sband->ht_cap.mcs, 0,
2385 sizeof(sband->ht_cap.mcs));
2386 sband->ht_cap.mcs.rx_mask[0] = 0xff;
2387 sband->ht_cap.mcs.rx_mask[1] = 0xff;
2388 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2389
2390 hw->wiphy->bands[band] = sband;
2391
2392 sband->vht_cap.vht_supported = true;
2393 sband->vht_cap.cap =
2394 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2395 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2396 IEEE80211_VHT_CAP_RXLDPC |
2397 IEEE80211_VHT_CAP_SHORT_GI_80 |
2398 IEEE80211_VHT_CAP_SHORT_GI_160 |
2399 IEEE80211_VHT_CAP_TXSTBC |
2400 IEEE80211_VHT_CAP_RXSTBC_1 |
2401 IEEE80211_VHT_CAP_RXSTBC_2 |
2402 IEEE80211_VHT_CAP_RXSTBC_3 |
2403 IEEE80211_VHT_CAP_RXSTBC_4 |
2404 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
2405 sband->vht_cap.vht_mcs.rx_mcs_map =
2406 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 |
2407 IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 |
2408 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
2409 IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 |
2410 IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 |
2411 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
2412 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
2413 IEEE80211_VHT_MCS_SUPPORT_0_8 << 14);
2414 sband->vht_cap.vht_mcs.tx_mcs_map =
2415 sband->vht_cap.vht_mcs.rx_mcs_map;
2416 }
2417 /* By default all radios are belonging to the first group */
2418 data->group = 1;
2419 mutex_init(&data->mutex);
2420
2421 /* Enable frame retransmissions for lossy channels */
2422 hw->max_rates = 4;
2423 hw->max_rate_tries = 11;
2424
2425 /* Work to be done prior to ieee80211_register_hw() */
2426 switch (regtest) { 2577 switch (regtest) {
2427 case HWSIM_REGTEST_DISABLED:
2428 case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
2429 case HWSIM_REGTEST_DRIVER_REG_ALL:
2430 case HWSIM_REGTEST_DIFF_COUNTRY: 2578 case HWSIM_REGTEST_DIFF_COUNTRY:
2431 /* 2579 if (i < ARRAY_SIZE(hwsim_alpha2s))
2432 * Nothing to be done for driver regulatory domain 2580 reg_alpha2 = hwsim_alpha2s[i];
2433 * hints prior to ieee80211_register_hw()
2434 */
2435 break;
2436 case HWSIM_REGTEST_WORLD_ROAM:
2437 if (i == 0) {
2438 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2439 wiphy_apply_custom_regulatory(hw->wiphy,
2440 &hwsim_world_regdom_custom_01);
2441 }
2442 break;
2443 case HWSIM_REGTEST_CUSTOM_WORLD:
2444 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2445 wiphy_apply_custom_regulatory(hw->wiphy,
2446 &hwsim_world_regdom_custom_01);
2447 break;
2448 case HWSIM_REGTEST_CUSTOM_WORLD_2:
2449 if (i == 0) {
2450 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2451 wiphy_apply_custom_regulatory(hw->wiphy,
2452 &hwsim_world_regdom_custom_01);
2453 } else if (i == 1) {
2454 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2455 wiphy_apply_custom_regulatory(hw->wiphy,
2456 &hwsim_world_regdom_custom_02);
2457 }
2458 break;
2459 case HWSIM_REGTEST_STRICT_ALL:
2460 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
2461 break;
2462 case HWSIM_REGTEST_STRICT_FOLLOW:
2463 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
2464 if (i == 0)
2465 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
2466 break;
2467 case HWSIM_REGTEST_ALL:
2468 if (i == 0) {
2469 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2470 wiphy_apply_custom_regulatory(hw->wiphy,
2471 &hwsim_world_regdom_custom_01);
2472 } else if (i == 1) {
2473 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
2474 wiphy_apply_custom_regulatory(hw->wiphy,
2475 &hwsim_world_regdom_custom_02);
2476 } else if (i == 4)
2477 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
2478 break;
2479 default:
2480 break;
2481 }
2482
2483 /* give the regulatory workqueue a chance to run */
2484 if (regtest)
2485 schedule_timeout_interruptible(1);
2486 err = ieee80211_register_hw(hw);
2487 if (err < 0) {
2488 printk(KERN_DEBUG "mac80211_hwsim: "
2489 "ieee80211_register_hw failed (%d)\n", err);
2490 goto failed_hw;
2491 }
2492
2493 /* Work to be done after to ieee80211_register_hw() */
2494 switch (regtest) {
2495 case HWSIM_REGTEST_WORLD_ROAM:
2496 case HWSIM_REGTEST_DISABLED:
2497 break; 2581 break;
2498 case HWSIM_REGTEST_DRIVER_REG_FOLLOW: 2582 case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
2499 if (!i) 2583 if (!i)
2500 regulatory_hint(hw->wiphy, hwsim_alpha2s[0]); 2584 reg_alpha2 = hwsim_alpha2s[0];
2501 break; 2585 break;
2502 case HWSIM_REGTEST_DRIVER_REG_ALL:
2503 case HWSIM_REGTEST_STRICT_ALL: 2586 case HWSIM_REGTEST_STRICT_ALL:
2504 regulatory_hint(hw->wiphy, hwsim_alpha2s[0]); 2587 reg_strict = true;
2588 case HWSIM_REGTEST_DRIVER_REG_ALL:
2589 reg_alpha2 = hwsim_alpha2s[0];
2505 break; 2590 break;
2506 case HWSIM_REGTEST_DIFF_COUNTRY: 2591 case HWSIM_REGTEST_WORLD_ROAM:
2507 if (i < ARRAY_SIZE(hwsim_alpha2s)) 2592 if (i == 0)
2508 regulatory_hint(hw->wiphy, hwsim_alpha2s[i]); 2593 regd = &hwsim_world_regdom_custom_01;
2509 break; 2594 break;
2510 case HWSIM_REGTEST_CUSTOM_WORLD: 2595 case HWSIM_REGTEST_CUSTOM_WORLD:
2596 regd = &hwsim_world_regdom_custom_01;
2597 break;
2511 case HWSIM_REGTEST_CUSTOM_WORLD_2: 2598 case HWSIM_REGTEST_CUSTOM_WORLD_2:
2512 /* 2599 if (i == 0)
2513 * Nothing to be done for custom world regulatory 2600 regd = &hwsim_world_regdom_custom_01;
2514 * domains after to ieee80211_register_hw 2601 else if (i == 1)
2515 */ 2602 regd = &hwsim_world_regdom_custom_02;
2516 break; 2603 break;
2517 case HWSIM_REGTEST_STRICT_FOLLOW: 2604 case HWSIM_REGTEST_STRICT_FOLLOW:
2518 if (i == 0) 2605 if (i == 0) {
2519 regulatory_hint(hw->wiphy, hwsim_alpha2s[0]); 2606 reg_strict = true;
2607 reg_alpha2 = hwsim_alpha2s[0];
2608 }
2520 break; 2609 break;
2521 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: 2610 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
2522 if (i == 0) 2611 if (i == 0) {
2523 regulatory_hint(hw->wiphy, hwsim_alpha2s[0]); 2612 reg_strict = true;
2524 else if (i == 1) 2613 reg_alpha2 = hwsim_alpha2s[0];
2525 regulatory_hint(hw->wiphy, hwsim_alpha2s[1]); 2614 } else if (i == 1) {
2615 reg_alpha2 = hwsim_alpha2s[1];
2616 }
2526 break; 2617 break;
2527 case HWSIM_REGTEST_ALL: 2618 case HWSIM_REGTEST_ALL:
2528 if (i == 2) 2619 switch (i) {
2529 regulatory_hint(hw->wiphy, hwsim_alpha2s[0]); 2620 case 0:
2530 else if (i == 3) 2621 regd = &hwsim_world_regdom_custom_01;
2531 regulatory_hint(hw->wiphy, hwsim_alpha2s[1]); 2622 break;
2532 else if (i == 4) 2623 case 1:
2533 regulatory_hint(hw->wiphy, hwsim_alpha2s[2]); 2624 regd = &hwsim_world_regdom_custom_02;
2625 break;
2626 case 2:
2627 reg_alpha2 = hwsim_alpha2s[0];
2628 break;
2629 case 3:
2630 reg_alpha2 = hwsim_alpha2s[1];
2631 break;
2632 case 4:
2633 reg_strict = true;
2634 reg_alpha2 = hwsim_alpha2s[2];
2635 break;
2636 }
2534 break; 2637 break;
2535 default: 2638 default:
2536 break; 2639 break;
2537 } 2640 }
2538 2641
2539 wiphy_debug(hw->wiphy, "hwaddr %pm registered\n", 2642 err = mac80211_hwsim_create_radio(channels, reg_alpha2,
2540 hw->wiphy->perm_addr); 2643 regd, reg_strict);
2541 2644 if (err < 0)
2542 data->debugfs = debugfs_create_dir("hwsim", 2645 goto out_free_radios;
2543 hw->wiphy->debugfsdir);
2544 data->debugfs_ps = debugfs_create_file("ps", 0666,
2545 data->debugfs, data,
2546 &hwsim_fops_ps);
2547 data->debugfs_group = debugfs_create_file("group", 0666,
2548 data->debugfs, data,
2549 &hwsim_fops_group);
2550
2551 tasklet_hrtimer_init(&data->beacon_timer,
2552 mac80211_hwsim_beacon,
2553 CLOCK_REALTIME, HRTIMER_MODE_ABS);
2554
2555 list_add_tail(&data->list, &hwsim_radios);
2556 } 2646 }
2557 2647
2558 hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); 2648 hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
2559 if (hwsim_mon == NULL) { 2649 if (hwsim_mon == NULL) {
2560 err = -ENOMEM; 2650 err = -ENOMEM;
2561 goto failed; 2651 goto out_free_radios;
2562 } 2652 }
2563 2653
2564 rtnl_lock(); 2654 rtnl_lock();
2565
2566 err = dev_alloc_name(hwsim_mon, hwsim_mon->name); 2655 err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
2567 if (err < 0) 2656 if (err < 0) {
2568 goto failed_mon; 2657 rtnl_unlock();
2569 2658 goto out_free_radios;
2659 }
2570 2660
2571 err = register_netdevice(hwsim_mon); 2661 err = register_netdevice(hwsim_mon);
2572 if (err < 0) 2662 if (err < 0) {
2573 goto failed_mon; 2663 rtnl_unlock();
2574 2664 goto out_free_mon;
2665 }
2575 rtnl_unlock(); 2666 rtnl_unlock();
2576 2667
2577 err = hwsim_init_netlink(); 2668 err = hwsim_init_netlink();
2578 if (err < 0) 2669 if (err < 0)
2579 goto failed_nl; 2670 goto out_free_mon;
2580 2671
2581 return 0; 2672 return 0;
2582 2673
2583failed_nl: 2674out_free_mon:
2584 printk(KERN_DEBUG "mac_80211_hwsim: failed initializing netlink\n");
2585 return err;
2586
2587failed_mon:
2588 rtnl_unlock();
2589 free_netdev(hwsim_mon); 2675 free_netdev(hwsim_mon);
2676out_free_radios:
2590 mac80211_hwsim_free(); 2677 mac80211_hwsim_free();
2591 return err; 2678out_unregister_driver:
2592
2593failed_hw:
2594 device_unregister(data->dev);
2595failed_drvdata:
2596 ieee80211_free_hw(hw);
2597failed:
2598 mac80211_hwsim_free();
2599failed_unregister_driver:
2600 platform_driver_unregister(&mac80211_hwsim_driver); 2679 platform_driver_unregister(&mac80211_hwsim_driver);
2601 return err; 2680 return err;
2602} 2681}
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index afaad5a443b6..2747cce5a269 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -65,6 +65,9 @@ enum hwsim_tx_control_flags {
65 * kernel, uses: 65 * kernel, uses:
66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, 66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE 67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
68 * @HWSIM_CMD_CREATE_RADIO: create a new radio with the given parameters,
69 * returns the radio ID (>= 0) or negative on errors
70 * @HWSIM_CMD_DESTROY_RADIO: destroy a radio
68 * @__HWSIM_CMD_MAX: enum limit 71 * @__HWSIM_CMD_MAX: enum limit
69 */ 72 */
70enum { 73enum {
@@ -72,6 +75,8 @@ enum {
72 HWSIM_CMD_REGISTER, 75 HWSIM_CMD_REGISTER,
73 HWSIM_CMD_FRAME, 76 HWSIM_CMD_FRAME,
74 HWSIM_CMD_TX_INFO_FRAME, 77 HWSIM_CMD_TX_INFO_FRAME,
78 HWSIM_CMD_CREATE_RADIO,
79 HWSIM_CMD_DESTROY_RADIO,
75 __HWSIM_CMD_MAX, 80 __HWSIM_CMD_MAX,
76}; 81};
77#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) 82#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
@@ -94,6 +99,14 @@ enum {
94 space 99 space
95 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array 100 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
96 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame 101 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
102 * @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_RADIO
103 * command giving the number of channels supported by the new radio
104 * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO
105 * only to destroy a radio
106 * @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint
107 * (nla string, length 2)
108 * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
109 * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
97 * @__HWSIM_ATTR_MAX: enum limit 110 * @__HWSIM_ATTR_MAX: enum limit
98 */ 111 */
99 112
@@ -108,6 +121,11 @@ enum {
108 HWSIM_ATTR_SIGNAL, 121 HWSIM_ATTR_SIGNAL,
109 HWSIM_ATTR_TX_INFO, 122 HWSIM_ATTR_TX_INFO,
110 HWSIM_ATTR_COOKIE, 123 HWSIM_ATTR_COOKIE,
124 HWSIM_ATTR_CHANNELS,
125 HWSIM_ATTR_RADIO_ID,
126 HWSIM_ATTR_REG_HINT_ALPHA2,
127 HWSIM_ATTR_REG_CUSTOM_REG,
128 HWSIM_ATTR_REG_STRICT_REG,
111 __HWSIM_ATTR_MAX, 129 __HWSIM_ATTR_MAX,
112}; 130};
113#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 131#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 0b803c05cab3..6261f8c53d44 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -483,7 +483,7 @@ mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra)
483 483
484 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); 484 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
485 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { 485 list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
486 if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) && 486 if (ether_addr_equal_unaligned(tx_ba_tsr_tbl->ra, ra) &&
487 tx_ba_tsr_tbl->tid == tid) { 487 tx_ba_tsr_tbl->tid == tid) {
488 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, 488 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
489 flags); 489 flags);
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 1214c587fd08..63211707f939 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -69,9 +69,9 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
69 memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset); 69 memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset);
70 70
71 /* Copy SNAP header */ 71 /* Copy SNAP header */
72 snap.snap_type = 72 snap.snap_type = ((struct ethhdr *)skb_src->data)->h_proto;
73 le16_to_cpu(*(__le16 *) ((u8 *)skb_src->data + dt_offset)); 73
74 dt_offset += sizeof(u16); 74 dt_offset += sizeof(__be16);
75 75
76 memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr)); 76 memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr));
77 77
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index f7ff4725506a..ecdf34505b54 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -31,12 +31,12 @@ config MWIFIEX_PCIE
31 mwifiex_pcie. 31 mwifiex_pcie.
32 32
33config MWIFIEX_USB 33config MWIFIEX_USB
34 tristate "Marvell WiFi-Ex Driver for USB8797" 34 tristate "Marvell WiFi-Ex Driver for USB8797/8897"
35 depends on MWIFIEX && USB 35 depends on MWIFIEX && USB
36 select FW_LOADER 36 select FW_LOADER
37 ---help--- 37 ---help---
38 This adds support for wireless adapters based on Marvell 38 This adds support for wireless adapters based on Marvell
39 Avastar 88W8797 chipset with USB interface. 39 8797/8897 chipset with USB interface.
40 40
41 If you choose to build it as a module, it will be called 41 If you choose to build it as a module, it will be called
42 mwifiex_usb. 42 mwifiex_usb.
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index aeaea0e3b4c4..8bfc07cd330e 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -50,24 +50,24 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0), 50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
51 /* Channel 12 - 13 */ 51 /* Channel 12 - 13 */
52 REG_RULE(2467-10, 2472+10, 20, 3, 20, 52 REG_RULE(2467-10, 2472+10, 20, 3, 20,
53 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 53 NL80211_RRF_NO_IR),
54 /* Channel 14 */ 54 /* Channel 14 */
55 REG_RULE(2484-10, 2484+10, 20, 3, 20, 55 REG_RULE(2484-10, 2484+10, 20, 3, 20,
56 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 56 NL80211_RRF_NO_IR |
57 NL80211_RRF_NO_OFDM), 57 NL80211_RRF_NO_OFDM),
58 /* Channel 36 - 48 */ 58 /* Channel 36 - 48 */
59 REG_RULE(5180-10, 5240+10, 40, 3, 20, 59 REG_RULE(5180-10, 5240+10, 40, 3, 20,
60 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 60 NL80211_RRF_NO_IR),
61 /* Channel 149 - 165 */ 61 /* Channel 149 - 165 */
62 REG_RULE(5745-10, 5825+10, 40, 3, 20, 62 REG_RULE(5745-10, 5825+10, 40, 3, 20,
63 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 63 NL80211_RRF_NO_IR),
64 /* Channel 52 - 64 */ 64 /* Channel 52 - 64 */
65 REG_RULE(5260-10, 5320+10, 40, 3, 30, 65 REG_RULE(5260-10, 5320+10, 40, 3, 30,
66 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 66 NL80211_RRF_NO_IR |
67 NL80211_RRF_DFS), 67 NL80211_RRF_DFS),
68 /* Channel 100 - 140 */ 68 /* Channel 100 - 140 */
69 REG_RULE(5500-10, 5700+10, 40, 3, 30, 69 REG_RULE(5500-10, 5700+10, 40, 3, 30,
70 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 70 NL80211_RRF_NO_IR |
71 NL80211_RRF_DFS), 71 NL80211_RRF_DFS),
72 } 72 }
73}; 73};
@@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
184 */ 184 */
185static int 185static int
186mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 186mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
187 struct ieee80211_channel *chan, bool offchan, 187 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
188 unsigned int wait, const u8 *buf, size_t len,
189 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
190{ 188{
189 const u8 *buf = params->buf;
190 size_t len = params->len;
191 struct sk_buff *skb; 191 struct sk_buff *skb;
192 u16 pkt_len; 192 u16 pkt_len;
193 const struct ieee80211_mgmt *mgmt; 193 const struct ieee80211_mgmt *mgmt;
@@ -222,6 +222,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
222 tx_info = MWIFIEX_SKB_TXCB(skb); 222 tx_info = MWIFIEX_SKB_TXCB(skb);
223 tx_info->bss_num = priv->bss_num; 223 tx_info->bss_num = priv->bss_num;
224 tx_info->bss_type = priv->bss_type; 224 tx_info->bss_type = priv->bss_type;
225 tx_info->pkt_len = pkt_len;
225 226
226 mwifiex_form_mgmt_frame(skb, buf, len); 227 mwifiex_form_mgmt_frame(skb, buf, len);
227 mwifiex_queue_tx_pkt(priv, skb); 228 mwifiex_queue_tx_pkt(priv, skb);
@@ -537,23 +538,33 @@ static void mwifiex_reg_notifier(struct wiphy *wiphy,
537 struct regulatory_request *request) 538 struct regulatory_request *request)
538{ 539{
539 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 540 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
541 struct mwifiex_private *priv = mwifiex_get_priv(adapter,
542 MWIFIEX_BSS_ROLE_ANY);
540 543
541 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n", 544 wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for %c%c\n",
542 request->alpha2[0], request->alpha2[1]); 545 request->alpha2[0], request->alpha2[1]);
543 546
544 memcpy(adapter->country_code, request->alpha2, sizeof(request->alpha2));
545
546 switch (request->initiator) { 547 switch (request->initiator) {
547 case NL80211_REGDOM_SET_BY_DRIVER: 548 case NL80211_REGDOM_SET_BY_DRIVER:
548 case NL80211_REGDOM_SET_BY_CORE: 549 case NL80211_REGDOM_SET_BY_CORE:
549 case NL80211_REGDOM_SET_BY_USER: 550 case NL80211_REGDOM_SET_BY_USER:
550 break;
551 /* Todo: apply driver specific changes in channel flags based
552 on the request initiator if necessary. */
553 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 551 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
554 break; 552 break;
553 default:
554 wiphy_err(wiphy, "unknown regdom initiator: %d\n",
555 request->initiator);
556 return;
557 }
558
559 /* Don't send world or same regdom info to firmware */
560 if (strncmp(request->alpha2, "00", 2) &&
561 strncmp(request->alpha2, adapter->country_code,
562 sizeof(request->alpha2))) {
563 memcpy(adapter->country_code, request->alpha2,
564 sizeof(request->alpha2));
565 mwifiex_send_domain_info_cmd_fw(wiphy);
566 mwifiex_dnld_txpwr_table(priv);
555 } 567 }
556 mwifiex_send_domain_info_cmd_fw(wiphy);
557} 568}
558 569
559/* 570/*
@@ -1170,10 +1181,10 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
1170 else 1181 else
1171 bitmap_rates[1] = mask->control[band].legacy; 1182 bitmap_rates[1] = mask->control[band].legacy;
1172 1183
1173 /* Fill MCS rates */ 1184 /* Fill HT MCS rates */
1174 bitmap_rates[2] = mask->control[band].mcs[0]; 1185 bitmap_rates[2] = mask->control[band].ht_mcs[0];
1175 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) 1186 if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2)
1176 bitmap_rates[2] |= mask->control[band].mcs[1] << 8; 1187 bitmap_rates[2] |= mask->control[band].ht_mcs[1] << 8;
1177 1188
1178 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, 1189 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
1179 HostCmd_ACT_GEN_SET, 0, bitmap_rates); 1190 HostCmd_ACT_GEN_SET, 0, bitmap_rates);
@@ -1968,7 +1979,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1968 user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1979 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1969 user_scan_cfg->chan_list[i].radio_type = chan->band; 1980 user_scan_cfg->chan_list[i].radio_type = chan->band;
1970 1981
1971 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1982 if (chan->flags & IEEE80211_CHAN_NO_IR)
1972 user_scan_cfg->chan_list[i].scan_type = 1983 user_scan_cfg->chan_list[i].scan_type =
1973 MWIFIEX_SCAN_TYPE_PASSIVE; 1984 MWIFIEX_SCAN_TYPE_PASSIVE;
1974 else 1985 else
@@ -2438,7 +2449,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2438 ETH_ALEN); 2449 ETH_ALEN);
2439 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2450 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2440 ETH_ALEN; 2451 ETH_ALEN;
2441 mef_entry->filter[filt_num].offset = 14; 2452 mef_entry->filter[filt_num].offset = 28;
2442 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2453 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2443 if (filt_num) 2454 if (filt_num)
2444 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2455 mef_entry->filter[filt_num].filt_action = TYPE_OR;
@@ -2666,6 +2677,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2666 struct wiphy *wiphy; 2677 struct wiphy *wiphy;
2667 struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; 2678 struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA];
2668 u8 *country_code; 2679 u8 *country_code;
2680 u32 thr, retry;
2669 2681
2670 /* create a new wiphy for use with cfg80211 */ 2682 /* create a new wiphy for use with cfg80211 */
2671 wiphy = wiphy_new(&mwifiex_cfg80211_ops, 2683 wiphy = wiphy_new(&mwifiex_cfg80211_ops,
@@ -2702,9 +2714,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2702 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 2714 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2703 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2715 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2704 WIPHY_FLAG_AP_UAPSD | 2716 WIPHY_FLAG_AP_UAPSD |
2705 WIPHY_FLAG_CUSTOM_REGULATORY |
2706 WIPHY_FLAG_STRICT_REGULATORY |
2707 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2717 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2718 wiphy->regulatory_flags |=
2719 REGULATORY_CUSTOM_REG |
2720 REGULATORY_STRICT_REG;
2708 2721
2709 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2722 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2710 2723
@@ -2754,6 +2767,19 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2754 country_code); 2767 country_code);
2755 } 2768 }
2756 2769
2770 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
2771 HostCmd_ACT_GEN_GET, FRAG_THRESH_I, &thr);
2772 wiphy->frag_threshold = thr;
2773 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
2774 HostCmd_ACT_GEN_GET, RTS_THRESH_I, &thr);
2775 wiphy->rts_threshold = thr;
2776 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
2777 HostCmd_ACT_GEN_GET, SHORT_RETRY_LIM_I, &retry);
2778 wiphy->retry_short = (u8) retry;
2779 mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
2780 HostCmd_ACT_GEN_GET, LONG_RETRY_LIM_I, &retry);
2781 wiphy->retry_long = (u8) retry;
2782
2757 adapter->wiphy = wiphy; 2783 adapter->wiphy = wiphy;
2758 return ret; 2784 return ret;
2759} 2785}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index e47f4e3012b8..1ddc8b2e3722 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -312,14 +312,14 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
312 } 312 }
313 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) 313 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
314 == MWIFIEX_BSS_ROLE_STA) { 314 == MWIFIEX_BSS_ROLE_STA) {
315 if (!sleep_cfm_buf->resp_ctrl) 315 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl))
316 /* Response is not needed for sleep 316 /* Response is not needed for sleep
317 confirm command */ 317 confirm command */
318 adapter->ps_state = PS_STATE_SLEEP; 318 adapter->ps_state = PS_STATE_SLEEP;
319 else 319 else
320 adapter->ps_state = PS_STATE_SLEEP_CFM; 320 adapter->ps_state = PS_STATE_SLEEP_CFM;
321 321
322 if (!sleep_cfm_buf->resp_ctrl && 322 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl) &&
323 (adapter->is_hs_configured && 323 (adapter->is_hs_configured &&
324 !adapter->sleep_period.period)) { 324 !adapter->sleep_period.period)) {
325 adapter->pm_wakeup_card_req = true; 325 adapter->pm_wakeup_card_req = true;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 5c85d7803d00..3a21bd03d6db 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -130,6 +130,7 @@ struct mwifiex_txinfo {
130 u8 flags; 130 u8 flags;
131 u8 bss_num; 131 u8 bss_num;
132 u8 bss_type; 132 u8 bss_type;
133 u32 pkt_len;
133}; 134};
134 135
135enum mwifiex_wmm_ac_e { 136enum mwifiex_wmm_ac_e {
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index c8385ec77a86..5fa932d5f905 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -30,7 +30,7 @@ struct rfc_1042_hdr {
30 u8 llc_ssap; 30 u8 llc_ssap;
31 u8 llc_ctrl; 31 u8 llc_ctrl;
32 u8 snap_oui[3]; 32 u8 snap_oui[3];
33 u16 snap_type; 33 __be16 snap_type;
34}; 34};
35 35
36struct rx_packet_hdr { 36struct rx_packet_hdr {
@@ -226,7 +226,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
226 226
227/* HW_SPEC fw_cap_info */ 227/* HW_SPEC fw_cap_info */
228 228
229#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(13)|BIT(14))) 229#define ISSUPP_11ACENABLED(fw_cap_info) (fw_cap_info & (BIT(12)|BIT(13)))
230 230
231#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3) 231#define GET_VHTCAP_CHWDSET(vht_cap_info) ((vht_cap_info >> 2) & 0x3)
232#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3) 232#define GET_VHTNSSMCS(mcs_mapset, nss) ((mcs_mapset >> (2 * (nss - 1))) & 0x3)
@@ -468,8 +468,6 @@ enum P2P_MODES {
468#define MWIFIEX_CRITERIA_UNICAST BIT(1) 468#define MWIFIEX_CRITERIA_UNICAST BIT(1)
469#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 469#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
470 470
471#define CFG_DATA_TYPE_CAL 2
472
473struct mwifiex_ie_types_header { 471struct mwifiex_ie_types_header {
474 __le16 type; 472 __le16 type;
475 __le16 len; 473 __le16 len;
@@ -610,12 +608,12 @@ struct mwifiex_ie_types_tsf_timestamp {
610struct mwifiex_cf_param_set { 608struct mwifiex_cf_param_set {
611 u8 cfp_cnt; 609 u8 cfp_cnt;
612 u8 cfp_period; 610 u8 cfp_period;
613 u16 cfp_max_duration; 611 __le16 cfp_max_duration;
614 u16 cfp_duration_remaining; 612 __le16 cfp_duration_remaining;
615} __packed; 613} __packed;
616 614
617struct mwifiex_ibss_param_set { 615struct mwifiex_ibss_param_set {
618 u16 atim_window; 616 __le16 atim_window;
619} __packed; 617} __packed;
620 618
621struct mwifiex_ie_types_ss_param_set { 619struct mwifiex_ie_types_ss_param_set {
@@ -627,7 +625,7 @@ struct mwifiex_ie_types_ss_param_set {
627} __packed; 625} __packed;
628 626
629struct mwifiex_fh_param_set { 627struct mwifiex_fh_param_set {
630 u16 dwell_time; 628 __le16 dwell_time;
631 u8 hop_set; 629 u8 hop_set;
632 u8 hop_pattern; 630 u8 hop_pattern;
633 u8 hop_index; 631 u8 hop_index;
@@ -684,10 +682,10 @@ struct host_cmd_ds_802_11_key_material {
684} __packed; 682} __packed;
685 683
686struct host_cmd_ds_gen { 684struct host_cmd_ds_gen {
687 u16 command; 685 __le16 command;
688 u16 size; 686 __le16 size;
689 u16 seq_num; 687 __le16 seq_num;
690 u16 result; 688 __le16 result;
691}; 689};
692 690
693#define S_DS_GEN sizeof(struct host_cmd_ds_gen) 691#define S_DS_GEN sizeof(struct host_cmd_ds_gen)
@@ -820,8 +818,8 @@ struct ieee_types_cf_param_set {
820 u8 len; 818 u8 len;
821 u8 cfp_cnt; 819 u8 cfp_cnt;
822 u8 cfp_period; 820 u8 cfp_period;
823 u16 cfp_max_duration; 821 __le16 cfp_max_duration;
824 u16 cfp_duration_remaining; 822 __le16 cfp_duration_remaining;
825} __packed; 823} __packed;
826 824
827struct ieee_types_ibss_param_set { 825struct ieee_types_ibss_param_set {
@@ -957,7 +955,7 @@ struct mwifiex_hs_config_param {
957} __packed; 955} __packed;
958 956
959struct hs_activate_param { 957struct hs_activate_param {
960 u16 resp_ctrl; 958 __le16 resp_ctrl;
961} __packed; 959} __packed;
962 960
963struct host_cmd_ds_802_11_hs_cfg_enh { 961struct host_cmd_ds_802_11_hs_cfg_enh {
@@ -1131,7 +1129,7 @@ struct host_cmd_ds_802_11_bg_scan_query {
1131} __packed; 1129} __packed;
1132 1130
1133struct host_cmd_ds_802_11_bg_scan_query_rsp { 1131struct host_cmd_ds_802_11_bg_scan_query_rsp {
1134 u32 report_condition; 1132 __le32 report_condition;
1135 struct host_cmd_ds_802_11_scan_rsp scan_resp; 1133 struct host_cmd_ds_802_11_scan_rsp scan_resp;
1136} __packed; 1134} __packed;
1137 1135
@@ -1230,7 +1228,7 @@ struct mwifiex_ie_types_wmm_queue_status {
1230 struct mwifiex_ie_types_header header; 1228 struct mwifiex_ie_types_header header;
1231 u8 queue_index; 1229 u8 queue_index;
1232 u8 disabled; 1230 u8 disabled;
1233 u16 medium_time; 1231 __le16 medium_time;
1234 u8 flow_required; 1232 u8 flow_required;
1235 u8 flow_created; 1233 u8 flow_created;
1236 u32 reserved; 1234 u32 reserved;
@@ -1310,7 +1308,7 @@ struct mwifiex_ie_types_vht_oper {
1310 u8 chan_center_freq_1; 1308 u8 chan_center_freq_1;
1311 u8 chan_center_freq_2; 1309 u8 chan_center_freq_2;
1312 /* Basic MCS set map, each 2 bits stands for a NSS */ 1310 /* Basic MCS set map, each 2 bits stands for a NSS */
1313 u16 basic_mcs_map; 1311 __le16 basic_mcs_map;
1314} __packed; 1312} __packed;
1315 1313
1316struct mwifiex_ie_types_wmmcap { 1314struct mwifiex_ie_types_wmmcap {
@@ -1592,12 +1590,6 @@ struct mwifiex_ie_list {
1592 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX]; 1590 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
1593} __packed; 1591} __packed;
1594 1592
1595struct host_cmd_ds_802_11_cfg_data {
1596 __le16 action;
1597 __le16 type;
1598 __le16 data_len;
1599} __packed;
1600
1601struct coalesce_filt_field_param { 1593struct coalesce_filt_field_param {
1602 u8 operation; 1594 u8 operation;
1603 u8 operand_len; 1595 u8 operand_len;
@@ -1678,7 +1670,6 @@ struct host_cmd_ds_command {
1678 struct host_cmd_ds_sys_config uap_sys_config; 1670 struct host_cmd_ds_sys_config uap_sys_config;
1679 struct host_cmd_ds_sta_deauth sta_deauth; 1671 struct host_cmd_ds_sta_deauth sta_deauth;
1680 struct host_cmd_11ac_vht_cfg vht_cfg; 1672 struct host_cmd_11ac_vht_cfg vht_cfg;
1681 struct host_cmd_ds_802_11_cfg_data cfg_data;
1682 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 1673 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1683 } params; 1674 } params;
1684} __packed; 1675} __packed;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 6499117fce43..1d0a817f2bf0 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -643,7 +643,8 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
643 if (priv) 643 if (priv)
644 priv->stats.rx_dropped++; 644 priv->stats.rx_dropped++;
645 645
646 adapter->if_ops.data_complete(adapter, skb); 646 dev_kfree_skb_any(skb);
647 adapter->if_ops.data_complete(adapter);
647 } 648 }
648 } 649 }
649 650
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 8bb8988c435c..4d79761b9c87 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -648,6 +648,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
648 tx_info = MWIFIEX_SKB_TXCB(skb); 648 tx_info = MWIFIEX_SKB_TXCB(skb);
649 tx_info->bss_num = priv->bss_num; 649 tx_info->bss_num = priv->bss_num;
650 tx_info->bss_type = priv->bss_type; 650 tx_info->bss_type = priv->bss_type;
651 tx_info->pkt_len = skb->len;
651 652
652 /* Record the current time the packet was queued; used to 653 /* Record the current time the packet was queued; used to
653 * determine the amount of time the packet was queued in 654 * determine the amount of time the packet was queued in
@@ -749,7 +750,7 @@ static u16
749mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, 750mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
750 void *accel_priv) 751 void *accel_priv)
751{ 752{
752 skb->priority = cfg80211_classify8021d(skb); 753 skb->priority = cfg80211_classify8021d(skb, NULL);
753 return mwifiex_1d_to_wmm_queue[skb->priority]; 754 return mwifiex_1d_to_wmm_queue[skb->priority];
754} 755}
755 756
@@ -992,12 +993,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
992 rtnl_unlock(); 993 rtnl_unlock();
993 } 994 }
994 995
995 priv = adapter->priv[0]; 996 wiphy_unregister(adapter->wiphy);
996 if (!priv || !priv->wdev) 997 wiphy_free(adapter->wiphy);
997 goto exit_remove;
998
999 wiphy_unregister(priv->wdev->wiphy);
1000 wiphy_free(priv->wdev->wiphy);
1001 998
1002 mwifiex_terminate_workqueue(adapter); 999 mwifiex_terminate_workqueue(adapter);
1003 1000
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1d72f13adb9d..d8ad554ce39f 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -32,6 +32,7 @@
32#include <net/lib80211.h> 32#include <net/lib80211.h>
33#include <linux/firmware.h> 33#include <linux/firmware.h>
34#include <linux/ctype.h> 34#include <linux/ctype.h>
35#include <linux/of.h>
35 36
36#include "decl.h" 37#include "decl.h"
37#include "ioctl.h" 38#include "ioctl.h"
@@ -615,7 +616,7 @@ struct mwifiex_if_ops {
615 void (*cleanup_mpa_buf) (struct mwifiex_adapter *); 616 void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
616 int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *); 617 int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *);
617 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); 618 int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *);
618 int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); 619 int (*data_complete) (struct mwifiex_adapter *);
619 int (*init_fw_port) (struct mwifiex_adapter *); 620 int (*init_fw_port) (struct mwifiex_adapter *);
620 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); 621 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
621 void (*card_reset) (struct mwifiex_adapter *); 622 void (*card_reset) (struct mwifiex_adapter *);
@@ -739,6 +740,7 @@ struct mwifiex_adapter {
739 u8 scan_delay_cnt; 740 u8 scan_delay_cnt;
740 u8 empty_tx_q_cnt; 741 u8 empty_tx_q_cnt;
741 const struct firmware *cal_data; 742 const struct firmware *cal_data;
743 struct device_node *dt_node;
742 744
743 /* 11AC */ 745 /* 11AC */
744 u32 is_hw_11ac_capable; 746 u32 is_hw_11ac_capable;
@@ -1151,6 +1153,9 @@ void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
1151void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, 1153void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
1152 struct mwifiex_bssdescriptor *bss_desc); 1154 struct mwifiex_bssdescriptor *bss_desc);
1153int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); 1155int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv);
1156int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv,
1157 struct device_node *node, const char *prefix);
1158void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv);
1154 1159
1155extern const struct ethtool_ops mwifiex_ethtool_ops; 1160extern const struct ethtool_ops mwifiex_ethtool_ops;
1156 1161
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 8cf7d50a7603..0a8a26e10f01 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -515,14 +515,14 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
515 scan_chan_list[chan_idx].max_scan_time = 515 scan_chan_list[chan_idx].max_scan_time =
516 cpu_to_le16((u16) user_scan_in-> 516 cpu_to_le16((u16) user_scan_in->
517 chan_list[0].scan_time); 517 chan_list[0].scan_time);
518 else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 518 else if (ch->flags & IEEE80211_CHAN_NO_IR)
519 scan_chan_list[chan_idx].max_scan_time = 519 scan_chan_list[chan_idx].max_scan_time =
520 cpu_to_le16(adapter->passive_scan_time); 520 cpu_to_le16(adapter->passive_scan_time);
521 else 521 else
522 scan_chan_list[chan_idx].max_scan_time = 522 scan_chan_list[chan_idx].max_scan_time =
523 cpu_to_le16(adapter->active_scan_time); 523 cpu_to_le16(adapter->active_scan_time);
524 524
525 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 525 if (ch->flags & IEEE80211_CHAN_NO_IR)
526 scan_chan_list[chan_idx].chan_scan_mode_bitmap 526 scan_chan_list[chan_idx].chan_scan_mode_bitmap
527 |= MWIFIEX_PASSIVE_SCAN; 527 |= MWIFIEX_PASSIVE_SCAN;
528 else 528 else
@@ -1681,7 +1681,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1681 const u8 *ie_buf; 1681 const u8 *ie_buf;
1682 size_t ie_len; 1682 size_t ie_len;
1683 u16 channel = 0; 1683 u16 channel = 0;
1684 u64 fw_tsf = 0; 1684 __le64 fw_tsf = 0;
1685 u16 beacon_size = 0; 1685 u16 beacon_size = 0;
1686 u32 curr_bcn_bytes; 1686 u32 curr_bcn_bytes;
1687 u32 freq; 1687 u32 freq;
@@ -1815,7 +1815,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1815 ie_buf, ie_len, rssi, GFP_KERNEL); 1815 ie_buf, ie_len, rssi, GFP_KERNEL);
1816 bss_priv = (struct mwifiex_bss_priv *)bss->priv; 1816 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1817 bss_priv->band = band; 1817 bss_priv->band = band;
1818 bss_priv->fw_tsf = fw_tsf; 1818 bss_priv->fw_tsf = le64_to_cpu(fw_tsf);
1819 if (priv->media_connected && 1819 if (priv->media_connected &&
1820 !memcmp(bssid, 1820 !memcmp(bssid,
1821 priv->curr_bss_params.bss_descriptor 1821 priv->curr_bss_params.bss_descriptor
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 2181ee283d82..9208a8816b80 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -354,7 +354,7 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
354 } 354 }
355 if (hs_activate) { 355 if (hs_activate) {
356 hs_cfg->action = cpu_to_le16(HS_ACTIVATE); 356 hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
357 hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; 357 hs_cfg->params.hs_activate.resp_ctrl = cpu_to_le16(RESP_NEEDED);
358 } else { 358 } else {
359 hs_cfg->action = cpu_to_le16(HS_CONFIGURE); 359 hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
360 hs_cfg->params.hs_config.conditions = hscfg_param->conditions; 360 hs_cfg->params.hs_config.conditions = hscfg_param->conditions;
@@ -1156,30 +1156,62 @@ static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
1156 return d - dst; 1156 return d - dst;
1157} 1157}
1158 1158
1159int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv,
1160 struct device_node *node, const char *prefix)
1161{
1162#ifdef CONFIG_OF
1163 struct property *prop;
1164 size_t len = strlen(prefix);
1165 int ret;
1166
1167 /* look for all matching property names */
1168 for_each_property_of_node(node, prop) {
1169 if (len > strlen(prop->name) ||
1170 strncmp(prop->name, prefix, len))
1171 continue;
1172
1173 /* property header is 6 bytes, data must fit in cmd buffer */
1174 if (prop && prop->value && prop->length > 6 &&
1175 prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) {
1176 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
1177 HostCmd_ACT_GEN_SET, 0,
1178 prop);
1179 if (ret)
1180 return ret;
1181 }
1182 }
1183#endif
1184 return 0;
1185}
1186
1159/* This function prepares command of set_cfg_data. */ 1187/* This function prepares command of set_cfg_data. */
1160static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv, 1188static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
1161 struct host_cmd_ds_command *cmd, 1189 struct host_cmd_ds_command *cmd, void *data_buf)
1162 u16 cmd_action)
1163{ 1190{
1164 struct host_cmd_ds_802_11_cfg_data *cfg_data = &cmd->params.cfg_data;
1165 struct mwifiex_adapter *adapter = priv->adapter; 1191 struct mwifiex_adapter *adapter = priv->adapter;
1166 u32 len, cal_data_offset; 1192 struct property *prop = data_buf;
1167 u8 *tmp_cmd = (u8 *)cmd; 1193 u32 len;
1194 u8 *data = (u8 *)cmd + S_DS_GEN;
1195 int ret;
1168 1196
1169 cal_data_offset = S_DS_GEN + sizeof(*cfg_data); 1197 if (prop) {
1170 if ((adapter->cal_data->data) && (adapter->cal_data->size > 0)) 1198 len = prop->length;
1199 ret = of_property_read_u8_array(adapter->dt_node, prop->name,
1200 data, len);
1201 if (ret)
1202 return ret;
1203 dev_dbg(adapter->dev,
1204 "download cfg_data from device tree: %s\n", prop->name);
1205 } else if (adapter->cal_data->data && adapter->cal_data->size > 0) {
1171 len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data, 1206 len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
1172 adapter->cal_data->size, 1207 adapter->cal_data->size, data);
1173 (u8 *)(tmp_cmd + cal_data_offset)); 1208 dev_dbg(adapter->dev, "download cfg_data from config file\n");
1174 else 1209 } else {
1175 return -1; 1210 return -1;
1176 1211 }
1177 cfg_data->action = cpu_to_le16(cmd_action);
1178 cfg_data->type = cpu_to_le16(CFG_DATA_TYPE_CAL);
1179 cfg_data->data_len = cpu_to_le16(len);
1180 1212
1181 cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA); 1213 cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
1182 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*cfg_data) + len); 1214 cmd->size = cpu_to_le16(S_DS_GEN + len);
1183 1215
1184 return 0; 1216 return 0;
1185} 1217}
@@ -1267,7 +1299,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1267 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr); 1299 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
1268 break; 1300 break;
1269 case HostCmd_CMD_CFG_DATA: 1301 case HostCmd_CMD_CFG_DATA:
1270 ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, cmd_action); 1302 ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, data_buf);
1271 break; 1303 break;
1272 case HostCmd_CMD_MAC_CONTROL: 1304 case HostCmd_CMD_MAC_CONTROL:
1273 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action, 1305 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
@@ -1527,7 +1559,19 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1527 if (ret) 1559 if (ret)
1528 return -1; 1560 return -1;
1529 1561
1530 /* Download calibration data to firmware */ 1562 /* Download calibration data to firmware.
1563 * The cal-data can be read from device tree and/or
1564 * a configuration file and downloaded to firmware.
1565 */
1566 adapter->dt_node =
1567 of_find_node_by_name(NULL, "marvell_cfgdata");
1568 if (adapter->dt_node) {
1569 ret = mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node,
1570 "marvell,caldata");
1571 if (ret)
1572 return -1;
1573 }
1574
1531 if (adapter->cal_data) { 1575 if (adapter->cal_data) {
1532 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, 1576 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
1533 HostCmd_ACT_GEN_SET, 0, NULL); 1577 HostCmd_ACT_GEN_SET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 2675ca7f8d14..24523e4015cb 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -338,8 +338,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
338 if (!data_buf) 338 if (!data_buf)
339 return -1; 339 return -1;
340 340
341 pg_tlv_hdr = (struct mwifiex_types_power_group *) 341 pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf);
342 ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
343 pg = (struct mwifiex_power_group *) 342 pg = (struct mwifiex_power_group *)
344 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); 343 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
345 length = le16_to_cpu(pg_tlv_hdr->length); 344 length = le16_to_cpu(pg_tlv_hdr->length);
@@ -383,19 +382,25 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
383 struct mwifiex_types_power_group *pg_tlv_hdr; 382 struct mwifiex_types_power_group *pg_tlv_hdr;
384 struct mwifiex_power_group *pg; 383 struct mwifiex_power_group *pg;
385 u16 action = le16_to_cpu(txp_cfg->action); 384 u16 action = le16_to_cpu(txp_cfg->action);
385 u16 tlv_buf_left;
386 386
387 switch (action) { 387 pg_tlv_hdr = (struct mwifiex_types_power_group *)
388 case HostCmd_ACT_GEN_GET: 388 ((u8 *)txp_cfg +
389 pg_tlv_hdr = (struct mwifiex_types_power_group *) 389 sizeof(struct host_cmd_ds_txpwr_cfg));
390 ((u8 *) txp_cfg +
391 sizeof(struct host_cmd_ds_txpwr_cfg));
392 390
393 pg = (struct mwifiex_power_group *) 391 pg = (struct mwifiex_power_group *)
394 ((u8 *) pg_tlv_hdr + 392 ((u8 *)pg_tlv_hdr +
395 sizeof(struct mwifiex_types_power_group)); 393 sizeof(struct mwifiex_types_power_group));
396 394
395 tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
396 if (tlv_buf_left <
397 le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
398 return 0;
399
400 switch (action) {
401 case HostCmd_ACT_GEN_GET:
397 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 402 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
398 mwifiex_get_power_level(priv, txp_cfg); 403 mwifiex_get_power_level(priv, pg_tlv_hdr);
399 404
400 priv->tx_power_level = (u16) pg->power_min; 405 priv->tx_power_level = (u16) pg->power_min;
401 break; 406 break;
@@ -404,14 +409,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
404 if (!le32_to_cpu(txp_cfg->mode)) 409 if (!le32_to_cpu(txp_cfg->mode))
405 break; 410 break;
406 411
407 pg_tlv_hdr = (struct mwifiex_types_power_group *)
408 ((u8 *) txp_cfg +
409 sizeof(struct host_cmd_ds_txpwr_cfg));
410
411 pg = (struct mwifiex_power_group *)
412 ((u8 *) pg_tlv_hdr +
413 sizeof(struct mwifiex_types_power_group));
414
415 if (pg->power_max == pg->power_min) 412 if (pg->power_max == pg->power_min)
416 priv->tx_power_level = (u16) pg->power_min; 413 priv->tx_power_level = (u16) pg->power_min;
417 break; 414 break;
@@ -785,8 +782,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
785 } 782 }
786 783
787 /* If BSSID is diff, modify current BSS parameters */ 784 /* If BSSID is diff, modify current BSS parameters */
788 if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address, 785 if (!ether_addr_equal(priv->curr_bss_params.bss_descriptor.mac_address, ibss_coal_resp->bssid)) {
789 ibss_coal_resp->bssid, ETH_ALEN)) {
790 /* BSSID */ 786 /* BSSID */
791 memcpy(priv->curr_bss_params.bss_descriptor.mac_address, 787 memcpy(priv->curr_bss_params.bss_descriptor.mac_address,
792 ibss_coal_resp->bssid, ETH_ALEN); 788 ibss_coal_resp->bssid, ETH_ALEN);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index a09398fe9e2a..c5cb2ed19ec2 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -184,6 +184,16 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
184 return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc); 184 return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
185} 185}
186 186
187void mwifiex_dnld_txpwr_table(struct mwifiex_private *priv)
188{
189 if (priv->adapter->dt_node) {
190 char txpwr[] = {"marvell,00_txpwrlimit"};
191
192 memcpy(&txpwr[8], priv->adapter->country_code, 2);
193 mwifiex_dnld_dt_cfgdata(priv, priv->adapter->dt_node, txpwr);
194 }
195}
196
187static int mwifiex_process_country_ie(struct mwifiex_private *priv, 197static int mwifiex_process_country_ie(struct mwifiex_private *priv,
188 struct cfg80211_bss *bss) 198 struct cfg80211_bss *bss)
189{ 199{
@@ -205,6 +215,14 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
205 return 0; 215 return 0;
206 } 216 }
207 217
218 if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) {
219 rcu_read_unlock();
220 wiphy_dbg(priv->wdev->wiphy,
221 "11D: skip setting domain info in FW\n");
222 return 0;
223 }
224 memcpy(priv->adapter->country_code, &country_ie[2], 2);
225
208 domain_info->country_code[0] = country_ie[2]; 226 domain_info->country_code[0] = country_ie[2];
209 domain_info->country_code[1] = country_ie[3]; 227 domain_info->country_code[1] = country_ie[3];
210 domain_info->country_code[2] = ' '; 228 domain_info->country_code[2] = ' ';
@@ -226,6 +244,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
226 return -1; 244 return -1;
227 } 245 }
228 246
247 mwifiex_dnld_txpwr_table(priv);
248
229 return 0; 249 return 0;
230} 250}
231 251
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index bb22664923ef..4651d676df38 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -36,12 +36,12 @@ mwifiex_discard_gratuitous_arp(struct mwifiex_private *priv,
36 struct sk_buff *skb) 36 struct sk_buff *skb)
37{ 37{
38 const struct mwifiex_arp_eth_header *arp; 38 const struct mwifiex_arp_eth_header *arp;
39 struct ethhdr *eth_hdr; 39 struct ethhdr *eth;
40 struct ipv6hdr *ipv6; 40 struct ipv6hdr *ipv6;
41 struct icmp6hdr *icmpv6; 41 struct icmp6hdr *icmpv6;
42 42
43 eth_hdr = (struct ethhdr *)skb->data; 43 eth = (struct ethhdr *)skb->data;
44 switch (ntohs(eth_hdr->h_proto)) { 44 switch (ntohs(eth->h_proto)) {
45 case ETH_P_ARP: 45 case ETH_P_ARP:
46 arp = (void *)(skb->data + sizeof(struct ethhdr)); 46 arp = (void *)(skb->data + sizeof(struct ethhdr));
47 if (arp->hdr.ar_op == htons(ARPOP_REPLY) || 47 if (arp->hdr.ar_op == htons(ARPOP_REPLY) ||
@@ -87,16 +87,19 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
87 struct rx_packet_hdr *rx_pkt_hdr; 87 struct rx_packet_hdr *rx_pkt_hdr;
88 struct rxpd *local_rx_pd; 88 struct rxpd *local_rx_pd;
89 int hdr_chop; 89 int hdr_chop;
90 struct ethhdr *eth_hdr; 90 struct ethhdr *eth;
91 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
92 91
93 local_rx_pd = (struct rxpd *) (skb->data); 92 local_rx_pd = (struct rxpd *) (skb->data);
94 93
95 rx_pkt_hdr = (void *)local_rx_pd + 94 rx_pkt_hdr = (void *)local_rx_pd +
96 le16_to_cpu(local_rx_pd->rx_pkt_offset); 95 le16_to_cpu(local_rx_pd->rx_pkt_offset);
97 96
98 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr, 97 if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
99 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) { 98 sizeof(bridge_tunnel_header))) ||
99 (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
100 sizeof(rfc1042_header)) &&
101 ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
102 ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
100 /* 103 /*
101 * Replace the 803 header and rfc1042 header (llc/snap) with an 104 * Replace the 803 header and rfc1042 header (llc/snap) with an
102 * EthernetII header, keep the src/dst and snap_type 105 * EthernetII header, keep the src/dst and snap_type
@@ -106,7 +109,7 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
106 * To create the Ethernet II, just move the src, dst address 109 * To create the Ethernet II, just move the src, dst address
107 * right before the snap_type. 110 * right before the snap_type.
108 */ 111 */
109 eth_hdr = (struct ethhdr *) 112 eth = (struct ethhdr *)
110 ((u8 *) &rx_pkt_hdr->eth803_hdr 113 ((u8 *) &rx_pkt_hdr->eth803_hdr
111 + sizeof(rx_pkt_hdr->eth803_hdr) + 114 + sizeof(rx_pkt_hdr->eth803_hdr) +
112 sizeof(rx_pkt_hdr->rfc1042_hdr) 115 sizeof(rx_pkt_hdr->rfc1042_hdr)
@@ -114,14 +117,14 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
114 - sizeof(rx_pkt_hdr->eth803_hdr.h_source) 117 - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
115 - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type)); 118 - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
116 119
117 memcpy(eth_hdr->h_source, rx_pkt_hdr->eth803_hdr.h_source, 120 memcpy(eth->h_source, rx_pkt_hdr->eth803_hdr.h_source,
118 sizeof(eth_hdr->h_source)); 121 sizeof(eth->h_source));
119 memcpy(eth_hdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest, 122 memcpy(eth->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
120 sizeof(eth_hdr->h_dest)); 123 sizeof(eth->h_dest));
121 124
122 /* Chop off the rxpd + the excess memory from the 802.2/llc/snap 125 /* Chop off the rxpd + the excess memory from the 802.2/llc/snap
123 header that was removed. */ 126 header that was removed. */
124 hdr_chop = (u8 *) eth_hdr - (u8 *) local_rx_pd; 127 hdr_chop = (u8 *) eth - (u8 *) local_rx_pd;
125 } else { 128 } else {
126 /* Chop off the rxpd */ 129 /* Chop off the rxpd */
127 hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr - 130 hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr -
@@ -185,12 +188,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
185 "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n", 188 "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
186 skb->len, rx_pkt_offset, rx_pkt_length); 189 skb->len, rx_pkt_offset, rx_pkt_length);
187 priv->stats.rx_dropped++; 190 priv->stats.rx_dropped++;
188 191 dev_kfree_skb_any(skb);
189 if (adapter->if_ops.data_complete)
190 adapter->if_ops.data_complete(adapter, skb);
191 else
192 dev_kfree_skb_any(skb);
193
194 return ret; 192 return ret;
195 } 193 }
196 194
@@ -226,7 +224,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
226 * directly to os. Don't pass thru rx reordering 224 * directly to os. Don't pass thru rx reordering
227 */ 225 */
228 if (!IS_11N_ENABLED(priv) || 226 if (!IS_11N_ENABLED(priv) ||
229 memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) { 227 !ether_addr_equal_unaligned(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest)) {
230 mwifiex_process_rx_packet(priv, skb); 228 mwifiex_process_rx_packet(priv, skb);
231 return ret; 229 return ret;
232 } 230 }
@@ -244,12 +242,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
244 ret = mwifiex_11n_rx_reorder_pkt(priv, seq_num, local_rx_pd->priority, 242 ret = mwifiex_11n_rx_reorder_pkt(priv, seq_num, local_rx_pd->priority,
245 ta, (u8) rx_pkt_type, skb); 243 ta, (u8) rx_pkt_type, skb);
246 244
247 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { 245 if (ret || (rx_pkt_type == PKT_TYPE_BAR))
248 if (adapter->if_ops.data_complete) 246 dev_kfree_skb_any(skb);
249 adapter->if_ops.data_complete(adapter, skb);
250 else
251 dev_kfree_skb_any(skb);
252 }
253 247
254 if (ret) 248 if (ret)
255 priv->stats.rx_dropped++; 249 priv->stats.rx_dropped++;
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 7b581af24f5f..354d64c9606f 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -148,6 +148,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
148 tx_info = MWIFIEX_SKB_TXCB(skb); 148 tx_info = MWIFIEX_SKB_TXCB(skb);
149 tx_info->bss_num = priv->bss_num; 149 tx_info->bss_num = priv->bss_num;
150 tx_info->bss_type = priv->bss_type; 150 tx_info->bss_type = priv->bss_type;
151 tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
151 skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN); 152 skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
152 skb_push(skb, sizeof(struct txpd)); 153 skb_push(skb, sizeof(struct txpd));
153 154
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 8f923d0d2ba6..37f26afd4314 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -40,6 +40,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
40 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 40 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
41 struct rxpd *local_rx_pd; 41 struct rxpd *local_rx_pd;
42 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 42 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
43 int ret;
43 44
44 local_rx_pd = (struct rxpd *) (skb->data); 45 local_rx_pd = (struct rxpd *) (skb->data);
45 /* Get the BSS number from rxpd, get corresponding priv */ 46 /* Get the BSS number from rxpd, get corresponding priv */
@@ -58,9 +59,15 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
58 rx_info->bss_type = priv->bss_type; 59 rx_info->bss_type = priv->bss_type;
59 60
60 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 61 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
61 return mwifiex_process_uap_rx_packet(priv, skb); 62 ret = mwifiex_process_uap_rx_packet(priv, skb);
63 else
64 ret = mwifiex_process_sta_rx_packet(priv, skb);
65
66 /* Decrement RX pending counter for each packet */
67 if (adapter->if_ops.data_complete)
68 adapter->if_ops.data_complete(adapter);
62 69
63 return mwifiex_process_sta_rx_packet(priv, skb); 70 return ret;
64} 71}
65EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); 72EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
66 73
@@ -105,7 +112,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
105 112
106 switch (ret) { 113 switch (ret) {
107 case -ENOSR: 114 case -ENOSR:
108 dev_err(adapter->dev, "data: -ENOSR is returned\n"); 115 dev_dbg(adapter->dev, "data: -ENOSR is returned\n");
109 break; 116 break;
110 case -EBUSY: 117 case -EBUSY:
111 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && 118 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
@@ -168,7 +175,7 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
168 mwifiex_set_trans_start(priv->netdev); 175 mwifiex_set_trans_start(priv->netdev);
169 if (!status) { 176 if (!status) {
170 priv->stats.tx_packets++; 177 priv->stats.tx_packets++;
171 priv->stats.tx_bytes += skb->len; 178 priv->stats.tx_bytes += tx_info->pkt_len;
172 if (priv->tx_timeout_cnt) 179 if (priv->tx_timeout_cnt)
173 priv->tx_timeout_cnt = 0; 180 priv->tx_timeout_cnt = 0;
174 } else { 181 } else {
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 92f76d655e6c..3c74eb254927 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -98,7 +98,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
98 int hdr_chop; 98 int hdr_chop;
99 struct timeval tv; 99 struct timeval tv;
100 struct ethhdr *p_ethhdr; 100 struct ethhdr *p_ethhdr;
101 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
102 101
103 uap_rx_pd = (struct uap_rxpd *)(skb->data); 102 uap_rx_pd = (struct uap_rxpd *)(skb->data);
104 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); 103 rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
@@ -112,8 +111,12 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
112 return; 111 return;
113 } 112 }
114 113
115 if (!memcmp(&rx_pkt_hdr->rfc1042_hdr, 114 if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
116 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) { 115 sizeof(bridge_tunnel_header))) ||
116 (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
117 sizeof(rfc1042_header)) &&
118 ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
119 ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
117 /* Replace the 803 header and rfc1042 header (llc/snap) with 120 /* Replace the 803 header and rfc1042 header (llc/snap) with
118 * an Ethernet II header, keep the src/dst and snap_type 121 * an Ethernet II header, keep the src/dst and snap_type
119 * (ethertype). 122 * (ethertype).
@@ -144,7 +147,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
144 hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd; 147 hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd;
145 } 148 }
146 149
147 /* Chop off the leading header bytes so the it points 150 /* Chop off the leading header bytes so that it points
148 * to the start of either the reconstructed EthII frame 151 * to the start of either the reconstructed EthII frame
149 * or the 802.2/llc/snap frame. 152 * or the 802.2/llc/snap frame.
150 */ 153 */
@@ -176,6 +179,19 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
176 tx_info->bss_type = priv->bss_type; 179 tx_info->bss_type = priv->bss_type;
177 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT; 180 tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
178 181
182 if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) {
183 /* Update bridge packet statistics as the
184 * packet is not going to kernel/upper layer.
185 */
186 priv->stats.rx_bytes += skb->len;
187 priv->stats.rx_packets++;
188
189 /* Sending bridge packet to TX queue, so save the packet
190 * length in TXCB to update statistics in TX complete.
191 */
192 tx_info->pkt_len = skb->len;
193 }
194
179 do_gettimeofday(&tv); 195 do_gettimeofday(&tv);
180 skb->tstamp = timeval_to_ktime(tv); 196 skb->tstamp = timeval_to_ktime(tv);
181 mwifiex_wmm_add_buf_txqueue(priv, skb); 197 mwifiex_wmm_add_buf_txqueue(priv, skb);
@@ -264,12 +280,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
264 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset), 280 skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset),
265 le16_to_cpu(uap_rx_pd->rx_pkt_length)); 281 le16_to_cpu(uap_rx_pd->rx_pkt_length));
266 priv->stats.rx_dropped++; 282 priv->stats.rx_dropped++;
267 283 dev_kfree_skb_any(skb);
268 if (adapter->if_ops.data_complete)
269 adapter->if_ops.data_complete(adapter, skb);
270 else
271 dev_kfree_skb_any(skb);
272
273 return 0; 284 return 0;
274 } 285 }
275 286
@@ -323,12 +334,8 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
323 uap_rx_pd->priority, ta, pkt_type, 334 uap_rx_pd->priority, ta, pkt_type,
324 skb); 335 skb);
325 336
326 if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { 337 if (ret || (rx_pkt_type == PKT_TYPE_BAR))
327 if (adapter->if_ops.data_complete) 338 dev_kfree_skb_any(skb);
328 adapter->if_ops.data_complete(adapter, skb);
329 else
330 dev_kfree_skb_any(skb);
331 }
332 339
333 if (ret) 340 if (ret)
334 priv->stats.rx_dropped++; 341 priv->stats.rx_dropped++;
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index edf5b7a24900..e8ebbd4bc3cd 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -22,15 +22,21 @@
22 22
23#define USB_VERSION "1.0" 23#define USB_VERSION "1.0"
24 24
25static const char usbdriver_name[] = "usb8797"; 25static const char usbdriver_name[] = "usb8xxx";
26 26
27static struct mwifiex_if_ops usb_ops; 27static struct mwifiex_if_ops usb_ops;
28static struct semaphore add_remove_card_sem; 28static struct semaphore add_remove_card_sem;
29static struct usb_card_rec *usb_card; 29static struct usb_card_rec *usb_card;
30 30
31static struct usb_device_id mwifiex_usb_table[] = { 31static struct usb_device_id mwifiex_usb_table[] = {
32 {USB_DEVICE(USB8797_VID, USB8797_PID_1)}, 32 /* 8797 */
33 {USB_DEVICE_AND_INTERFACE_INFO(USB8797_VID, USB8797_PID_2, 33 {USB_DEVICE(USB8XXX_VID, USB8797_PID_1)},
34 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2,
35 USB_CLASS_VENDOR_SPEC,
36 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
37 /* 8897 */
38 {USB_DEVICE(USB8XXX_VID, USB8897_PID_1)},
39 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8897_PID_2,
34 USB_CLASS_VENDOR_SPEC, 40 USB_CLASS_VENDOR_SPEC,
35 USB_SUBCLASS_VENDOR_SPEC, 0xff)}, 41 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
36 { } /* Terminating entry */ 42 { } /* Terminating entry */
@@ -343,10 +349,20 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
343 id_vendor, id_product, bcd_device); 349 id_vendor, id_product, bcd_device);
344 350
345 /* PID_1 is used for firmware downloading only */ 351 /* PID_1 is used for firmware downloading only */
346 if (id_product == USB8797_PID_1) 352 switch (id_product) {
347 card->usb_boot_state = USB8797_FW_DNLD; 353 case USB8797_PID_1:
348 else 354 case USB8897_PID_1:
349 card->usb_boot_state = USB8797_FW_READY; 355 card->usb_boot_state = USB8XXX_FW_DNLD;
356 break;
357 case USB8797_PID_2:
358 case USB8897_PID_2:
359 card->usb_boot_state = USB8XXX_FW_READY;
360 break;
361 default:
362 pr_warning("unknown id_product %#x\n", id_product);
363 card->usb_boot_state = USB8XXX_FW_DNLD;
364 break;
365 }
350 366
351 card->udev = udev; 367 card->udev = udev;
352 card->intf = intf; 368 card->intf = intf;
@@ -755,9 +771,20 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
755 771
756 card->adapter = adapter; 772 card->adapter = adapter;
757 adapter->dev = &card->udev->dev; 773 adapter->dev = &card->udev->dev;
758 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
759 usb_card = card; 774 usb_card = card;
760 775
776 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
777 case USB8897_PID_1:
778 case USB8897_PID_2:
779 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
780 break;
781 case USB8797_PID_1:
782 case USB8797_PID_2:
783 default:
784 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
785 break;
786 }
787
761 return 0; 788 return 0;
762} 789}
763 790
@@ -773,7 +800,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
773{ 800{
774 int ret = 0; 801 int ret = 0;
775 u8 *firmware = fw->fw_buf, *recv_buff; 802 u8 *firmware = fw->fw_buf, *recv_buff;
776 u32 retries = USB8797_FW_MAX_RETRY, dlen; 803 u32 retries = USB8XXX_FW_MAX_RETRY, dlen;
777 u32 fw_seqnum = 0, tlen = 0, dnld_cmd = 0; 804 u32 fw_seqnum = 0, tlen = 0, dnld_cmd = 0;
778 struct fw_data *fwdata; 805 struct fw_data *fwdata;
779 struct fw_sync_header sync_fw; 806 struct fw_sync_header sync_fw;
@@ -875,7 +902,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
875 continue; 902 continue;
876 } 903 }
877 904
878 retries = USB8797_FW_MAX_RETRY; 905 retries = USB8XXX_FW_MAX_RETRY;
879 break; 906 break;
880 } 907 }
881 fw_seqnum++; 908 fw_seqnum++;
@@ -899,13 +926,13 @@ static int mwifiex_usb_dnld_fw(struct mwifiex_adapter *adapter,
899 int ret; 926 int ret;
900 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; 927 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
901 928
902 if (card->usb_boot_state == USB8797_FW_DNLD) { 929 if (card->usb_boot_state == USB8XXX_FW_DNLD) {
903 ret = mwifiex_prog_fw_w_helper(adapter, fw); 930 ret = mwifiex_prog_fw_w_helper(adapter, fw);
904 if (ret) 931 if (ret)
905 return -1; 932 return -1;
906 933
907 /* Boot state changes after successful firmware download */ 934 /* Boot state changes after successful firmware download */
908 if (card->usb_boot_state == USB8797_FW_DNLD) 935 if (card->usb_boot_state == USB8XXX_FW_DNLD)
909 return -1; 936 return -1;
910 } 937 }
911 938
@@ -938,11 +965,9 @@ static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter,
938 return 0; 965 return 0;
939} 966}
940 967
941static int mwifiex_usb_data_complete(struct mwifiex_adapter *adapter, 968static int mwifiex_usb_data_complete(struct mwifiex_adapter *adapter)
942 struct sk_buff *skb)
943{ 969{
944 atomic_dec(&adapter->rx_pending); 970 atomic_dec(&adapter->rx_pending);
945 dev_kfree_skb_any(skb);
946 971
947 return 0; 972 return 0;
948} 973}
@@ -1041,4 +1066,5 @@ MODULE_AUTHOR("Marvell International Ltd.");
1041MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION); 1066MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION);
1042MODULE_VERSION(USB_VERSION); 1067MODULE_VERSION(USB_VERSION);
1043MODULE_LICENSE("GPL v2"); 1068MODULE_LICENSE("GPL v2");
1044MODULE_FIRMWARE("mrvl/usb8797_uapsta.bin"); 1069MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME);
1070MODULE_FIRMWARE(USB8897_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 98c4316cd1a9..15b73d12e998 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -22,19 +22,23 @@
22 22
23#include <linux/usb.h> 23#include <linux/usb.h>
24 24
25#define USB8797_VID 0x1286 25#define USB8XXX_VID 0x1286
26
26#define USB8797_PID_1 0x2043 27#define USB8797_PID_1 0x2043
27#define USB8797_PID_2 0x2044 28#define USB8797_PID_2 0x2044
29#define USB8897_PID_1 0x2045
30#define USB8897_PID_2 0x2046
28 31
29#define USB8797_FW_DNLD 1 32#define USB8XXX_FW_DNLD 1
30#define USB8797_FW_READY 2 33#define USB8XXX_FW_READY 2
31#define USB8797_FW_MAX_RETRY 3 34#define USB8XXX_FW_MAX_RETRY 3
32 35
33#define MWIFIEX_TX_DATA_URB 6 36#define MWIFIEX_TX_DATA_URB 6
34#define MWIFIEX_RX_DATA_URB 6 37#define MWIFIEX_RX_DATA_URB 6
35#define MWIFIEX_USB_TIMEOUT 100 38#define MWIFIEX_USB_TIMEOUT 100
36 39
37#define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin" 40#define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin"
41#define USB8897_DEFAULT_FW_NAME "mrvl/usb8897_uapsta.bin"
38 42
39#define FW_DNLD_TX_BUF_SIZE 620 43#define FW_DNLD_TX_BUF_SIZE 620
40#define FW_DNLD_RX_BUF_SIZE 2048 44#define FW_DNLD_RX_BUF_SIZE 2048
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 5d9e150f4111..9b82e225880c 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -191,6 +191,9 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
191 if (!skb) 191 if (!skb)
192 return -1; 192 return -1;
193 193
194 priv->stats.rx_bytes += skb->len;
195 priv->stats.rx_packets++;
196
194 skb->dev = priv->netdev; 197 skb->dev = priv->netdev;
195 skb->protocol = eth_type_trans(skb, priv->netdev); 198 skb->protocol = eth_type_trans(skb, priv->netdev);
196 skb->ip_summed = CHECKSUM_NONE; 199 skb->ip_summed = CHECKSUM_NONE;
@@ -217,8 +220,6 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
217 (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) 220 (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE))
218 skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); 221 skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE);
219 222
220 priv->stats.rx_bytes += skb->len;
221 priv->stats.rx_packets++;
222 if (in_interrupt()) 223 if (in_interrupt())
223 netif_rx(skb); 224 netif_rx(skb);
224 else 225 else
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b953ad621e0b..4987c3f942ce 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -9,7 +9,6 @@
9 * warranty of any kind, whether express or implied. 9 * warranty of any kind, whether express or implied.
10 */ 10 */
11 11
12#include <linux/init.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
@@ -1258,7 +1257,7 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
1258{ 1257{
1259 return priv->capture_beacon && 1258 return priv->capture_beacon &&
1260 ieee80211_is_beacon(wh->frame_control) && 1259 ieee80211_is_beacon(wh->frame_control) &&
1261 ether_addr_equal(wh->addr3, priv->capture_bssid); 1260 ether_addr_equal_64bits(wh->addr3, priv->capture_bssid);
1262} 1261}
1263 1262
1264static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, 1263static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
@@ -5893,8 +5892,6 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5893 5892
5894 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0; 5893 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
5895 5894
5896 hw->channel_change_time = 10;
5897
5898 hw->queues = MWL8K_TX_WMM_QUEUES; 5895 hw->queues = MWL8K_TX_WMM_QUEUES;
5899 5896
5900 /* Set rssi values to dBm */ 5897 /* Set rssi values to dBm */
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index 75c15bc7b34c..43790fbea0e0 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -40,7 +40,6 @@
40 40
41#include <linux/module.h> 41#include <linux/module.h>
42#include <linux/kernel.h> 42#include <linux/kernel.h>
43#include <linux/init.h>
44#include <linux/delay.h> 43#include <linux/delay.h>
45 44
46#include "hermes.h" 45#include "hermes.h"
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index d21d95939316..c0a27377d9e2 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <pcmcia/cistpl.h> 19#include <pcmcia/cistpl.h>
21#include <pcmcia/cisreg.h> 20#include <pcmcia/cisreg.h>
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index bdfe637953f4..f9805c9353d2 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -52,7 +52,6 @@
52#include <linux/signal.h> 52#include <linux/signal.h>
53#include <linux/errno.h> 53#include <linux/errno.h>
54#include <linux/poll.h> 54#include <linux/poll.h>
55#include <linux/init.h>
56#include <linux/slab.h> 55#include <linux/slab.h>
57#include <linux/fcntl.h> 56#include <linux/fcntl.h>
58#include <linux/spinlock.h> 57#include <linux/spinlock.h>
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index e2264bc12ebf..b60048c95e0a 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -23,7 +23,6 @@
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <pcmcia/cistpl.h> 27#include <pcmcia/cistpl.h>
29#include <pcmcia/cisreg.h> 28#include <pcmcia/cisreg.h>
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index d43e3740e45d..0fe67d2da208 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -16,7 +16,6 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/firmware.h> 19#include <linux/firmware.h>
21#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
22#include <linux/sort.h> 21#include <linux/sort.h>
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index b3879fbf5368..bc065e8e348b 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -16,7 +16,6 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/firmware.h> 20#include <linux/firmware.h>
22#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c
index 3837e1eec5f4..1f6fd5ff5531 100644
--- a/drivers/net/wireless/p54/led.c
+++ b/drivers/net/wireless/p54/led.c
@@ -16,7 +16,6 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/firmware.h> 19#include <linux/firmware.h>
21#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
22 21
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 067e6f2fd050..eede90b63f84 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -16,7 +16,6 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/firmware.h> 20#include <linux/firmware.h>
22#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
@@ -757,7 +756,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
757 BIT(NL80211_IFTYPE_AP) | 756 BIT(NL80211_IFTYPE_AP) |
758 BIT(NL80211_IFTYPE_MESH_POINT); 757 BIT(NL80211_IFTYPE_MESH_POINT);
759 758
760 dev->channel_change_time = 1000; /* TODO: find actual value */
761 priv->beacon_req_id = cpu_to_le32(0); 759 priv->beacon_req_id = cpu_to_le32(0);
762 priv->tx_stats[P54_QUEUE_BEACON].limit = 1; 760 priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
763 priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1; 761 priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
diff --git a/drivers/net/wireless/p54/net2280.h b/drivers/net/wireless/p54/net2280.h
index e3ed893b5aaf..aedfaf24f386 100644
--- a/drivers/net/wireless/p54/net2280.h
+++ b/drivers/net/wireless/p54/net2280.h
@@ -20,8 +20,7 @@
20 * GNU General Public License for more details. 20 * GNU General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software 23 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */ 24 */
26 25
27/*-------------------------------------------------------------------------*/ 26/*-------------------------------------------------------------------------*/
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index f9a07b0d83ac..d411de409050 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -13,7 +13,6 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15 15
16#include <linux/init.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
19#include <linux/firmware.h> 18#include <linux/firmware.h>
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index e328d3058c41..6e635cfa24c8 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -12,7 +12,6 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/usb.h> 15#include <linux/usb.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index f95de0d16216..153c61539ec8 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -17,7 +17,6 @@
17 */ 17 */
18 18
19#include <linux/export.h> 19#include <linux/export.h>
20#include <linux/init.h>
21#include <linux/firmware.h> 20#include <linux/firmware.h>
22#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
23#include <asm/div64.h> 22#include <asm/div64.h>
@@ -308,7 +307,7 @@ static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
308 return; 307 return;
309 308
310 /* only consider beacons from the associated BSSID */ 309 /* only consider beacons from the associated BSSID */
311 if (!ether_addr_equal(hdr->addr3, priv->bssid)) 310 if (!ether_addr_equal_64bits(hdr->addr3, priv->bssid))
312 return; 311 return;
313 312
314 tim = p54_find_ie(skb, WLAN_EID_TIM); 313 tim = p54_find_ie(skb, WLAN_EID_TIM);
@@ -587,7 +586,7 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
587 chan = priv->curchan; 586 chan = priv->curchan;
588 if (chan) { 587 if (chan) {
589 struct survey_info *survey = &priv->survey[chan->hw_value]; 588 struct survey_info *survey = &priv->survey[chan->hw_value];
590 survey->noise = clamp_t(s8, priv->noise, -128, 127); 589 survey->noise = clamp(priv->noise, -128, 127);
591 survey->channel_time = priv->survey_raw.active; 590 survey->channel_time = priv->survey_raw.active;
592 survey->channel_time_tx = priv->survey_raw.tx; 591 survey->channel_time_tx = priv->survey_raw.tx;
593 survey->channel_time_busy = priv->survey_raw.tx + 592 survey->channel_time_busy = priv->survey_raw.tx +
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67bccbd0..333c1a2f882e 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -12,8 +12,7 @@
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 16 *
18 */ 17 */
19 18
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index 19c33d313734..547ab885610b 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 8863a6cb2388..78fa64d3f223 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 18 *
20 */ 19 */
21 20
@@ -25,6 +24,7 @@
25#include <linux/if_arp.h> 24#include <linux/if_arp.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/etherdevice.h>
28 28
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30 30
@@ -1861,7 +1861,7 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
1861 if (mutex_lock_interruptible(&acl->lock)) 1861 if (mutex_lock_interruptible(&acl->lock))
1862 return -ERESTARTSYS; 1862 return -ERESTARTSYS;
1863 list_for_each_entry(entry, &acl->mac_list, _list) { 1863 list_for_each_entry(entry, &acl->mac_list, _list) {
1864 if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { 1864 if (ether_addr_equal(entry->addr, addr->sa_data)) {
1865 list_del(&entry->_list); 1865 list_del(&entry->_list);
1866 acl->size--; 1866 acl->size--;
1867 kfree(entry); 1867 kfree(entry);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index a34bceb6e3cd..842a2549facc 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -13,8 +13,7 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * 17 *
19 */ 18 */
20 19
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index 59e31258d450..83fec557997e 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -13,8 +13,7 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * 17 *
19 */ 18 */
20 19
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index e05d9b4c8317..931cf440ff18 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -13,8 +13,7 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * 17 *
19 */ 18 */
20 19
@@ -914,7 +913,6 @@ islpci_setup(struct pci_dev *pdev)
914 do_islpci_free_memory: 913 do_islpci_free_memory:
915 islpci_free_memory(priv); 914 islpci_free_memory(priv);
916 do_free_netdev: 915 do_free_netdev:
917 pci_set_drvdata(pdev, NULL);
918 free_netdev(ndev); 916 free_netdev(ndev);
919 priv = NULL; 917 priv = NULL;
920 return NULL; 918 return NULL;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index c40403877f97..f6f088e05fe4 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 18 *
20 */ 19 */
21 20
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 799e148d0370..674658f2e6ef 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
index 6ca30a5b7bfb..80f50f1bc6f2 100644
--- a/drivers/net/wireless/prism54/islpci_eth.h
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 9e68e0cb718e..1105a12dbde8 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -12,8 +12,7 @@
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 16 *
18 */ 17 */
19 18
@@ -199,7 +198,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
199 do_unregister_netdev: 198 do_unregister_netdev:
200 unregister_netdev(ndev); 199 unregister_netdev(ndev);
201 islpci_free_memory(priv); 200 islpci_free_memory(priv);
202 pci_set_drvdata(pdev, NULL);
203 free_netdev(ndev); 201 free_netdev(ndev);
204 priv = NULL; 202 priv = NULL;
205 do_pci_clear_mwi: 203 do_pci_clear_mwi:
@@ -247,7 +245,6 @@ prism54_remove(struct pci_dev *pdev)
247 /* free the PCI memory and unmap the remapped page */ 245 /* free the PCI memory and unmap the remapped page */
248 islpci_free_memory(priv); 246 islpci_free_memory(priv);
249 247
250 pci_set_drvdata(pdev, NULL);
251 free_netdev(ndev); 248 free_netdev(ndev);
252 priv = NULL; 249 priv = NULL;
253 250
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 9f19cceab487..0de14dfa68cc 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -12,8 +12,7 @@
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 16 *
18 */ 17 */
19 18
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index 0db93db9b675..700c434c8803 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -12,8 +12,7 @@
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * 16 *
18 */ 17 */
19 18
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 056af38e72e3..47b34bfe890a 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d4acd8..cf5141df8474 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
index aa1d1747784f..bc1401eb4b9d 100644
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ b/drivers/net/wireless/prism54/prismcompat.h
@@ -11,8 +11,7 @@
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * 15 *
17 */ 16 */
18 17
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 9b557a1bb7f8..cbf0a589d32a 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -17,8 +17,7 @@
17 * GNU General Public License for more details. 17 * GNU General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 * 21 *
23 * Changes: 22 * Changes:
24 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000 23 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 8169a85c4498..5028557aa18a 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -15,8 +15,7 @@
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 19 *
21 * Portions of this file are based on NDISwrapper project, 20 * Portions of this file are based on NDISwrapper project,
22 * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani 21 * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
@@ -27,7 +26,6 @@
27// #define VERBOSE // more; success messages 26// #define VERBOSE // more; success messages
28 27
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/netdevice.h> 29#include <linux/netdevice.h>
32#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
33#include <linux/ethtool.h> 31#include <linux/ethtool.h>
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 38ed9a3e44c8..4ccfef5094e0 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -26,7 +24,6 @@
26 24
27#include <linux/delay.h> 25#include <linux/delay.h>
28#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
29#include <linux/init.h>
30#include <linux/kernel.h> 27#include <linux/kernel.h>
31#include <linux/module.h> 28#include <linux/module.h>
32#include <linux/pci.h> 29#include <linux/pci.h>
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index e4b07f0aa3cc..0fd3a9d01a60 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 0ac5c589ddce..abc5f56f29fe 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -26,7 +24,6 @@
26 24
27#include <linux/delay.h> 25#include <linux/delay.h>
28#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
29#include <linux/init.h>
30#include <linux/kernel.h> 27#include <linux/kernel.h>
31#include <linux/module.h> 28#include <linux/module.h>
32#include <linux/pci.h> 29#include <linux/pci.h>
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 9c10068e4987..573e87bcc553 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 85acc79f68b8..9f16824cd1bc 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -26,7 +24,6 @@
26 24
27#include <linux/delay.h> 25#include <linux/delay.h>
28#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
29#include <linux/init.h>
30#include <linux/kernel.h> 27#include <linux/kernel.h>
31#include <linux/module.h> 28#include <linux/module.h>
32#include <linux/slab.h> 29#include <linux/slab.h>
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 1b91a4cef965..afba0739c3b8 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index aab6b5e4f5dd..a394a9a95919 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -21,9 +21,7 @@
21 GNU General Public License for more details. 21 GNU General Public License for more details.
22 22
23 You should have received a copy of the GNU General Public License 23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the 24 along with this program; if not, see <http://www.gnu.org/licenses/>.
25 Free Software Foundation, Inc.,
26 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */ 25 */
28 26
29/* 27/*
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 776aff3678ff..b8f5b06006c4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -24,9 +24,7 @@
24 GNU General Public License for more details. 24 GNU General Public License for more details.
25 25
26 You should have received a copy of the GNU General Public License 26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the 27 along with this program; if not, see <http://www.gnu.org/licenses/>.
28 Free Software Foundation, Inc.,
29 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 28 */
31 29
32/* 30/*
@@ -5462,15 +5460,14 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
5462 5460
5463 rt2800_bbp_write(rt2x00dev, 68, 0x0b); 5461 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
5464 5462
5465 rt2800_bbp_write(rt2x00dev, 69, 0x12); 5463 rt2800_bbp_write(rt2x00dev, 69, 0x0d);
5464 rt2800_bbp_write(rt2x00dev, 70, 0x06);
5466 rt2800_bbp_write(rt2x00dev, 73, 0x13); 5465 rt2800_bbp_write(rt2x00dev, 73, 0x13);
5467 rt2800_bbp_write(rt2x00dev, 75, 0x46); 5466 rt2800_bbp_write(rt2x00dev, 75, 0x46);
5468 rt2800_bbp_write(rt2x00dev, 76, 0x28); 5467 rt2800_bbp_write(rt2x00dev, 76, 0x28);
5469 5468
5470 rt2800_bbp_write(rt2x00dev, 77, 0x59); 5469 rt2800_bbp_write(rt2x00dev, 77, 0x59);
5471 5470
5472 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
5473
5474 rt2800_bbp_write(rt2x00dev, 79, 0x13); 5471 rt2800_bbp_write(rt2x00dev, 79, 0x13);
5475 rt2800_bbp_write(rt2x00dev, 80, 0x05); 5472 rt2800_bbp_write(rt2x00dev, 80, 0x05);
5476 rt2800_bbp_write(rt2x00dev, 81, 0x33); 5473 rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -5513,6 +5510,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
5513 if (rt2x00_rt(rt2x00dev, RT5392)) { 5510 if (rt2x00_rt(rt2x00dev, RT5392)) {
5514 rt2800_bbp_write(rt2x00dev, 134, 0xd0); 5511 rt2800_bbp_write(rt2x00dev, 134, 0xd0);
5515 rt2800_bbp_write(rt2x00dev, 135, 0xf6); 5512 rt2800_bbp_write(rt2x00dev, 135, 0xf6);
5513 rt2800_bbp_write(rt2x00dev, 148, 0x84);
5516 } 5514 }
5517 5515
5518 rt2800_disable_unused_dac_adc(rt2x00dev); 5516 rt2800_disable_unused_dac_adc(rt2x00dev);
@@ -6453,7 +6451,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6453 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 6451 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
6454 rt2800_rfcsr_write(rt2x00dev, 10, 0x53); 6452 rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
6455 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); 6453 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
6456 rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); 6454 rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
6457 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); 6455 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
6458 rt2800_rfcsr_write(rt2x00dev, 14, 0x00); 6456 rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
6459 rt2800_rfcsr_write(rt2x00dev, 15, 0x00); 6457 rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
@@ -6466,7 +6464,8 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6466 rt2800_rfcsr_write(rt2x00dev, 22, 0x20); 6464 rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
6467 rt2800_rfcsr_write(rt2x00dev, 23, 0x00); 6465 rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
6468 rt2800_rfcsr_write(rt2x00dev, 24, 0x00); 6466 rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
6469 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6467 if (rt2x00_is_usb(rt2x00dev) &&
6468 rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
6470 rt2800_rfcsr_write(rt2x00dev, 25, 0x80); 6469 rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
6471 else 6470 else
6472 rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); 6471 rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
@@ -6486,10 +6485,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6486 rt2800_rfcsr_write(rt2x00dev, 38, 0x85); 6485 rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
6487 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); 6486 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
6488 6487
6489 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6488 rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
6490 rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
6491 else
6492 rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
6493 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); 6489 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
6494 rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); 6490 rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
6495 rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); 6491 rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
@@ -6510,16 +6506,26 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6510 rt2800_rfcsr_write(rt2x00dev, 53, 0x84); 6506 rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
6511 rt2800_rfcsr_write(rt2x00dev, 54, 0x78); 6507 rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
6512 rt2800_rfcsr_write(rt2x00dev, 55, 0x44); 6508 rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
6513 rt2800_rfcsr_write(rt2x00dev, 56, 0x22); 6509 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
6510 rt2800_rfcsr_write(rt2x00dev, 56, 0x42);
6511 else
6512 rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
6514 rt2800_rfcsr_write(rt2x00dev, 57, 0x80); 6513 rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
6515 rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); 6514 rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
6516 rt2800_rfcsr_write(rt2x00dev, 59, 0x8f); 6515 rt2800_rfcsr_write(rt2x00dev, 59, 0x8f);
6517 6516
6518 rt2800_rfcsr_write(rt2x00dev, 60, 0x45); 6517 rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
6519 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6518 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
6520 rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); 6519 if (rt2x00_is_usb(rt2x00dev))
6521 else 6520 rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
6522 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); 6521 else
6522 rt2800_rfcsr_write(rt2x00dev, 61, 0xd5);
6523 } else {
6524 if (rt2x00_is_usb(rt2x00dev))
6525 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
6526 else
6527 rt2800_rfcsr_write(rt2x00dev, 61, 0xb5);
6528 }
6523 rt2800_rfcsr_write(rt2x00dev, 62, 0x00); 6529 rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
6524 rt2800_rfcsr_write(rt2x00dev, 63, 0x00); 6530 rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
6525 6531
@@ -6602,7 +6608,6 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
6602 6608
6603 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); 6609 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F);
6604 rt2800_rfcsr_write(rt2x00dev, 3, 0x08); 6610 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
6605 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
6606 rt2800_rfcsr_write(rt2x00dev, 5, 0x10); 6611 rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
6607 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); 6612 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
6608 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 6613 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index a94ba447e63c..3019db637a4b 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22#ifndef RT2800LIB_H 20#ifndef RT2800LIB_H
diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.c b/drivers/net/wireless/rt2x00/rt2800mmio.c
index a8cc736b5063..de4790b41be7 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
@@ -19,9 +19,7 @@
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the 22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 * Free Software Foundation, Inc.,
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */ 23 */
26 24
27/* Module: rt2800mmio 25/* Module: rt2800mmio
diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.h b/drivers/net/wireless/rt2x00/rt2800mmio.h
index 6a10de3eee3e..b63312ce3f27 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
@@ -19,9 +19,7 @@
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the 22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 * Free Software Foundation, Inc.,
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */ 23 */
26 24
27/* Module: rt2800mmio 25/* Module: rt2800mmio
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b504455b4fec..a5b32ca2cf0f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -20,9 +20,7 @@
20 GNU General Public License for more details. 20 GNU General Public License for more details.
21 21
22 You should have received a copy of the GNU General Public License 22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the 23 along with this program; if not, see <http://www.gnu.org/licenses/>.
24 Free Software Foundation, Inc.,
25 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */ 24 */
27 25
28/* 26/*
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index a81c9ee281c0..9dfef4607d6b 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -20,9 +20,7 @@
20 GNU General Public License for more details. 20 GNU General Public License for more details.
21 21
22 You should have received a copy of the GNU General Public License 22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the 23 along with this program; if not, see <http://www.gnu.org/licenses/>.
24 Free Software Foundation, Inc.,
25 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */ 24 */
27 25
28/* 26/*
diff --git a/drivers/net/wireless/rt2x00/rt2800soc.c b/drivers/net/wireless/rt2x00/rt2800soc.c
index 1359227ca411..f6d1bf5be006 100644
--- a/drivers/net/wireless/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/rt2x00/rt2800soc.c
@@ -19,9 +19,7 @@
19 * GNU General Public License for more details. 19 * GNU General Public License for more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the 22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 * Free Software Foundation, Inc.,
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */ 23 */
26 24
27/* Module: rt2800soc 25/* Module: rt2800soc
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index a81ceb61d746..caddc1b427a9 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -18,9 +18,7 @@
18 GNU General Public License for more details. 18 GNU General Public License for more details.
19 19
20 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the 21 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */ 22 */
25 23
26/* 24/*
@@ -31,7 +29,6 @@
31 29
32#include <linux/delay.h> 30#include <linux/delay.h>
33#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
34#include <linux/init.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36#include <linux/module.h> 33#include <linux/module.h>
37#include <linux/usb.h> 34#include <linux/usb.h>
@@ -992,6 +989,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
992 { USB_DEVICE(0x07d1, 0x3c15) }, 989 { USB_DEVICE(0x07d1, 0x3c15) },
993 { USB_DEVICE(0x07d1, 0x3c16) }, 990 { USB_DEVICE(0x07d1, 0x3c16) },
994 { USB_DEVICE(0x07d1, 0x3c17) }, 991 { USB_DEVICE(0x07d1, 0x3c17) },
992 { USB_DEVICE(0x2001, 0x3317) },
995 { USB_DEVICE(0x2001, 0x3c1b) }, 993 { USB_DEVICE(0x2001, 0x3c1b) },
996 /* Draytek */ 994 /* Draytek */
997 { USB_DEVICE(0x07fa, 0x7712) }, 995 { USB_DEVICE(0x07fa, 0x7712) },
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 671ea3592610..ea7cac095997 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -17,9 +17,7 @@
17 GNU General Public License for more details. 17 GNU General Public License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the 20 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */ 21 */
24 22
25/* 23/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e4ba2ce0f212..e3b885d8f7db 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -15,9 +15,7 @@
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the 18 along with this program; if not, see <http://www.gnu.org/licenses/>.
19 Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */ 19 */
22 20
23/* 21/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 8cb43f8f3efc..1122dc44c9fd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index 3db0d99d9da7..a2fd05ba25ca 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 7f7baae5ae02..2e3d1645e68b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index e11d39bdfef7..e65712c235bd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9dd92a700442..2bde6729f5e6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22/* 20/*
@@ -567,10 +565,10 @@ static void rt2x00lib_rxdone_check_ba(struct rt2x00_dev *rt2x00dev,
567 565
568#undef TID_CHECK 566#undef TID_CHECK
569 567
570 if (!ether_addr_equal(ba->ra, entry->ta)) 568 if (!ether_addr_equal_64bits(ba->ra, entry->ta))
571 continue; 569 continue;
572 570
573 if (!ether_addr_equal(ba->ta, entry->ra)) 571 if (!ether_addr_equal_64bits(ba->ta, entry->ra))
574 continue; 572 continue;
575 573
576 /* Mark BAR since we received the according BA */ 574 /* Mark BAR since we received the according BA */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
index 063ebcce97f8..4c0e01b5d515 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dump.h
+++ b/drivers/net/wireless/rt2x00/rt2x00dump.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index 1b4254b4272d..fbae2799e3ee 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22/* 20/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index 997a6c89e66e..c681d04b506c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h
index 3b46f0c3332a..b2c5269570da 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.h
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 7f40ab8e1bd8..fb7c349ccc9c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22/* 20/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index c2b3b6629188..9b941c0c1264 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 2183e7978399..ddeb5a709aa3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
index 64b06c6abe58..6f236ea180aa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h
index cda3dbcf7ead..701c3127efb9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mmio.h
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 25da20e7e1f3..d93db4b0371b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -156,8 +154,6 @@ exit_release_regions:
156exit_disable_device: 154exit_disable_device:
157 pci_disable_device(pci_dev); 155 pci_disable_device(pci_dev);
158 156
159 pci_set_drvdata(pci_dev, NULL);
160
161 return retval; 157 return retval;
162} 158}
163EXPORT_SYMBOL_GPL(rt2x00pci_probe); 159EXPORT_SYMBOL_GPL(rt2x00pci_probe);
@@ -177,7 +173,6 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
177 /* 173 /*
178 * Free the PCI device data. 174 * Free the PCI device data.
179 */ 175 */
180 pci_set_drvdata(pci_dev, NULL);
181 pci_disable_device(pci_dev); 176 pci_disable_device(pci_dev);
182 pci_release_regions(pci_dev); 177 pci_release_regions(pci_dev);
183} 178}
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 60d90b20f8b9..bc0ca5f58f38 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a5d38e8ad9e4..5642ccceca7c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -15,9 +15,7 @@
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the 18 along with this program; if not, see <http://www.gnu.org/licenses/>.
19 Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */ 19 */
22 20
23/* 21/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index ebe117224979..c48125be0e34 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 6f867eec49cc..3cc541d13d67 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c
index 9271a5fce0a8..69a0cdadb07f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.c
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.c
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22/* 20/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h
index 474cbfc1efc7..9948d355e9a4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00soc.h
+++ b/drivers/net/wireless/rt2x00/rt2x00soc.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 4e121627925d..10572452cc21 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -14,9 +14,7 @@
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the 17 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 18 */
21 19
22/* 20/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 323ca7b2b095..e7bcf62347d5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a5b69cb49012..24402984ee57 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -27,7 +25,6 @@
27#include <linux/crc-itu-t.h> 25#include <linux/crc-itu-t.h>
28#include <linux/delay.h> 26#include <linux/delay.h>
29#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
30#include <linux/init.h>
31#include <linux/kernel.h> 28#include <linux/kernel.h>
32#include <linux/module.h> 29#include <linux/module.h>
33#include <linux/slab.h> 30#include <linux/slab.h>
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 9bc6b6044e34..1442075a8382 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1baf9c896dcd..a140170b1eb3 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
@@ -27,7 +25,6 @@
27#include <linux/crc-itu-t.h> 25#include <linux/crc-itu-t.h>
28#include <linux/delay.h> 26#include <linux/delay.h>
29#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
30#include <linux/init.h>
31#include <linux/kernel.h> 28#include <linux/kernel.h>
32#include <linux/module.h> 29#include <linux/module.h>
33#include <linux/slab.h> 30#include <linux/slab.h>
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 7577e0ba3877..4a4f235466d1 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -13,9 +13,7 @@
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */ 17 */
20 18
21/* 19/*
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index a91506b12a62..8ec17aad0e52 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -15,7 +15,6 @@
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16 */ 16 */
17 17
18#include <linux/init.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/pci.h> 19#include <linux/pci.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
index dc845693f321..b1bfee738937 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/grf5101.c
@@ -19,7 +19,6 @@
19 * published by the Free Software Foundation. 19 * published by the Free Software Foundation.
20 */ 20 */
21 21
22#include <linux/init.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <net/mac80211.h> 24#include <net/mac80211.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8180/max2820.c b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
index a63c443c3c6f..eebf23976524 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/max2820.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/max2820.c
@@ -18,7 +18,6 @@
18 * published by the Free Software Foundation. 18 * published by the Free Software Foundation.
19 */ 19 */
20 20
21#include <linux/init.h>
22#include <linux/pci.h> 21#include <linux/pci.h>
23#include <linux/delay.h> 22#include <linux/delay.h>
24#include <net/mac80211.h> 23#include <net/mac80211.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
index ee638d0749d6..d60a5f399022 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8225.c
@@ -15,7 +15,6 @@
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16 */ 16 */
17 17
18#include <linux/init.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
21#include <net/mac80211.h> 20#include <net/mac80211.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
index 7614d9ccc729..959b049827de 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/sa2400.c
@@ -19,7 +19,6 @@
19 * published by the Free Software Foundation. 19 * published by the Free Software Foundation.
20 */ 20 */
21 21
22#include <linux/init.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <net/mac80211.h> 24#include <net/mac80211.h>
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 9a6edb0c014e..fd78df813a85 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -20,7 +20,6 @@
20 * published by the Free Software Foundation. 20 * published by the Free Software Foundation.
21 */ 21 */
22 22
23#include <linux/init.h>
24#include <linux/usb.h> 23#include <linux/usb.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
@@ -416,7 +415,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
416 struct rtl8187_rx_info *info; 415 struct rtl8187_rx_info *info;
417 int ret = 0; 416 int ret = 0;
418 417
419 while (skb_queue_len(&priv->rx_queue) < 16) { 418 while (skb_queue_len(&priv->rx_queue) < 32) {
420 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); 419 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
421 if (!skb) { 420 if (!skb) {
422 ret = -ENOMEM; 421 ret = -ENOMEM;
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
index a26193a04447..5ecf18ed67b8 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
@@ -16,7 +16,6 @@
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/usb.h> 19#include <linux/usb.h>
21#include <net/mac80211.h> 20#include <net/mac80211.h>
22 21
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index ff784072fb42..93bb384eb001 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -353,7 +353,6 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
353 353
354 /* TODO: Correct this value for our hw */ 354 /* TODO: Correct this value for our hw */
355 /* TODO: define these hard code value */ 355 /* TODO: define these hard code value */
356 hw->channel_change_time = 100;
357 hw->max_listen_interval = 10; 356 hw->max_listen_interval = 10;
358 hw->max_rate_tries = 4; 357 hw->max_rate_tries = 4;
359 /* hw->max_rates = 1; */ 358 /* hw->max_rates = 1; */
@@ -1293,7 +1292,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
1293 return; 1292 return;
1294 1293
1295 /* and only beacons from the associated BSSID, please */ 1294 /* and only beacons from the associated BSSID, please */
1296 if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) 1295 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
1297 return; 1296 return;
1298 1297
1299 rtlpriv->link_info.bcn_rx_inperiod++; 1298 rtlpriv->link_info.bcn_rx_inperiod++;
@@ -1437,7 +1436,8 @@ void rtl_watchdog_wq_callback(void *data)
1437 /* if we can't recv beacon for 6s, we should 1436 /* if we can't recv beacon for 6s, we should
1438 * reconnect this AP 1437 * reconnect this AP
1439 */ 1438 */
1440 if (rtlpriv->link_info.roam_times >= 3) { 1439 if ((rtlpriv->link_info.roam_times >= 3) &&
1440 !is_zero_ether_addr(rtlpriv->mac80211.bssid)) {
1441 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1441 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1442 "AP off, try to reconnect now\n"); 1442 "AP off, try to reconnect now\n");
1443 rtlpriv->link_info.roam_times = 0; 1443 rtlpriv->link_info.roam_times = 0;
@@ -1780,7 +1780,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
1780 return; 1780 return;
1781 1781
1782 /* and only beacons from the associated BSSID, please */ 1782 /* and only beacons from the associated BSSID, please */
1783 if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) 1783 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
1784 return; 1784 return;
1785 1785
1786 if (rtl_find_221_ie(hw, data, len)) 1786 if (rtl_find_221_ie(hw, data, len))
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index 0e510f73041a..0276153c72cc 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -295,7 +295,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
295 /* Does STA already exist? */ 295 /* Does STA already exist? */
296 for (i = 4; i < TOTAL_CAM_ENTRY; i++) { 296 for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
297 addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; 297 addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
298 if (memcmp(addr, sta_addr, ETH_ALEN) == 0) 298 if (ether_addr_equal_unaligned(addr, sta_addr))
299 return i; 299 return i;
300 } 300 }
301 /* Get a free CAM entry. */ 301 /* Get a free CAM entry. */
@@ -335,7 +335,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
335 addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; 335 addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
336 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i; 336 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
337 if (((bitmap & BIT(0)) == BIT(0)) && 337 if (((bitmap & BIT(0)) == BIT(0)) &&
338 (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { 338 (ether_addr_equal_unaligned(addr, sta_addr))) {
339 /* Remove from HW Security CAM */ 339 /* Remove from HW Security CAM */
340 eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); 340 eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);
341 rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); 341 rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 210ce7cd94d8..2d337a0c3df0 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -46,10 +46,20 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)
46 "Firmware callback routine entered!\n"); 46 "Firmware callback routine entered!\n");
47 complete(&rtlpriv->firmware_loading_complete); 47 complete(&rtlpriv->firmware_loading_complete);
48 if (!firmware) { 48 if (!firmware) {
49 if (rtlpriv->cfg->alt_fw_name) {
50 err = request_firmware(&firmware,
51 rtlpriv->cfg->alt_fw_name,
52 rtlpriv->io.dev);
53 pr_info("Loading alternative firmware %s\n",
54 rtlpriv->cfg->alt_fw_name);
55 if (!err)
56 goto found_alt;
57 }
49 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); 58 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
50 rtlpriv->max_fw_size = 0; 59 rtlpriv->max_fw_size = 0;
51 return; 60 return;
52 } 61 }
62found_alt:
53 if (firmware->size > rtlpriv->max_fw_size) { 63 if (firmware->size > rtlpriv->max_fw_size) {
54 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
55 "Firmware is too big!\n"); 65 "Firmware is too big!\n");
@@ -184,6 +194,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
184 rtlpriv->cfg->maps 194 rtlpriv->cfg->maps
185 [RTL_IBSS_INT_MASKS]); 195 [RTL_IBSS_INT_MASKS]);
186 } 196 }
197 mac->link_state = MAC80211_LINKED;
187 break; 198 break;
188 case NL80211_IFTYPE_ADHOC: 199 case NL80211_IFTYPE_ADHOC:
189 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 200 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 5a53195d016b..d7aa165fe677 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -688,8 +688,6 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
688 rtlpriv->stats.rxbytesunicast += skb->len; 688 rtlpriv->stats.rxbytesunicast += skb->len;
689 } 689 }
690 690
691 rtl_is_special_data(hw, skb, false);
692
693 if (ieee80211_is_data(fc)) { 691 if (ieee80211_is_data(fc)) {
694 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 692 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
695 693
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 0d81f766fd0f..deedae3c5449 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -478,7 +478,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
478 return; 478 return;
479 479
480 /* and only beacons from the associated BSSID, please */ 480 /* and only beacons from the associated BSSID, please */
481 if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) 481 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
482 return; 482 return;
483 483
484 rtlpriv->psc.last_beacon = jiffies; 484 rtlpriv->psc.last_beacon = jiffies;
@@ -923,7 +923,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
923 return; 923 return;
924 924
925 /* and only beacons from the associated BSSID, please */ 925 /* and only beacons from the associated BSSID, please */
926 if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) 926 if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))
927 return; 927 return;
928 928
929 /* check if this really is a beacon */ 929 /* check if this really is a beacon */
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
index d7d0d4948b01..a4eb9b271438 100644
--- a/drivers/net/wireless/rtlwifi/regd.c
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -59,30 +59,26 @@ static struct country_code_to_enum_rd allCountries[] = {
59 */ 59 */
60#define RTL819x_2GHZ_CH12_13 \ 60#define RTL819x_2GHZ_CH12_13 \
61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
62 NL80211_RRF_PASSIVE_SCAN) 62 NL80211_RRF_NO_IR)
63 63
64#define RTL819x_2GHZ_CH14 \ 64#define RTL819x_2GHZ_CH14 \
65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \ 65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \
66 NL80211_RRF_PASSIVE_SCAN | \ 66 NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)
67 NL80211_RRF_NO_OFDM)
68 67
69/* 5G chan 36 - chan 64*/ 68/* 5G chan 36 - chan 64*/
70#define RTL819x_5GHZ_5150_5350 \ 69#define RTL819x_5GHZ_5150_5350 \
71 REG_RULE(5150-10, 5350+10, 40, 0, 30, \ 70 REG_RULE(5150-10, 5350+10, 40, 0, 30, \
72 NL80211_RRF_PASSIVE_SCAN | \ 71 NL80211_RRF_NO_IR)
73 NL80211_RRF_NO_IBSS)
74 72
75/* 5G chan 100 - chan 165*/ 73/* 5G chan 100 - chan 165*/
76#define RTL819x_5GHZ_5470_5850 \ 74#define RTL819x_5GHZ_5470_5850 \
77 REG_RULE(5470-10, 5850+10, 40, 0, 30, \ 75 REG_RULE(5470-10, 5850+10, 40, 0, 30, \
78 NL80211_RRF_PASSIVE_SCAN | \ 76 NL80211_RRF_NO_IR)
79 NL80211_RRF_NO_IBSS)
80 77
81/* 5G chan 149 - chan 165*/ 78/* 5G chan 149 - chan 165*/
82#define RTL819x_5GHZ_5725_5850 \ 79#define RTL819x_5GHZ_5725_5850 \
83 REG_RULE(5725-10, 5850+10, 40, 0, 30, \ 80 REG_RULE(5725-10, 5850+10, 40, 0, 30, \
84 NL80211_RRF_PASSIVE_SCAN | \ 81 NL80211_RRF_NO_IR)
85 NL80211_RRF_NO_IBSS)
86 82
87#define RTL819x_5GHZ_ALL \ 83#define RTL819x_5GHZ_ALL \
88 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) 84 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
@@ -172,7 +168,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
172 (ch->flags & IEEE80211_CHAN_RADAR)) 168 (ch->flags & IEEE80211_CHAN_RADAR))
173 continue; 169 continue;
174 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 170 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
175 reg_rule = freq_reg_info(wiphy, ch->center_freq); 171 reg_rule = freq_reg_info(wiphy,
172 MHZ_TO_KHZ(ch->center_freq));
176 if (IS_ERR(reg_rule)) 173 if (IS_ERR(reg_rule))
177 continue; 174 continue;
178 175
@@ -185,16 +182,11 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
185 *regulatory_hint(). 182 *regulatory_hint().
186 */ 183 */
187 184
188 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 185 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
189 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 186 ch->flags &= ~IEEE80211_CHAN_NO_IR;
190 if (!(reg_rule->
191 flags & NL80211_RRF_PASSIVE_SCAN))
192 ch->flags &=
193 ~IEEE80211_CHAN_PASSIVE_SCAN;
194 } else { 187 } else {
195 if (ch->beacon_found) 188 if (ch->beacon_found)
196 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 189 ch->flags &= ~IEEE80211_CHAN_NO_IR;
197 IEEE80211_CHAN_PASSIVE_SCAN);
198 } 190 }
199 } 191 }
200 } 192 }
@@ -219,11 +211,11 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
219 */ 211 */
220 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 212 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
221 ch = &sband->channels[11]; /* CH 12 */ 213 ch = &sband->channels[11]; /* CH 12 */
222 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 214 if (ch->flags & IEEE80211_CHAN_NO_IR)
223 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 215 ch->flags &= ~IEEE80211_CHAN_NO_IR;
224 ch = &sband->channels[12]; /* CH 13 */ 216 ch = &sband->channels[12]; /* CH 13 */
225 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 217 if (ch->flags & IEEE80211_CHAN_NO_IR)
226 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 218 ch->flags &= ~IEEE80211_CHAN_NO_IR;
227 return; 219 return;
228 } 220 }
229 221
@@ -235,19 +227,19 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
235 */ 227 */
236 228
237 ch = &sband->channels[11]; /* CH 12 */ 229 ch = &sband->channels[11]; /* CH 12 */
238 reg_rule = freq_reg_info(wiphy, ch->center_freq); 230 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
239 if (!IS_ERR(reg_rule)) { 231 if (!IS_ERR(reg_rule)) {
240 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 232 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
241 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 233 if (ch->flags & IEEE80211_CHAN_NO_IR)
242 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 234 ch->flags &= ~IEEE80211_CHAN_NO_IR;
243 } 235 }
244 236
245 ch = &sband->channels[12]; /* CH 13 */ 237 ch = &sband->channels[12]; /* CH 13 */
246 reg_rule = freq_reg_info(wiphy, ch->center_freq); 238 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
247 if (!IS_ERR(reg_rule)) { 239 if (!IS_ERR(reg_rule)) {
248 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 240 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
249 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 241 if (ch->flags & IEEE80211_CHAN_NO_IR)
250 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 242 ch->flags &= ~IEEE80211_CHAN_NO_IR;
251 } 243 }
252} 244}
253 245
@@ -284,8 +276,7 @@ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
284 */ 276 */
285 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 277 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
286 ch->flags |= IEEE80211_CHAN_RADAR | 278 ch->flags |= IEEE80211_CHAN_RADAR |
287 IEEE80211_CHAN_NO_IBSS | 279 IEEE80211_CHAN_NO_IR;
288 IEEE80211_CHAN_PASSIVE_SCAN;
289 } 280 }
290} 281}
291 282
@@ -354,9 +345,9 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
354 345
355 wiphy->reg_notifier = reg_notifier; 346 wiphy->reg_notifier = reg_notifier;
356 347
357 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 348 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
358 wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; 349 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
359 wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; 350 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
360 351
361 regd = _rtl_regdomain_select(reg); 352 regd = _rtl_regdomain_select(reg);
362 wiphy_apply_custom_regulatory(wiphy, regd); 353 wiphy_apply_custom_regulatory(wiphy, regd);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
index 21a5cf060677..a6184b6e1d57 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -1078,7 +1078,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
1078 rtldm->swing_flag_ofdm = true; 1078 rtldm->swing_flag_ofdm = true;
1079 } 1079 }
1080 1080
1081 if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) { 1081 if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck; 1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1083 rtldm->swing_flag_cck = true; 1083 rtldm->swing_flag_cck = true;
1084 } 1084 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index e9caa5d4cff0..eb78fd8607f7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -158,6 +158,42 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
158 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} 158 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
159}; 159};
160 160
161static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
162
163void dm_restorepowerindex(struct ieee80211_hw *hw)
164{
165 struct rtl_priv *rtlpriv = rtl_priv(hw);
166 u8 index;
167
168 for (index = 0; index < 6; index++)
169 rtl_write_byte(rtlpriv, power_index_reg[index],
170 rtlpriv->dm.powerindex_backup[index]);
171}
172EXPORT_SYMBOL_GPL(dm_restorepowerindex);
173
174void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
175{
176 struct rtl_priv *rtlpriv = rtl_priv(hw);
177 u8 index;
178
179 for (index = 0; index < 6; index++)
180 rtl_write_byte(rtlpriv, power_index_reg[index], value);
181}
182EXPORT_SYMBOL_GPL(dm_writepowerindex);
183
184void dm_savepowerindex(struct ieee80211_hw *hw)
185{
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 u8 index;
188 u8 tmp;
189
190 for (index = 0; index < 6; index++) {
191 tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
192 rtlpriv->dm.powerindex_backup[index] = tmp;
193 }
194}
195EXPORT_SYMBOL_GPL(dm_savepowerindex);
196
161static void rtl92c_dm_diginit(struct ieee80211_hw *hw) 197static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
162{ 198{
163 struct rtl_priv *rtlpriv = rtl_priv(hw); 199 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -180,7 +216,12 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
180 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 216 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
181 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 217 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
182 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; 218 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
183 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 219 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi;
220
221 dm_digtable->forbidden_igi = DM_DIG_MIN;
222 dm_digtable->large_fa_hit = 0;
223 dm_digtable->recover_cnt = 0;
224 dm_digtable->dig_dynamic_min = 0x25;
184} 225}
185 226
186static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 227static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
@@ -206,7 +247,9 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
206 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; 247 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
207 } 248 }
208 249
209 return (u8) rssi_val_min; 250 if (rssi_val_min > 100)
251 rssi_val_min = 100;
252 return (u8)rssi_val_min;
210} 253}
211 254
212static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 255static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
@@ -224,9 +267,17 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
224 267
225 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); 268 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
226 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 269 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
270
271 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
272 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
273 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
274
227 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 275 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
228 falsealm_cnt->cnt_rate_illegal + 276 falsealm_cnt->cnt_rate_illegal +
229 falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; 277 falsealm_cnt->cnt_crc8_fail +
278 falsealm_cnt->cnt_mcs_fail +
279 falsealm_cnt->cnt_fast_fsync_fail +
280 falsealm_cnt->cnt_sb_search_fail;
230 281
231 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); 282 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
232 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); 283 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
@@ -271,12 +322,14 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
271 value_igi++; 322 value_igi++;
272 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) 323 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
273 value_igi += 2; 324 value_igi += 2;
325
274 if (value_igi > DM_DIG_FA_UPPER) 326 if (value_igi > DM_DIG_FA_UPPER)
275 value_igi = DM_DIG_FA_UPPER; 327 value_igi = DM_DIG_FA_UPPER;
276 else if (value_igi < DM_DIG_FA_LOWER) 328 else if (value_igi < DM_DIG_FA_LOWER)
277 value_igi = DM_DIG_FA_LOWER; 329 value_igi = DM_DIG_FA_LOWER;
330
278 if (rtlpriv->falsealm_cnt.cnt_all > 10000) 331 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
279 value_igi = 0x32; 332 value_igi = DM_DIG_FA_UPPER;
280 333
281 dm_digtable->cur_igvalue = value_igi; 334 dm_digtable->cur_igvalue = value_igi;
282 rtl92c_dm_write_dig(hw); 335 rtl92c_dm_write_dig(hw);
@@ -286,32 +339,80 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
286{ 339{
287 struct rtl_priv *rtlpriv = rtl_priv(hw); 340 struct rtl_priv *rtlpriv = rtl_priv(hw);
288 struct dig_t *digtable = &rtlpriv->dm_digtable; 341 struct dig_t *digtable = &rtlpriv->dm_digtable;
342 u32 isbt;
343
344 /* modify DIG lower bound, deal with abnorally large false alarm */
345 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
346 digtable->large_fa_hit++;
347 if (digtable->forbidden_igi < digtable->cur_igvalue) {
348 digtable->forbidden_igi = digtable->cur_igvalue;
349 digtable->large_fa_hit = 1;
350 }
289 351
290 if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { 352 if (digtable->large_fa_hit >= 3) {
291 if ((digtable->back_val - 2) < digtable->back_range_min) 353 if ((digtable->forbidden_igi + 1) >
292 digtable->back_val = digtable->back_range_min; 354 digtable->rx_gain_max)
293 else 355 digtable->rx_gain_min = digtable->rx_gain_max;
294 digtable->back_val -= 2; 356 else
295 } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { 357 digtable->rx_gain_min = (digtable->forbidden_igi + 1);
296 if ((digtable->back_val + 2) > digtable->back_range_max) 358 digtable->recover_cnt = 3600; /* 3600=2hr */
297 digtable->back_val = digtable->back_range_max; 359 }
298 else 360 } else {
299 digtable->back_val += 2; 361 /* Recovery mechanism for IGI lower bound */
362 if (digtable->recover_cnt != 0) {
363 digtable->recover_cnt--;
364 } else {
365 if (digtable->large_fa_hit == 0) {
366 if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
367 digtable->forbidden_igi = DM_DIG_MIN;
368 digtable->rx_gain_min = DM_DIG_MIN;
369 } else {
370 digtable->forbidden_igi--;
371 digtable->rx_gain_min = digtable->forbidden_igi + 1;
372 }
373 } else if (digtable->large_fa_hit == 3) {
374 digtable->large_fa_hit = 0;
375 }
376 }
377 }
378 if (rtlpriv->falsealm_cnt.cnt_all < 250) {
379 isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
380
381 if (!isbt) {
382 if (rtlpriv->falsealm_cnt.cnt_all >
383 digtable->fa_lowthresh) {
384 if ((digtable->back_val - 2) <
385 digtable->back_range_min)
386 digtable->back_val = digtable->back_range_min;
387 else
388 digtable->back_val -= 2;
389 } else if (rtlpriv->falsealm_cnt.cnt_all <
390 digtable->fa_lowthresh) {
391 if ((digtable->back_val + 2) >
392 digtable->back_range_max)
393 digtable->back_val = digtable->back_range_max;
394 else
395 digtable->back_val += 2;
396 }
397 } else {
398 digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
399 }
400 } else {
401 /* Adjust initial gain by false alarm */
402 if (rtlpriv->falsealm_cnt.cnt_all > 1000)
403 digtable->cur_igvalue = digtable->pre_igvalue + 2;
404 else if (rtlpriv->falsealm_cnt.cnt_all > 750)
405 digtable->cur_igvalue = digtable->pre_igvalue + 1;
406 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
407 digtable->cur_igvalue = digtable->pre_igvalue - 1;
300 } 408 }
301 409
302 if ((digtable->rssi_val_min + 10 - digtable->back_val) > 410 /* Check initial gain by upper/lower bound */
303 digtable->rx_gain_max) 411 if (digtable->cur_igvalue > digtable->rx_gain_max)
304 digtable->cur_igvalue = digtable->rx_gain_max; 412 digtable->cur_igvalue = digtable->rx_gain_max;
305 else if ((digtable->rssi_val_min + 10 -
306 digtable->back_val) < digtable->rx_gain_min)
307 digtable->cur_igvalue = digtable->rx_gain_min;
308 else
309 digtable->cur_igvalue = digtable->rssi_val_min + 10 -
310 digtable->back_val;
311 413
312 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 414 if (digtable->cur_igvalue < digtable->rx_gain_min)
313 "rssi_val_min = %x back_val %x\n", 415 digtable->cur_igvalue = digtable->rx_gain_min;
314 digtable->rssi_val_min, digtable->back_val);
315 416
316 rtl92c_dm_write_dig(hw); 417 rtl92c_dm_write_dig(hw);
317} 418}
@@ -329,7 +430,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
329 multi_sta = true; 430 multi_sta = true;
330 431
331 if (!multi_sta || 432 if (!multi_sta ||
332 dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 433 dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
333 initialized = false; 434 initialized = false;
334 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 435 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
335 return; 436 return;
@@ -375,7 +476,6 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
375 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 476 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
376 "presta_cstate = %x, cursta_cstate = %x\n", 477 "presta_cstate = %x, cursta_cstate = %x\n",
377 dm_digtable->presta_cstate, dm_digtable->cursta_cstate); 478 dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
378
379 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || 479 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
380 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || 480 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
381 dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 481 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
@@ -383,6 +483,8 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
383 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 483 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
384 dm_digtable->rssi_val_min = 484 dm_digtable->rssi_val_min =
385 rtl92c_dm_initial_gain_min_pwdb(hw); 485 rtl92c_dm_initial_gain_min_pwdb(hw);
486 if (dm_digtable->rssi_val_min > 100)
487 dm_digtable->rssi_val_min = 100;
386 rtl92c_dm_ctrl_initgain_by_rssi(hw); 488 rtl92c_dm_ctrl_initgain_by_rssi(hw);
387 } 489 }
388 } else { 490 } else {
@@ -398,11 +500,12 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
398static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 500static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
399{ 501{
400 struct rtl_priv *rtlpriv = rtl_priv(hw); 502 struct rtl_priv *rtlpriv = rtl_priv(hw);
401 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
402 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 503 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
403 504
404 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 505 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
405 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); 506 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
507 if (dm_digtable->rssi_val_min > 100)
508 dm_digtable->rssi_val_min = 100;
406 509
407 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { 510 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
408 if (dm_digtable->rssi_val_min <= 25) 511 if (dm_digtable->rssi_val_min <= 25)
@@ -424,48 +527,14 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
424 } 527 }
425 528
426 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 529 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
427 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { 530 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) ||
428 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) 531 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
429 dm_digtable->cur_cck_fa_state = 532 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
430 CCK_FA_STAGE_High; 533 else
431 else
432 dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low;
433
434 if (dm_digtable->pre_cck_fa_state !=
435 dm_digtable->cur_cck_fa_state) {
436 if (dm_digtable->cur_cck_fa_state ==
437 CCK_FA_STAGE_Low)
438 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
439 0x83);
440 else
441 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
442 0xcd);
443
444 dm_digtable->pre_cck_fa_state =
445 dm_digtable->cur_cck_fa_state;
446 }
447
448 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
449
450 if (IS_92C_SERIAL(rtlhal->version))
451 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
452 MASKBYTE2, 0xd7);
453 } else {
454 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 534 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
455 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
456 535
457 if (IS_92C_SERIAL(rtlhal->version))
458 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
459 MASKBYTE2, 0xd3);
460 }
461 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; 536 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
462 } 537 }
463
464 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
465 dm_digtable->cur_cck_pd_state);
466
467 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
468 IS_92C_SERIAL(rtlhal->version));
469} 538}
470 539
471static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) 540static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
@@ -482,6 +551,8 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
482 else 551 else
483 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; 552 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
484 553
554 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
555
485 rtl92c_dm_initial_gain_sta(hw); 556 rtl92c_dm_initial_gain_sta(hw);
486 rtl92c_dm_initial_gain_multi_sta(hw); 557 rtl92c_dm_initial_gain_multi_sta(hw);
487 rtl92c_dm_cck_packet_detection_thresh(hw); 558 rtl92c_dm_cck_packet_detection_thresh(hw);
@@ -493,23 +564,26 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
493static void rtl92c_dm_dig(struct ieee80211_hw *hw) 564static void rtl92c_dm_dig(struct ieee80211_hw *hw)
494{ 565{
495 struct rtl_priv *rtlpriv = rtl_priv(hw); 566 struct rtl_priv *rtlpriv = rtl_priv(hw);
496 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
497 567
498 if (rtlpriv->dm.dm_initialgain_enable == false) 568 if (rtlpriv->dm.dm_initialgain_enable == false)
499 return; 569 return;
500 if (dm_digtable->dig_enable_flag == false) 570 if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG))
501 return; 571 return;
502 572
503 rtl92c_dm_ctrl_initgain_by_twoport(hw); 573 rtl92c_dm_ctrl_initgain_by_twoport(hw);
504
505} 574}
506 575
507static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) 576static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
508{ 577{
509 struct rtl_priv *rtlpriv = rtl_priv(hw); 578 struct rtl_priv *rtlpriv = rtl_priv(hw);
510 579
511 rtlpriv->dm.dynamic_txpower_enable = false; 580 if (rtlpriv->rtlhal.interface == INTF_USB &&
512 581 rtlpriv->rtlhal.board_type & 0x1) {
582 dm_savepowerindex(hw);
583 rtlpriv->dm.dynamic_txpower_enable = true;
584 } else {
585 rtlpriv->dm.dynamic_txpower_enable = false;
586 }
513 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; 587 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
514 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 588 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
515} 589}
@@ -524,9 +598,14 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
524 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, 598 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
525 dm_digtable->back_val); 599 dm_digtable->back_val);
526 600
527 dm_digtable->cur_igvalue += 2; 601 if (rtlpriv->rtlhal.interface == INTF_USB &&
528 if (dm_digtable->cur_igvalue > 0x3f) 602 !dm_digtable->dig_enable_flag) {
529 dm_digtable->cur_igvalue = 0x3f; 603 dm_digtable->pre_igvalue = 0x17;
604 return;
605 }
606 dm_digtable->cur_igvalue -= 1;
607 if (dm_digtable->cur_igvalue < DM_DIG_MIN)
608 dm_digtable->cur_igvalue = DM_DIG_MIN;
530 609
531 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { 610 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
532 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, 611 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
@@ -536,11 +615,47 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
536 615
537 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; 616 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
538 } 617 }
618 RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING,
619 "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
620 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
621 dm_digtable->rssi_val_min, dm_digtable->back_val,
622 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
623 dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
539} 624}
540EXPORT_SYMBOL(rtl92c_dm_write_dig); 625EXPORT_SYMBOL(rtl92c_dm_write_dig);
541 626
542static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) 627static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
543{ 628{
629 struct rtl_priv *rtlpriv = rtl_priv(hw);
630 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
631 long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
632
633 if (mac->link_state != MAC80211_LINKED)
634 return;
635
636 if (mac->opmode == NL80211_IFTYPE_ADHOC ||
637 mac->opmode == NL80211_IFTYPE_AP) {
638 /* TODO: Handle ADHOC and AP Mode */
639 }
640
641 if (tmpentry_max_pwdb != 0)
642 rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
643 else
644 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
645
646 if (tmpentry_min_pwdb != 0xff)
647 rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
648 else
649 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
650
651/* TODO:
652 * if (mac->opmode == NL80211_IFTYPE_STATION) {
653 * if (rtlpriv->rtlhal.fw_ready) {
654 * u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16);
655 * rtl8192c_set_rssi_cmd(hw, param);
656 * }
657 * }
658 */
544} 659}
545 660
546void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) 661void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
@@ -750,6 +865,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
750 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; 865 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
751 rtlpriv->dm.cck_index = cck_index_old; 866 rtlpriv->dm.cck_index = cck_index_old;
752 } 867 }
868 /* Handle USB High PA boards */
753 869
754 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? 870 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
755 (thermalvalue - rtlpriv->dm.thermalvalue) : 871 (thermalvalue - rtlpriv->dm.thermalvalue) :
@@ -1140,22 +1256,22 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1140{ 1256{
1141 struct rtl_priv *rtlpriv = rtl_priv(hw); 1257 struct rtl_priv *rtlpriv = rtl_priv(hw);
1142 struct ps_t *dm_pstable = &rtlpriv->dm_pstable; 1258 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1143 static u8 initialize;
1144 static u32 reg_874, reg_c70, reg_85c, reg_a74;
1145 1259
1146 if (initialize == 0) { 1260 if (!rtlpriv->reg_init) {
1147 reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1261 rtlpriv->reg_874 = (rtl_get_bbreg(hw,
1148 MASKDWORD) & 0x1CC000) >> 14; 1262 RFPGA0_XCD_RFINTERFACESW,
1263 MASKDWORD) & 0x1CC000) >> 14;
1149 1264
1150 reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, 1265 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1151 MASKDWORD) & BIT(3)) >> 3; 1266 MASKDWORD) & BIT(3)) >> 3;
1152 1267
1153 reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 1268 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1154 MASKDWORD) & 0xFF000000) >> 24; 1269 MASKDWORD) & 0xFF000000) >> 24;
1155 1270
1156 reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; 1271 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
1272 0xF000) >> 12;
1157 1273
1158 initialize = 1; 1274 rtlpriv->reg_init = true;
1159 } 1275 }
1160 1276
1161 if (!bforce_in_normal) { 1277 if (!bforce_in_normal) {
@@ -1192,12 +1308,12 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1192 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); 1308 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1193 } else { 1309 } else {
1194 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1310 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1195 0x1CC000, reg_874); 1311 0x1CC000, rtlpriv->reg_874);
1196 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 1312 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1197 reg_c70); 1313 rtlpriv->reg_c70);
1198 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, 1314 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1199 reg_85c); 1315 rtlpriv->reg_85c);
1200 rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); 1316 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
1201 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); 1317 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1202 } 1318 }
1203 1319
@@ -1213,6 +1329,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1213 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1329 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1214 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1330 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1215 1331
1332 /* Determine the minimum RSSI */
1216 if (((mac->link_state == MAC80211_NOLINK)) && 1333 if (((mac->link_state == MAC80211_NOLINK)) &&
1217 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 1334 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
1218 dm_pstable->rssi_val_min = 0; 1335 dm_pstable->rssi_val_min = 0;
@@ -1241,6 +1358,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1241 dm_pstable->rssi_val_min); 1358 dm_pstable->rssi_val_min);
1242 } 1359 }
1243 1360
1361 /* Power Saving for 92C */
1244 if (IS_92C_SERIAL(rtlhal->version)) 1362 if (IS_92C_SERIAL(rtlhal->version))
1245 ;/* rtl92c_dm_1r_cca(hw); */ 1363 ;/* rtl92c_dm_1r_cca(hw); */
1246 else 1364 else
@@ -1252,12 +1370,23 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
1252 struct rtl_priv *rtlpriv = rtl_priv(hw); 1370 struct rtl_priv *rtlpriv = rtl_priv(hw);
1253 1371
1254 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1372 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1373 rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
1374 rtlpriv->dm.undec_sm_pwdb = -1;
1375 rtlpriv->dm.undec_sm_cck = -1;
1376 rtlpriv->dm.dm_initialgain_enable = true;
1255 rtl92c_dm_diginit(hw); 1377 rtl92c_dm_diginit(hw);
1378
1379 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
1256 rtl92c_dm_init_dynamic_txpower(hw); 1380 rtl92c_dm_init_dynamic_txpower(hw);
1381
1257 rtl92c_dm_init_edca_turbo(hw); 1382 rtl92c_dm_init_edca_turbo(hw);
1258 rtl92c_dm_init_rate_adaptive_mask(hw); 1383 rtl92c_dm_init_rate_adaptive_mask(hw);
1384 rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
1259 rtl92c_dm_initialize_txpower_tracking(hw); 1385 rtl92c_dm_initialize_txpower_tracking(hw);
1260 rtl92c_dm_init_dynamic_bb_powersaving(hw); 1386 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1387
1388 rtlpriv->dm.ofdm_pkt_cnt = 0;
1389 rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
1261} 1390}
1262EXPORT_SYMBOL(rtl92c_dm_init); 1391EXPORT_SYMBOL(rtl92c_dm_init);
1263 1392
@@ -1308,7 +1437,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1308 } 1437 }
1309 1438
1310 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { 1439 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
1311 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; 1440 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
1312 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 1441 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1313 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); 1442 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
1314 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && 1443 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
@@ -1328,8 +1457,16 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1328 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 1457 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
1329 rtlphy->current_channel); 1458 rtlphy->current_channel);
1330 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 1459 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1460 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1461 TXHIGHPWRLEVEL_NORMAL)
1462 dm_restorepowerindex(hw);
1463 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1464 TXHIGHPWRLEVEL_LEVEL1)
1465 dm_writepowerindex(hw, 0x14);
1466 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1467 TXHIGHPWRLEVEL_LEVEL2)
1468 dm_writepowerindex(hw, 0x10);
1331 } 1469 }
1332
1333 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 1470 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
1334} 1471}
1335 1472
@@ -1400,12 +1537,6 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
1400 else 1537 else
1401 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); 1538 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
1402 1539
1403 /* Set Tx Power according to BT status. */
1404 if (undec_sm_pwdb >= 30)
1405 curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW;
1406 else if (undec_sm_pwdb < 25)
1407 curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
1408
1409 /* Check BT state related to BT_Idle in B/G mode. */ 1540 /* Check BT state related to BT_Idle in B/G mode. */
1410 if (undec_sm_pwdb < 15) 1541 if (undec_sm_pwdb < 15)
1411 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; 1542 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
index 518e208c0180..4f232a063636 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
@@ -91,6 +91,17 @@
91#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 91#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
92#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 92#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
93 93
94#define DYNAMIC_FUNC_DISABLE 0x0
95#define DYNAMIC_FUNC_DIG BIT(0)
96#define DYNAMIC_FUNC_HP BIT(1)
97#define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/
98#define DYNAMIC_FUNC_BT BIT(3)
99#define DYNAMIC_FUNC_ANT_DIV BIT(4)
100
101#define RSSI_CCK 0
102#define RSSI_OFDM 1
103#define RSSI_DEFAULT 2
104
94struct swat_t { 105struct swat_t {
95 u8 failure_cnt; 106 u8 failure_cnt;
96 u8 try_flag; 107 u8 try_flag;
@@ -167,5 +178,8 @@ void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
167void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); 178void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
168void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); 179void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
169void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); 180void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
181void dm_savepowerindex(struct ieee80211_hw *hw);
182void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
183void dm_restorepowerindex(struct ieee80211_hw *hw);
170 184
171#endif 185#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index 0c0e78263a66..9e32ac8a4425 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -1147,6 +1147,12 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1147 0x522, 0x550, 0x551, 0x040 1147 0x522, 0x550, 0x551, 0x040
1148 }; 1148 };
1149 1149
1150 u32 iqk_bb_reg_92C[9] = {
1151 0xc04, 0xc08, 0x874, 0xb68,
1152 0xb6c, 0x870, 0x860, 0x864,
1153 0x800
1154 };
1155
1150 const u32 retrycount = 2; 1156 const u32 retrycount = 2;
1151 1157
1152 if (t == 0) { 1158 if (t == 0) {
@@ -1157,6 +1163,8 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1157 rtlphy->adda_backup, 16); 1163 rtlphy->adda_backup, 16);
1158 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, 1164 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1159 rtlphy->iqk_mac_backup); 1165 rtlphy->iqk_mac_backup);
1166 _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C,
1167 rtlphy->iqk_bb_backup, 9);
1160 } 1168 }
1161 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); 1169 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1162 if (t == 0) { 1170 if (t == 0) {
@@ -1167,14 +1175,18 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1167 1175
1168 if (!rtlphy->rfpi_enable) 1176 if (!rtlphy->rfpi_enable)
1169 _rtl92c_phy_pi_mode_switch(hw, true); 1177 _rtl92c_phy_pi_mode_switch(hw, true);
1170 if (t == 0) { 1178
1171 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 1179 rtl_set_bbreg(hw, 0x800, BIT(24), 0x0);
1172 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 1180
1173 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1174 }
1175 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 1181 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1176 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 1182 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1177 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 1183 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1184
1185 rtl_set_bbreg(hw, 0x870, BIT(10), 0x1);
1186 rtl_set_bbreg(hw, 0x870, BIT(26), 0x1);
1187 rtl_set_bbreg(hw, 0x860, BIT(10), 0x0);
1188 rtl_set_bbreg(hw, 0x864, BIT(10), 0x0);
1189
1178 if (is2t) { 1190 if (is2t) {
1179 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1191 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1180 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 1192 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
@@ -1239,13 +1251,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1239 0x3FF0000) >> 16; 1251 0x3FF0000) >> 16;
1240 } 1252 }
1241 } 1253 }
1242 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); 1254
1243 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1244 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1245 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 1255 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1246 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 1256
1247 if (is2t)
1248 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1249 if (t != 0) { 1257 if (t != 0) {
1250 if (!rtlphy->rfpi_enable) 1258 if (!rtlphy->rfpi_enable)
1251 _rtl92c_phy_pi_mode_switch(hw, false); 1259 _rtl92c_phy_pi_mode_switch(hw, false);
@@ -1253,6 +1261,15 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1253 rtlphy->adda_backup, 16); 1261 rtlphy->adda_backup, 16);
1254 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, 1262 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1255 rtlphy->iqk_mac_backup); 1263 rtlphy->iqk_mac_backup);
1264 _rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C,
1265 rtlphy->iqk_bb_backup, 9);
1266
1267 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1268 if (is2t)
1269 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1270
1271 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1272 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1256 } 1273 }
1257} 1274}
1258 1275
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
index 16a0b9e59acf..c16209a336ea 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
@@ -101,6 +101,15 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
101 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 101 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
102 rtlphy->current_channel); 102 rtlphy->current_channel);
103 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 103 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
104 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
105 TXHIGHPWRLEVEL_NORMAL)
106 dm_restorepowerindex(hw);
107 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
108 TXHIGHPWRLEVEL_LEVEL1)
109 dm_writepowerindex(hw, 0x14);
110 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
111 TXHIGHPWRLEVEL_LEVEL2)
112 dm_writepowerindex(hw, 0x10);
104 } 113 }
105 114
106 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 115 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
index d947e7d350bb..fafa6bac2a3f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
@@ -30,3 +30,6 @@
30#include "../rtl8192ce/dm.h" 30#include "../rtl8192ce/dm.h"
31 31
32void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); 32void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);
33void dm_savepowerindex(struct ieee80211_hw *hw);
34void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
35void dm_restorepowerindex(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 189ba124a8c6..468bf73cc883 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1022,7 +1022,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1022 if (ppsc->rfpwr_state == ERFON) { 1022 if (ppsc->rfpwr_state == ERFON) {
1023 rtl92c_phy_set_rfpath_switch(hw, 1); 1023 rtl92c_phy_set_rfpath_switch(hw, 1);
1024 if (iqk_initialized) { 1024 if (iqk_initialized) {
1025 rtl92c_phy_iq_calibrate(hw, false); 1025 rtl92c_phy_iq_calibrate(hw, true);
1026 } else { 1026 } else {
1027 rtl92c_phy_iq_calibrate(hw, false); 1027 rtl92c_phy_iq_calibrate(hw, false);
1028 iqk_initialized = true; 1028 iqk_initialized = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index 34e56308301e..0c09240eadcc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -120,6 +120,7 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
120 struct rtl_priv *rtlpriv = rtl_priv(hw); 120 struct rtl_priv *rtlpriv = rtl_priv(hw);
121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
122 u16 regval; 122 u16 regval;
123 u32 regval32;
123 u8 b_reg_hwparafile = 1; 124 u8 b_reg_hwparafile = 1;
124 125
125 _rtl92c_phy_init_bb_rf_register_definition(hw); 126 _rtl92c_phy_init_bb_rf_register_definition(hw);
@@ -135,8 +136,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
135 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) { 136 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
136 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | 137 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
137 FEN_BB_GLB_RSTn | FEN_BBRSTB); 138 FEN_BB_GLB_RSTn | FEN_BBRSTB);
138 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
139 } 139 }
140 regval32 = rtl_read_dword(rtlpriv, 0x87c);
141 rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
142 if (IS_HARDWARE_TYPE_8192CU(rtlhal))
143 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
140 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 144 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
141 if (b_reg_hwparafile == 1) 145 if (b_reg_hwparafile == 1)
142 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); 146 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index 2119313a737b..b878d56d2f4d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
85 if (mac->act_scanning) { 85 if (mac->act_scanning) {
86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f; 86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f; 87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
88 if (turbo_scanoff) { 88 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
89 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 89 tx_agc[idx1] = ppowerlevel[idx1] |
90 tx_agc[idx1] = ppowerlevel[idx1] | 90 (ppowerlevel[idx1] << 8) |
91 (ppowerlevel[idx1] << 8) | 91 (ppowerlevel[idx1] << 16) |
92 (ppowerlevel[idx1] << 16) | 92 (ppowerlevel[idx1] << 24);
93 (ppowerlevel[idx1] << 24); 93 if (rtlhal->interface == INTF_USB) {
94 if (rtlhal->interface == INTF_USB) { 94 if (tx_agc[idx1] > 0x20 &&
95 if (tx_agc[idx1] > 0x20 && 95 rtlefuse->external_pa)
96 rtlefuse->external_pa) 96 tx_agc[idx1] = 0x20;
97 tx_agc[idx1] = 0x20;
98 }
99 } 97 }
100 } 98 }
101 } else { 99 } else {
@@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
107 TXHIGHPWRLEVEL_LEVEL2) { 105 TXHIGHPWRLEVEL_LEVEL2) {
108 tx_agc[RF90_PATH_A] = 0x00000000; 106 tx_agc[RF90_PATH_A] = 0x00000000;
109 tx_agc[RF90_PATH_B] = 0x00000000; 107 tx_agc[RF90_PATH_B] = 0x00000000;
110 } else{ 108 } else {
111 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 109 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
112 tx_agc[idx1] = ppowerlevel[idx1] | 110 tx_agc[idx1] = ppowerlevel[idx1] |
113 (ppowerlevel[idx1] << 8) | 111 (ppowerlevel[idx1] << 8) |
@@ -373,7 +371,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
373 regoffset == RTXAGC_B_MCS07_MCS04) 371 regoffset == RTXAGC_B_MCS07_MCS04)
374 regoffset = 0xc98; 372 regoffset = 0xc98;
375 for (i = 0; i < 3; i++) { 373 for (i = 0; i < 3; i++) {
376 writeVal = (writeVal > 6) ? (writeVal - 6) : 0; 374 if (i != 2)
375 writeVal = (writeVal > 8) ?
376 (writeVal - 8) : 0;
377 else
378 writeVal = (writeVal > 6) ?
379 (writeVal - 6) : 0;
377 rtl_write_byte(rtlpriv, (u32)(regoffset + i), 380 rtl_write_byte(rtlpriv, (u32)(regoffset + i),
378 (u8)writeVal); 381 (u8)writeVal);
379 } 382 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 9936de716ad5..c61311084d7e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -50,6 +50,9 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); 51MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
52MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); 52MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
53MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin");
54MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
55MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
53 56
54static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) 57static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
55{ 58{
@@ -69,14 +72,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
69 "Can't alloc buffer for fw\n"); 72 "Can't alloc buffer for fw\n");
70 return 1; 73 return 1;
71 } 74 }
72 75 if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) &&
76 !IS_92C_SERIAL(rtlpriv->rtlhal.version)) {
77 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin";
78 } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) {
79 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin";
80 } else {
81 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin";
82 }
83 /* provide name of alternative file */
84 rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin";
73 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); 85 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
74 rtlpriv->max_fw_size = 0x4000; 86 rtlpriv->max_fw_size = 0x4000;
75 err = request_firmware_nowait(THIS_MODULE, 1, 87 err = request_firmware_nowait(THIS_MODULE, 1,
76 rtlpriv->cfg->fw_name, rtlpriv->io.dev, 88 rtlpriv->cfg->fw_name, rtlpriv->io.dev,
77 GFP_KERNEL, hw, rtl_fw_cb); 89 GFP_KERNEL, hw, rtl_fw_cb);
78
79
80 return err; 90 return err;
81} 91}
82 92
@@ -307,6 +317,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
307 {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ 317 {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
308 {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ 318 {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
309 {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ 319 {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
320 {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/
310 {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ 321 {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
311 {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ 322 {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/
312 /* HP - Lite-On ,8188CUS Slim Combo */ 323 /* HP - Lite-On ,8188CUS Slim Combo */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
index 966be519edb8..7903c154de00 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
@@ -36,7 +36,7 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
36 0x804, 0x00000003, 36 0x804, 0x00000003,
37 0x808, 0x0000fc00, 37 0x808, 0x0000fc00,
38 0x80c, 0x0000000a, 38 0x80c, 0x0000000a,
39 0x810, 0x10005388, 39 0x810, 0x10000330,
40 0x814, 0x020c3d10, 40 0x814, 0x020c3d10,
41 0x818, 0x02200385, 41 0x818, 0x02200385,
42 0x81c, 0x00000000, 42 0x81c, 0x00000000,
@@ -110,22 +110,22 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
110 0xc44, 0x000100b7, 110 0xc44, 0x000100b7,
111 0xc48, 0xec020107, 111 0xc48, 0xec020107,
112 0xc4c, 0x007f037f, 112 0xc4c, 0x007f037f,
113 0xc50, 0x6954341e, 113 0xc50, 0x69543420,
114 0xc54, 0x43bc0094, 114 0xc54, 0x43bc0094,
115 0xc58, 0x6954341e, 115 0xc58, 0x69543420,
116 0xc5c, 0x433c0094, 116 0xc5c, 0x433c0094,
117 0xc60, 0x00000000, 117 0xc60, 0x00000000,
118 0xc64, 0x5116848b, 118 0xc64, 0x5116848b,
119 0xc68, 0x47c00bff, 119 0xc68, 0x47c00bff,
120 0xc6c, 0x00000036, 120 0xc6c, 0x00000036,
121 0xc70, 0x2c7f000d, 121 0xc70, 0x2c7f000d,
122 0xc74, 0x0186115b, 122 0xc74, 0x2186115b,
123 0xc78, 0x0000001f, 123 0xc78, 0x0000001f,
124 0xc7c, 0x00b99612, 124 0xc7c, 0x00b99612,
125 0xc80, 0x40000100, 125 0xc80, 0x40000100,
126 0xc84, 0x20f60000, 126 0xc84, 0x20f60000,
127 0xc88, 0x40000100, 127 0xc88, 0x40000100,
128 0xc8c, 0x20200000, 128 0xc8c, 0xa0e40000,
129 0xc90, 0x00121820, 129 0xc90, 0x00121820,
130 0xc94, 0x00000000, 130 0xc94, 0x00000000,
131 0xc98, 0x00121820, 131 0xc98, 0x00121820,
@@ -226,7 +226,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
226 0x804, 0x00000001, 226 0x804, 0x00000001,
227 0x808, 0x0000fc00, 227 0x808, 0x0000fc00,
228 0x80c, 0x0000000a, 228 0x80c, 0x0000000a,
229 0x810, 0x10005388, 229 0x810, 0x10000330,
230 0x814, 0x020c3d10, 230 0x814, 0x020c3d10,
231 0x818, 0x02200385, 231 0x818, 0x02200385,
232 0x81c, 0x00000000, 232 0x81c, 0x00000000,
@@ -300,9 +300,9 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
300 0xc44, 0x000100b7, 300 0xc44, 0x000100b7,
301 0xc48, 0xec020107, 301 0xc48, 0xec020107,
302 0xc4c, 0x007f037f, 302 0xc4c, 0x007f037f,
303 0xc50, 0x6954341e, 303 0xc50, 0x69543420,
304 0xc54, 0x43bc0094, 304 0xc54, 0x43bc0094,
305 0xc58, 0x6954341e, 305 0xc58, 0x69543420,
306 0xc5c, 0x433c0094, 306 0xc5c, 0x433c0094,
307 0xc60, 0x00000000, 307 0xc60, 0x00000000,
308 0xc64, 0x5116848b, 308 0xc64, 0x5116848b,
@@ -340,7 +340,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
340 0xce4, 0x00000000, 340 0xce4, 0x00000000,
341 0xce8, 0x37644302, 341 0xce8, 0x37644302,
342 0xcec, 0x2f97d40c, 342 0xcec, 0x2f97d40c,
343 0xd00, 0x00080740, 343 0xd00, 0x00000740,
344 0xd04, 0x00020401, 344 0xd04, 0x00020401,
345 0xd08, 0x0000907f, 345 0xd08, 0x0000907f,
346 0xd0c, 0x20010201, 346 0xd0c, 0x20010201,
@@ -633,17 +633,17 @@ u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = {
633 0x012, 0x00071000, 633 0x012, 0x00071000,
634 0x012, 0x000b0000, 634 0x012, 0x000b0000,
635 0x012, 0x000fc000, 635 0x012, 0x000fc000,
636 0x013, 0x000287af, 636 0x013, 0x000287b3,
637 0x013, 0x000244b7, 637 0x013, 0x000244b7,
638 0x013, 0x000204ab, 638 0x013, 0x000204ab,
639 0x013, 0x0001c49f, 639 0x013, 0x0001c49f,
640 0x013, 0x00018493, 640 0x013, 0x00018493,
641 0x013, 0x00014297, 641 0x013, 0x0001429b,
642 0x013, 0x00010295, 642 0x013, 0x00010299,
643 0x013, 0x0000c298, 643 0x013, 0x0000c29c,
644 0x013, 0x0000819c, 644 0x013, 0x000081a0,
645 0x013, 0x000040a8, 645 0x013, 0x000040ac,
646 0x013, 0x0000001c, 646 0x013, 0x00000020,
647 0x014, 0x0001944c, 647 0x014, 0x0001944c,
648 0x014, 0x00059444, 648 0x014, 0x00059444,
649 0x014, 0x0009944c, 649 0x014, 0x0009944c,
@@ -932,10 +932,10 @@ u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = {
932 0x608, 0x0000000e, 932 0x608, 0x0000000e,
933 0x609, 0x0000002a, 933 0x609, 0x0000002a,
934 0x652, 0x00000020, 934 0x652, 0x00000020,
935 0x63c, 0x0000000a, 935 0x63c, 0x00000008,
936 0x63d, 0x0000000e, 936 0x63d, 0x00000008,
937 0x63e, 0x0000000a, 937 0x63e, 0x0000000c,
938 0x63f, 0x0000000e, 938 0x63f, 0x0000000c,
939 0x66e, 0x00000005, 939 0x66e, 0x00000005,
940 0x700, 0x00000021, 940 0x700, 0x00000021,
941 0x701, 0x00000043, 941 0x701, 0x00000043,
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c
index 8ed31744a054..4f083fc1d360 100644
--- a/drivers/net/wireless/rtlwifi/stats.c
+++ b/drivers/net/wireless/rtlwifi/stats.c
@@ -176,6 +176,7 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
176 struct rtl_sta_info *drv_priv = NULL; 176 struct rtl_sta_info *drv_priv = NULL;
177 struct ieee80211_sta *sta = NULL; 177 struct ieee80211_sta *sta = NULL;
178 long undec_sm_pwdb; 178 long undec_sm_pwdb;
179 long undec_sm_cck;
179 180
180 rcu_read_lock(); 181 rcu_read_lock();
181 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) 182 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
@@ -185,12 +186,16 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
185 if (sta) { 186 if (sta) {
186 drv_priv = (struct rtl_sta_info *) sta->drv_priv; 187 drv_priv = (struct rtl_sta_info *) sta->drv_priv;
187 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; 188 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
189 undec_sm_cck = drv_priv->rssi_stat.undec_sm_cck;
188 } else { 190 } else {
189 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; 191 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
192 undec_sm_cck = rtlpriv->dm.undec_sm_cck;
190 } 193 }
191 194
192 if (undec_sm_pwdb < 0) 195 if (undec_sm_pwdb < 0)
193 undec_sm_pwdb = pstatus->rx_pwdb_all; 196 undec_sm_pwdb = pstatus->rx_pwdb_all;
197 if (undec_sm_cck < 0)
198 undec_sm_cck = pstatus->rx_pwdb_all;
194 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { 199 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {
195 undec_sm_pwdb = (((undec_sm_pwdb) * 200 undec_sm_pwdb = (((undec_sm_pwdb) *
196 (RX_SMOOTH_FACTOR - 1)) + 201 (RX_SMOOTH_FACTOR - 1)) +
@@ -200,6 +205,15 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
200 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + 205 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
201 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 206 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
202 } 207 }
208 if (pstatus->rx_pwdb_all > (u32) undec_sm_cck) {
209 undec_sm_cck = (((undec_sm_pwdb) *
210 (RX_SMOOTH_FACTOR - 1)) +
211 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
212 undec_sm_cck = undec_sm_cck + 1;
213 } else {
214 undec_sm_pwdb = (((undec_sm_cck) * (RX_SMOOTH_FACTOR - 1)) +
215 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
216 }
203 217
204 if (sta) { 218 if (sta) {
205 drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; 219 drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 6e2b5c5c83c8..4933f02ce1d5 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -475,14 +475,14 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,
475 rtlpriv->stats.rxbytesunicast += skb->len; 475 rtlpriv->stats.rxbytesunicast += skb->len;
476 } 476 }
477 477
478 rtl_is_special_data(hw, skb, false);
479
480 if (ieee80211_is_data(fc)) { 478 if (ieee80211_is_data(fc)) {
481 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 479 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
482 480
483 if (unicast) 481 if (unicast)
484 rtlpriv->link_info.num_rx_inperiod++; 482 rtlpriv->link_info.num_rx_inperiod++;
485 } 483 }
484 /* static bcn for roaming */
485 rtl_beacon_statistic(hw, skb);
486 } 486 }
487} 487}
488 488
@@ -517,8 +517,6 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
517 rtlpriv->stats.rxbytesunicast += skb->len; 517 rtlpriv->stats.rxbytesunicast += skb->len;
518 } 518 }
519 519
520 rtl_is_special_data(hw, skb, false);
521
522 if (ieee80211_is_data(fc)) { 520 if (ieee80211_is_data(fc)) {
523 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 521 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
524 522
@@ -553,7 +551,7 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
553 } 551 }
554} 552}
555 553
556#define __RX_SKB_MAX_QUEUED 32 554#define __RX_SKB_MAX_QUEUED 64
557 555
558static void _rtl_rx_work(unsigned long param) 556static void _rtl_rx_work(unsigned long param)
559{ 557{
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 0c65386fa30d..8c647391bedf 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1033,6 +1033,7 @@ struct rtl_ht_agg {
1033 1033
1034struct rssi_sta { 1034struct rssi_sta {
1035 long undec_sm_pwdb; 1035 long undec_sm_pwdb;
1036 long undec_sm_cck;
1036}; 1037};
1037 1038
1038struct rtl_tid_data { 1039struct rtl_tid_data {
@@ -1323,8 +1324,10 @@ struct fast_ant_training {
1323struct rtl_dm { 1324struct rtl_dm {
1324 /*PHY status for Dynamic Management */ 1325 /*PHY status for Dynamic Management */
1325 long entry_min_undec_sm_pwdb; 1326 long entry_min_undec_sm_pwdb;
1327 long undec_sm_cck;
1326 long undec_sm_pwdb; /*out dm */ 1328 long undec_sm_pwdb; /*out dm */
1327 long entry_max_undec_sm_pwdb; 1329 long entry_max_undec_sm_pwdb;
1330 s32 ofdm_pkt_cnt;
1328 bool dm_initialgain_enable; 1331 bool dm_initialgain_enable;
1329 bool dynamic_txpower_enable; 1332 bool dynamic_txpower_enable;
1330 bool current_turbo_edca; 1333 bool current_turbo_edca;
@@ -1339,6 +1342,7 @@ struct rtl_dm {
1339 bool inform_fw_driverctrldm; 1342 bool inform_fw_driverctrldm;
1340 bool current_mrc_switch; 1343 bool current_mrc_switch;
1341 u8 txpowercount; 1344 u8 txpowercount;
1345 u8 powerindex_backup[6];
1342 1346
1343 u8 thermalvalue_rxgain; 1347 u8 thermalvalue_rxgain;
1344 u8 thermalvalue_iqk; 1348 u8 thermalvalue_iqk;
@@ -1350,7 +1354,9 @@ struct rtl_dm {
1350 bool done_txpower; 1354 bool done_txpower;
1351 u8 dynamic_txhighpower_lvl; /*Tx high power level */ 1355 u8 dynamic_txhighpower_lvl; /*Tx high power level */
1352 u8 dm_flag; /*Indicate each dynamic mechanism's status. */ 1356 u8 dm_flag; /*Indicate each dynamic mechanism's status. */
1357 u8 dm_flag_tmp;
1353 u8 dm_type; 1358 u8 dm_type;
1359 u8 dm_rssi_sel;
1354 u8 txpower_track_control; 1360 u8 txpower_track_control;
1355 bool interrupt_migration; 1361 bool interrupt_migration;
1356 bool disable_tx_int; 1362 bool disable_tx_int;
@@ -1804,6 +1810,7 @@ struct rtl_hal_cfg {
1804 bool write_readback; 1810 bool write_readback;
1805 char *name; 1811 char *name;
1806 char *fw_name; 1812 char *fw_name;
1813 char *alt_fw_name;
1807 struct rtl_hal_ops *ops; 1814 struct rtl_hal_ops *ops;
1808 struct rtl_mod_params *mod_params; 1815 struct rtl_mod_params *mod_params;
1809 struct rtl_hal_usbint_cfg *usb_interface_cfg; 1816 struct rtl_hal_usbint_cfg *usb_interface_cfg;
@@ -1948,6 +1955,7 @@ struct dig_t {
1948 u8 pre_ccastate; 1955 u8 pre_ccastate;
1949 u8 cur_ccasate; 1956 u8 cur_ccasate;
1950 u8 large_fa_hit; 1957 u8 large_fa_hit;
1958 u8 dig_dynamic_min;
1951 u8 forbidden_igi; 1959 u8 forbidden_igi;
1952 u8 dig_state; 1960 u8 dig_state;
1953 u8 dig_highpwrstate; 1961 u8 dig_highpwrstate;
@@ -2028,22 +2036,15 @@ struct rtl_priv {
2028 struct dig_t dm_digtable; 2036 struct dig_t dm_digtable;
2029 struct ps_t dm_pstable; 2037 struct ps_t dm_pstable;
2030 2038
2031 /* section shared by individual drivers */ 2039 u32 reg_874;
2032 union { 2040 u32 reg_c70;
2033 struct { /* data buffer pointer for USB reads */ 2041 u32 reg_85c;
2034 __le32 *usb_data; 2042 u32 reg_a74;
2035 int usb_data_index; 2043 bool reg_init; /* true if regs saved */
2036 bool initialized; 2044 bool bt_operation_on;
2037 }; 2045 __le32 *usb_data;
2038 struct { /* section for 8723ae */ 2046 int usb_data_index;
2039 bool reg_init; /* true if regs saved */ 2047 bool initialized;
2040 u32 reg_874;
2041 u32 reg_c70;
2042 u32 reg_85c;
2043 u32 reg_a74;
2044 bool bt_operation_on;
2045 };
2046 };
2047 bool enter_ps; /* true when entering PS */ 2048 bool enter_ps; /* true when entering PS */
2048 u8 rate_mask[5]; 2049 u8 rate_mask[5];
2049 2050
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index db6430c1a084..5a4ec56c83d0 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -18,10 +18,8 @@ int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
18 wl1251_debug(DEBUG_ACX, "acx frame rates"); 18 wl1251_debug(DEBUG_ACX, "acx frame rates");
19 19
20 rates = kzalloc(sizeof(*rates), GFP_KERNEL); 20 rates = kzalloc(sizeof(*rates), GFP_KERNEL);
21 if (!rates) { 21 if (!rates)
22 ret = -ENOMEM; 22 return -ENOMEM;
23 goto out;
24 }
25 23
26 rates->tx_ctrl_frame_rate = ctrl_rate; 24 rates->tx_ctrl_frame_rate = ctrl_rate;
27 rates->tx_ctrl_frame_mod = ctrl_mod; 25 rates->tx_ctrl_frame_mod = ctrl_mod;
@@ -49,10 +47,8 @@ int wl1251_acx_station_id(struct wl1251 *wl)
49 wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); 47 wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
50 48
51 mac = kzalloc(sizeof(*mac), GFP_KERNEL); 49 mac = kzalloc(sizeof(*mac), GFP_KERNEL);
52 if (!mac) { 50 if (!mac)
53 ret = -ENOMEM; 51 return -ENOMEM;
54 goto out;
55 }
56 52
57 for (i = 0; i < ETH_ALEN; i++) 53 for (i = 0; i < ETH_ALEN; i++)
58 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; 54 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
@@ -74,10 +70,8 @@ int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
74 wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); 70 wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
75 71
76 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); 72 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
77 if (!default_key) { 73 if (!default_key)
78 ret = -ENOMEM; 74 return -ENOMEM;
79 goto out;
80 }
81 75
82 default_key->id = key_id; 76 default_key->id = key_id;
83 77
@@ -104,10 +98,8 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
104 wl1251_debug(DEBUG_ACX, "acx wake up conditions"); 98 wl1251_debug(DEBUG_ACX, "acx wake up conditions");
105 99
106 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); 100 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
107 if (!wake_up) { 101 if (!wake_up)
108 ret = -ENOMEM; 102 return -ENOMEM;
109 goto out;
110 }
111 103
112 wake_up->wake_up_event = wake_up_event; 104 wake_up->wake_up_event = wake_up_event;
113 wake_up->listen_interval = listen_interval; 105 wake_up->listen_interval = listen_interval;
@@ -132,16 +124,13 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
132 wl1251_debug(DEBUG_ACX, "acx sleep auth"); 124 wl1251_debug(DEBUG_ACX, "acx sleep auth");
133 125
134 auth = kzalloc(sizeof(*auth), GFP_KERNEL); 126 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
135 if (!auth) { 127 if (!auth)
136 ret = -ENOMEM; 128 return -ENOMEM;
137 goto out;
138 }
139 129
140 auth->sleep_auth = sleep_auth; 130 auth->sleep_auth = sleep_auth;
141 131
142 ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); 132 ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
143 133
144out:
145 kfree(auth); 134 kfree(auth);
146 return ret; 135 return ret;
147} 136}
@@ -154,10 +143,8 @@ int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
154 wl1251_debug(DEBUG_ACX, "acx fw rev"); 143 wl1251_debug(DEBUG_ACX, "acx fw rev");
155 144
156 rev = kzalloc(sizeof(*rev), GFP_KERNEL); 145 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
157 if (!rev) { 146 if (!rev)
158 ret = -ENOMEM; 147 return -ENOMEM;
159 goto out;
160 }
161 148
162 ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); 149 ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
163 if (ret < 0) { 150 if (ret < 0) {
@@ -191,10 +178,8 @@ int wl1251_acx_tx_power(struct wl1251 *wl, int power)
191 return -EINVAL; 178 return -EINVAL;
192 179
193 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 180 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
194 if (!acx) { 181 if (!acx)
195 ret = -ENOMEM; 182 return -ENOMEM;
196 goto out;
197 }
198 183
199 acx->current_tx_power = power * 10; 184 acx->current_tx_power = power * 10;
200 185
@@ -209,7 +194,7 @@ out:
209 return ret; 194 return ret;
210} 195}
211 196
212int wl1251_acx_feature_cfg(struct wl1251 *wl) 197int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options)
213{ 198{
214 struct acx_feature_config *feature; 199 struct acx_feature_config *feature;
215 int ret; 200 int ret;
@@ -217,13 +202,11 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl)
217 wl1251_debug(DEBUG_ACX, "acx feature cfg"); 202 wl1251_debug(DEBUG_ACX, "acx feature cfg");
218 203
219 feature = kzalloc(sizeof(*feature), GFP_KERNEL); 204 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
220 if (!feature) { 205 if (!feature)
221 ret = -ENOMEM; 206 return -ENOMEM;
222 goto out;
223 }
224 207
225 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 208 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE can be set */
226 feature->data_flow_options = 0; 209 feature->data_flow_options = data_flow_options;
227 feature->options = 0; 210 feature->options = 0;
228 211
229 ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, 212 ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
@@ -261,10 +244,8 @@ int wl1251_acx_data_path_params(struct wl1251 *wl,
261 wl1251_debug(DEBUG_ACX, "acx data path params"); 244 wl1251_debug(DEBUG_ACX, "acx data path params");
262 245
263 params = kzalloc(sizeof(*params), GFP_KERNEL); 246 params = kzalloc(sizeof(*params), GFP_KERNEL);
264 if (!params) { 247 if (!params)
265 ret = -ENOMEM; 248 return -ENOMEM;
266 goto out;
267 }
268 249
269 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; 250 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
270 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; 251 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
@@ -309,10 +290,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
309 wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); 290 wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
310 291
311 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 292 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
312 if (!acx) { 293 if (!acx)
313 ret = -ENOMEM; 294 return -ENOMEM;
314 goto out;
315 }
316 295
317 acx->lifetime = life_time; 296 acx->lifetime = life_time;
318 ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, 297 ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
@@ -335,10 +314,8 @@ int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
335 wl1251_debug(DEBUG_ACX, "acx rx config"); 314 wl1251_debug(DEBUG_ACX, "acx rx config");
336 315
337 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); 316 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
338 if (!rx_config) { 317 if (!rx_config)
339 ret = -ENOMEM; 318 return -ENOMEM;
340 goto out;
341 }
342 319
343 rx_config->config_options = config; 320 rx_config->config_options = config;
344 rx_config->filter_options = filter; 321 rx_config->filter_options = filter;
@@ -363,10 +340,8 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl)
363 wl1251_debug(DEBUG_ACX, "acx data pd threshold"); 340 wl1251_debug(DEBUG_ACX, "acx data pd threshold");
364 341
365 pd = kzalloc(sizeof(*pd), GFP_KERNEL); 342 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
366 if (!pd) { 343 if (!pd)
367 ret = -ENOMEM; 344 return -ENOMEM;
368 goto out;
369 }
370 345
371 /* FIXME: threshold value not set */ 346 /* FIXME: threshold value not set */
372 347
@@ -389,10 +364,8 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
389 wl1251_debug(DEBUG_ACX, "acx slot"); 364 wl1251_debug(DEBUG_ACX, "acx slot");
390 365
391 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 366 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
392 if (!slot) { 367 if (!slot)
393 ret = -ENOMEM; 368 return -ENOMEM;
394 goto out;
395 }
396 369
397 slot->wone_index = STATION_WONE_INDEX; 370 slot->wone_index = STATION_WONE_INDEX;
398 slot->slot_time = slot_time; 371 slot->slot_time = slot_time;
@@ -408,7 +381,8 @@ out:
408 return ret; 381 return ret;
409} 382}
410 383
411int wl1251_acx_group_address_tbl(struct wl1251 *wl) 384int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable,
385 void *mc_list, u32 mc_list_len)
412{ 386{
413 struct acx_dot11_grp_addr_tbl *acx; 387 struct acx_dot11_grp_addr_tbl *acx;
414 int ret; 388 int ret;
@@ -416,15 +390,13 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl)
416 wl1251_debug(DEBUG_ACX, "acx group address tbl"); 390 wl1251_debug(DEBUG_ACX, "acx group address tbl");
417 391
418 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 392 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
419 if (!acx) { 393 if (!acx)
420 ret = -ENOMEM; 394 return -ENOMEM;
421 goto out;
422 }
423 395
424 /* MAC filtering */ 396 /* MAC filtering */
425 acx->enabled = 0; 397 acx->enabled = enable;
426 acx->num_groups = 0; 398 acx->num_groups = mc_list_len;
427 memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN); 399 memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN);
428 400
429 ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, 401 ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
430 acx, sizeof(*acx)); 402 acx, sizeof(*acx));
@@ -444,10 +416,8 @@ int wl1251_acx_service_period_timeout(struct wl1251 *wl)
444 int ret; 416 int ret;
445 417
446 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); 418 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
447 if (!rx_timeout) { 419 if (!rx_timeout)
448 ret = -ENOMEM; 420 return -ENOMEM;
449 goto out;
450 }
451 421
452 wl1251_debug(DEBUG_ACX, "acx service period timeout"); 422 wl1251_debug(DEBUG_ACX, "acx service period timeout");
453 423
@@ -475,10 +445,8 @@ int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
475 wl1251_debug(DEBUG_ACX, "acx rts threshold"); 445 wl1251_debug(DEBUG_ACX, "acx rts threshold");
476 446
477 rts = kzalloc(sizeof(*rts), GFP_KERNEL); 447 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
478 if (!rts) { 448 if (!rts)
479 ret = -ENOMEM; 449 return -ENOMEM;
480 goto out;
481 }
482 450
483 rts->threshold = rts_threshold; 451 rts->threshold = rts_threshold;
484 452
@@ -501,10 +469,8 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
501 wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); 469 wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
502 470
503 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); 471 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
504 if (!beacon_filter) { 472 if (!beacon_filter)
505 ret = -ENOMEM; 473 return -ENOMEM;
506 goto out;
507 }
508 474
509 beacon_filter->enable = enable_filter; 475 beacon_filter->enable = enable_filter;
510 beacon_filter->max_num_beacons = 0; 476 beacon_filter->max_num_beacons = 0;
@@ -530,10 +496,8 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
530 wl1251_debug(DEBUG_ACX, "acx beacon filter table"); 496 wl1251_debug(DEBUG_ACX, "acx beacon filter table");
531 497
532 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); 498 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
533 if (!ie_table) { 499 if (!ie_table)
534 ret = -ENOMEM; 500 return -ENOMEM;
535 goto out;
536 }
537 501
538 /* configure default beacon pass-through rules */ 502 /* configure default beacon pass-through rules */
539 ie_table->num_ie = 1; 503 ie_table->num_ie = 1;
@@ -560,10 +524,8 @@ int wl1251_acx_conn_monit_params(struct wl1251 *wl)
560 wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); 524 wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
561 525
562 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 526 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
563 if (!acx) { 527 if (!acx)
564 ret = -ENOMEM; 528 return -ENOMEM;
565 goto out;
566 }
567 529
568 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; 530 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
569 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; 531 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
@@ -589,10 +551,8 @@ int wl1251_acx_sg_enable(struct wl1251 *wl)
589 wl1251_debug(DEBUG_ACX, "acx sg enable"); 551 wl1251_debug(DEBUG_ACX, "acx sg enable");
590 552
591 pta = kzalloc(sizeof(*pta), GFP_KERNEL); 553 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
592 if (!pta) { 554 if (!pta)
593 ret = -ENOMEM; 555 return -ENOMEM;
594 goto out;
595 }
596 556
597 pta->enable = SG_ENABLE; 557 pta->enable = SG_ENABLE;
598 558
@@ -615,10 +575,8 @@ int wl1251_acx_sg_cfg(struct wl1251 *wl)
615 wl1251_debug(DEBUG_ACX, "acx sg cfg"); 575 wl1251_debug(DEBUG_ACX, "acx sg cfg");
616 576
617 param = kzalloc(sizeof(*param), GFP_KERNEL); 577 param = kzalloc(sizeof(*param), GFP_KERNEL);
618 if (!param) { 578 if (!param)
619 ret = -ENOMEM; 579 return -ENOMEM;
620 goto out;
621 }
622 580
623 /* BT-WLAN coext parameters */ 581 /* BT-WLAN coext parameters */
624 param->min_rate = RATE_INDEX_24MBPS; 582 param->min_rate = RATE_INDEX_24MBPS;
@@ -669,10 +627,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
669 wl1251_debug(DEBUG_ACX, "acx cca threshold"); 627 wl1251_debug(DEBUG_ACX, "acx cca threshold");
670 628
671 detection = kzalloc(sizeof(*detection), GFP_KERNEL); 629 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
672 if (!detection) { 630 if (!detection)
673 ret = -ENOMEM; 631 return -ENOMEM;
674 goto out;
675 }
676 632
677 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 633 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
678 detection->tx_energy_detection = 0; 634 detection->tx_energy_detection = 0;
@@ -682,7 +638,6 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
682 if (ret < 0) 638 if (ret < 0)
683 wl1251_warning("failed to set cca threshold: %d", ret); 639 wl1251_warning("failed to set cca threshold: %d", ret);
684 640
685out:
686 kfree(detection); 641 kfree(detection);
687 return ret; 642 return ret;
688} 643}
@@ -695,10 +650,8 @@ int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
695 wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); 650 wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
696 651
697 bb = kzalloc(sizeof(*bb), GFP_KERNEL); 652 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
698 if (!bb) { 653 if (!bb)
699 ret = -ENOMEM; 654 return -ENOMEM;
700 goto out;
701 }
702 655
703 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 656 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
704 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; 657 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
@@ -724,10 +677,8 @@ int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
724 wl1251_debug(DEBUG_ACX, "acx aid"); 677 wl1251_debug(DEBUG_ACX, "acx aid");
725 678
726 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); 679 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
727 if (!acx_aid) { 680 if (!acx_aid)
728 ret = -ENOMEM; 681 return -ENOMEM;
729 goto out;
730 }
731 682
732 acx_aid->aid = aid; 683 acx_aid->aid = aid;
733 684
@@ -750,10 +701,8 @@ int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
750 wl1251_debug(DEBUG_ACX, "acx event mbox mask"); 701 wl1251_debug(DEBUG_ACX, "acx event mbox mask");
751 702
752 mask = kzalloc(sizeof(*mask), GFP_KERNEL); 703 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
753 if (!mask) { 704 if (!mask)
754 ret = -ENOMEM; 705 return -ENOMEM;
755 goto out;
756 }
757 706
758 /* high event mask is unused */ 707 /* high event mask is unused */
759 mask->high_event_mask = 0xffffffff; 708 mask->high_event_mask = 0xffffffff;
@@ -805,10 +754,8 @@ int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
805 wl1251_debug(DEBUG_ACX, "acx_set_preamble"); 754 wl1251_debug(DEBUG_ACX, "acx_set_preamble");
806 755
807 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 756 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
808 if (!acx) { 757 if (!acx)
809 ret = -ENOMEM; 758 return -ENOMEM;
810 goto out;
811 }
812 759
813 acx->preamble = preamble; 760 acx->preamble = preamble;
814 761
@@ -832,10 +779,8 @@ int wl1251_acx_cts_protect(struct wl1251 *wl,
832 wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); 779 wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
833 780
834 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 781 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
835 if (!acx) { 782 if (!acx)
836 ret = -ENOMEM; 783 return -ENOMEM;
837 goto out;
838 }
839 784
840 acx->ctsprotect = ctsprotect; 785 acx->ctsprotect = ctsprotect;
841 786
@@ -856,10 +801,8 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
856 int ret; 801 int ret;
857 802
858 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); 803 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
859 if (!tsf_info) { 804 if (!tsf_info)
860 ret = -ENOMEM; 805 return -ENOMEM;
861 goto out;
862 }
863 806
864 ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO, 807 ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
865 tsf_info, sizeof(*tsf_info)); 808 tsf_info, sizeof(*tsf_info));
@@ -900,19 +843,22 @@ int wl1251_acx_rate_policies(struct wl1251 *wl)
900 wl1251_debug(DEBUG_ACX, "acx rate policies"); 843 wl1251_debug(DEBUG_ACX, "acx rate policies");
901 844
902 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 845 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
903 846 if (!acx)
904 if (!acx) { 847 return -ENOMEM;
905 ret = -ENOMEM;
906 goto out;
907 }
908 848
909 /* configure one default (one-size-fits-all) rate class */ 849 /* configure one default (one-size-fits-all) rate class */
910 acx->rate_class_cnt = 1; 850 acx->rate_class_cnt = 2;
911 acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED; 851 acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
912 acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT; 852 acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
913 acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT; 853 acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
914 acx->rate_class[0].aflags = 0; 854 acx->rate_class[0].aflags = 0;
915 855
856 /* no-retry rate class */
857 acx->rate_class[1].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
858 acx->rate_class[1].short_retry_limit = 0;
859 acx->rate_class[1].long_retry_limit = 0;
860 acx->rate_class[1].aflags = 0;
861
916 ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 862 ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
917 if (ret < 0) { 863 if (ret < 0) {
918 wl1251_warning("Setting of rate policies failed: %d", ret); 864 wl1251_warning("Setting of rate policies failed: %d", ret);
@@ -932,10 +878,8 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl)
932 wl1251_debug(DEBUG_ACX, "acx mem cfg"); 878 wl1251_debug(DEBUG_ACX, "acx mem cfg");
933 879
934 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); 880 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
935 if (!mem_conf) { 881 if (!mem_conf)
936 ret = -ENOMEM; 882 return -ENOMEM;
937 goto out;
938 }
939 883
940 /* memory config */ 884 /* memory config */
941 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); 885 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
@@ -979,10 +923,8 @@ int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
979 wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); 923 wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
980 924
981 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 925 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
982 if (!acx) { 926 if (!acx)
983 ret = -ENOMEM; 927 return -ENOMEM;
984 goto out;
985 }
986 928
987 acx->tbtt = tbtt; 929 acx->tbtt = tbtt;
988 acx->dtim = dtim; 930 acx->dtim = dtim;
@@ -1008,10 +950,8 @@ int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1008 wl1251_debug(DEBUG_ACX, "acx bet enable"); 950 wl1251_debug(DEBUG_ACX, "acx bet enable");
1009 951
1010 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 952 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1011 if (!acx) { 953 if (!acx)
1012 ret = -ENOMEM; 954 return -ENOMEM;
1013 goto out;
1014 }
1015 955
1016 acx->enable = mode; 956 acx->enable = mode;
1017 acx->max_consecutive = max_consecutive; 957 acx->max_consecutive = max_consecutive;
@@ -1027,6 +967,32 @@ out:
1027 return ret; 967 return ret;
1028} 968}
1029 969
970int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address)
971{
972 struct wl1251_acx_arp_filter *acx;
973 int ret;
974
975 wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable);
976
977 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
978 if (!acx)
979 return -ENOMEM;
980
981 acx->version = ACX_IPV4_VERSION;
982 acx->enable = enable;
983
984 if (enable)
985 memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
986
987 ret = wl1251_cmd_configure(wl, ACX_ARP_IP_FILTER,
988 acx, sizeof(*acx));
989 if (ret < 0)
990 wl1251_warning("failed to set arp ip filter: %d", ret);
991
992 kfree(acx);
993 return ret;
994}
995
1030int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, 996int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1031 u8 aifs, u16 txop) 997 u8 aifs, u16 txop)
1032{ 998{
@@ -1037,11 +1003,8 @@ int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1037 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); 1003 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
1038 1004
1039 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1005 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1040 1006 if (!acx)
1041 if (!acx) { 1007 return -ENOMEM;
1042 ret = -ENOMEM;
1043 goto out;
1044 }
1045 1008
1046 acx->ac = ac; 1009 acx->ac = ac;
1047 acx->cw_min = cw_min; 1010 acx->cw_min = cw_min;
@@ -1073,11 +1036,8 @@ int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1073 ps_scheme, ack_policy); 1036 ps_scheme, ack_policy);
1074 1037
1075 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1038 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1076 1039 if (!acx)
1077 if (!acx) { 1040 return -ENOMEM;
1078 ret = -ENOMEM;
1079 goto out;
1080 }
1081 1041
1082 acx->queue = queue; 1042 acx->queue = queue;
1083 acx->type = type; 1043 acx->type = type;
diff --git a/drivers/net/wireless/ti/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index c2ba100f9b1a..2bdec38699f4 100644
--- a/drivers/net/wireless/ti/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
@@ -350,8 +350,8 @@ struct acx_slot {
350} __packed; 350} __packed;
351 351
352 352
353#define ADDRESS_GROUP_MAX (8) 353#define ACX_MC_ADDRESS_GROUP_MAX (8)
354#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX) 354#define ACX_MC_ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_ADDRESS_GROUP_MAX)
355 355
356struct acx_dot11_grp_addr_tbl { 356struct acx_dot11_grp_addr_tbl {
357 struct acx_header header; 357 struct acx_header header;
@@ -359,7 +359,7 @@ struct acx_dot11_grp_addr_tbl {
359 u8 enabled; 359 u8 enabled;
360 u8 num_groups; 360 u8 num_groups;
361 u8 pad[2]; 361 u8 pad[2];
362 u8 mac_table[ADDRESS_GROUP_MAX_LEN]; 362 u8 mac_table[ACX_MC_ADDRESS_GROUP_MAX_LEN];
363} __packed; 363} __packed;
364 364
365 365
@@ -1232,6 +1232,20 @@ struct wl1251_acx_bet_enable {
1232 u8 padding[2]; 1232 u8 padding[2];
1233} __packed; 1233} __packed;
1234 1234
1235#define ACX_IPV4_VERSION 4
1236#define ACX_IPV6_VERSION 6
1237#define ACX_IPV4_ADDR_SIZE 4
1238struct wl1251_acx_arp_filter {
1239 struct acx_header header;
1240 u8 version; /* The IP version: 4 - IPv4, 6 - IPv6.*/
1241 u8 enable; /* 1 - ARP filtering is enabled, 0 - disabled */
1242 u8 padding[2];
1243 u8 address[16]; /* The IP address used to filter ARP packets.
1244 ARP packets that do not match this address are
1245 dropped. When the IP Version is 4, the last 12
1246 bytes of the the address are ignored. */
1247} __attribute__((packed));
1248
1235struct wl1251_acx_ac_cfg { 1249struct wl1251_acx_ac_cfg {
1236 struct acx_header header; 1250 struct acx_header header;
1237 1251
@@ -1440,7 +1454,7 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
1440int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth); 1454int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
1441int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len); 1455int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
1442int wl1251_acx_tx_power(struct wl1251 *wl, int power); 1456int wl1251_acx_tx_power(struct wl1251 *wl, int power);
1443int wl1251_acx_feature_cfg(struct wl1251 *wl); 1457int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options);
1444int wl1251_acx_mem_map(struct wl1251 *wl, 1458int wl1251_acx_mem_map(struct wl1251 *wl,
1445 struct acx_header *mem_map, size_t len); 1459 struct acx_header *mem_map, size_t len);
1446int wl1251_acx_data_path_params(struct wl1251 *wl, 1460int wl1251_acx_data_path_params(struct wl1251 *wl,
@@ -1449,7 +1463,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
1449int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter); 1463int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
1450int wl1251_acx_pd_threshold(struct wl1251 *wl); 1464int wl1251_acx_pd_threshold(struct wl1251 *wl);
1451int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); 1465int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
1452int wl1251_acx_group_address_tbl(struct wl1251 *wl); 1466int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable,
1467 void *mc_list, u32 mc_list_len);
1453int wl1251_acx_service_period_timeout(struct wl1251 *wl); 1468int wl1251_acx_service_period_timeout(struct wl1251 *wl);
1454int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); 1469int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
1455int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); 1470int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
@@ -1473,6 +1488,7 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl);
1473int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); 1488int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
1474int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, 1489int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1475 u8 max_consecutive); 1490 u8 max_consecutive);
1491int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address);
1476int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, 1492int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1477 u8 aifs, u16 txop); 1493 u8 aifs, u16 txop);
1478int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, 1494int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
diff --git a/drivers/net/wireless/ti/wl1251/boot.c b/drivers/net/wireless/ti/wl1251/boot.c
index a2e5241382da..2000cd536077 100644
--- a/drivers/net/wireless/ti/wl1251/boot.c
+++ b/drivers/net/wireless/ti/wl1251/boot.c
@@ -299,7 +299,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
299 ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | 299 ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
300 ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | 300 ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
301 REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | 301 REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
302 BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; 302 BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID |
303 PS_REPORT_EVENT_ID;
303 304
304 ret = wl1251_event_unmask(wl); 305 ret = wl1251_event_unmask(wl);
305 if (ret < 0) { 306 if (ret < 0) {
diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index 6822b845efc1..223649bcaa5a 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
@@ -3,6 +3,7 @@
3#include <linux/module.h> 3#include <linux/module.h>
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/crc7.h> 5#include <linux/crc7.h>
6#include <linux/etherdevice.h>
6 7
7#include "wl1251.h" 8#include "wl1251.h"
8#include "reg.h" 9#include "reg.h"
@@ -203,11 +204,11 @@ out:
203 return ret; 204 return ret;
204} 205}
205 206
206int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) 207int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable)
207{ 208{
208 struct cmd_enabledisable_path *cmd; 209 struct cmd_enabledisable_path *cmd;
209 int ret; 210 int ret;
210 u16 cmd_rx, cmd_tx; 211 u16 cmd_rx;
211 212
212 wl1251_debug(DEBUG_CMD, "cmd data path"); 213 wl1251_debug(DEBUG_CMD, "cmd data path");
213 214
@@ -219,13 +220,10 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
219 220
220 cmd->channel = channel; 221 cmd->channel = channel;
221 222
222 if (enable) { 223 if (enable)
223 cmd_rx = CMD_ENABLE_RX; 224 cmd_rx = CMD_ENABLE_RX;
224 cmd_tx = CMD_ENABLE_TX; 225 else
225 } else {
226 cmd_rx = CMD_DISABLE_RX; 226 cmd_rx = CMD_DISABLE_RX;
227 cmd_tx = CMD_DISABLE_TX;
228 }
229 227
230 ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); 228 ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
231 if (ret < 0) { 229 if (ret < 0) {
@@ -237,17 +235,38 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
237 wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", 235 wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
238 enable ? "start" : "stop", channel); 236 enable ? "start" : "stop", channel);
239 237
238out:
239 kfree(cmd);
240 return ret;
241}
242
243int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable)
244{
245 struct cmd_enabledisable_path *cmd;
246 int ret;
247 u16 cmd_tx;
248
249 wl1251_debug(DEBUG_CMD, "cmd data path");
250
251 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
252 if (!cmd)
253 return -ENOMEM;
254
255 cmd->channel = channel;
256
257 if (enable)
258 cmd_tx = CMD_ENABLE_TX;
259 else
260 cmd_tx = CMD_DISABLE_TX;
261
240 ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); 262 ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
241 if (ret < 0) { 263 if (ret < 0)
242 wl1251_error("tx %s cmd for channel %d failed", 264 wl1251_error("tx %s cmd for channel %d failed",
243 enable ? "start" : "stop", channel); 265 enable ? "start" : "stop", channel);
244 goto out; 266 else
245 } 267 wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
246 268 enable ? "start" : "stop", channel);
247 wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
248 enable ? "start" : "stop", channel);
249 269
250out:
251 kfree(cmd); 270 kfree(cmd);
252 return ret; 271 return ret;
253} 272}
@@ -410,7 +429,9 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
410 struct wl1251_cmd_scan *cmd; 429 struct wl1251_cmd_scan *cmd;
411 int i, ret = 0; 430 int i, ret = 0;
412 431
413 wl1251_debug(DEBUG_CMD, "cmd scan"); 432 wl1251_debug(DEBUG_CMD, "cmd scan channels %d", n_channels);
433
434 WARN_ON(n_channels > SCAN_MAX_NUM_OF_CHANNELS);
414 435
415 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 436 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
416 if (!cmd) 437 if (!cmd)
@@ -421,6 +442,13 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
421 CFG_RX_MGMT_EN | 442 CFG_RX_MGMT_EN |
422 CFG_RX_BCN_EN); 443 CFG_RX_BCN_EN);
423 cmd->params.scan_options = 0; 444 cmd->params.scan_options = 0;
445 /*
446 * Use high priority scan when not associated to prevent fw issue
447 * causing never-ending scans (sometimes 20+ minutes).
448 * Note: This bug may be caused by the fw's DTIM handling.
449 */
450 if (is_zero_ether_addr(wl->bssid))
451 cmd->params.scan_options |= WL1251_SCAN_OPT_PRIORITY_HIGH;
424 cmd->params.num_channels = n_channels; 452 cmd->params.num_channels = n_channels;
425 cmd->params.num_probe_requests = n_probes; 453 cmd->params.num_probe_requests = n_probes;
426 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ 454 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
diff --git a/drivers/net/wireless/ti/wl1251/cmd.h b/drivers/net/wireless/ti/wl1251/cmd.h
index ee4f2b391822..d824ff978311 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.h
+++ b/drivers/net/wireless/ti/wl1251/cmd.h
@@ -35,7 +35,8 @@ int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len);
35int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len); 35int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len);
36int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, 36int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
37 void *bitmap, u16 bitmap_len, u8 bitmap_control); 37 void *bitmap, u16 bitmap_len, u8 bitmap_control);
38int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable); 38int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable);
39int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable);
39int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, 40int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
40 u16 beacon_interval, u8 dtim_interval); 41 u16 beacon_interval, u8 dtim_interval);
41int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode); 42int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
@@ -167,6 +168,11 @@ struct cmd_read_write_memory {
167#define CMDMBOX_HEADER_LEN 4 168#define CMDMBOX_HEADER_LEN 4
168#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 169#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
169 170
171#define WL1251_SCAN_OPT_PASSIVE 1
172#define WL1251_SCAN_OPT_5GHZ_BAND 2
173#define WL1251_SCAN_OPT_TRIGGERD_SCAN 4
174#define WL1251_SCAN_OPT_PRIORITY_HIGH 8
175
170#define WL1251_SCAN_MIN_DURATION 30000 176#define WL1251_SCAN_MIN_DURATION 30000
171#define WL1251_SCAN_MAX_DURATION 60000 177#define WL1251_SCAN_MAX_DURATION 60000
172 178
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index 74ae8e1c2e33..db0105313745 100644
--- a/drivers/net/wireless/ti/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
@@ -46,6 +46,43 @@ static int wl1251_event_scan_complete(struct wl1251 *wl,
46 return ret; 46 return ret;
47} 47}
48 48
49#define WL1251_PSM_ENTRY_RETRIES 3
50static int wl1251_event_ps_report(struct wl1251 *wl,
51 struct event_mailbox *mbox)
52{
53 int ret = 0;
54
55 wl1251_debug(DEBUG_EVENT, "ps status: %x", mbox->ps_status);
56
57 switch (mbox->ps_status) {
58 case EVENT_ENTER_POWER_SAVE_FAIL:
59 wl1251_debug(DEBUG_PSM, "PSM entry failed");
60
61 if (wl->station_mode != STATION_POWER_SAVE_MODE) {
62 /* remain in active mode */
63 wl->psm_entry_retry = 0;
64 break;
65 }
66
67 if (wl->psm_entry_retry < WL1251_PSM_ENTRY_RETRIES) {
68 wl->psm_entry_retry++;
69 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
70 } else {
71 wl1251_error("Power save entry failed, giving up");
72 wl->psm_entry_retry = 0;
73 }
74 break;
75 case EVENT_ENTER_POWER_SAVE_SUCCESS:
76 case EVENT_EXIT_POWER_SAVE_FAIL:
77 case EVENT_EXIT_POWER_SAVE_SUCCESS:
78 default:
79 wl->psm_entry_retry = 0;
80 break;
81 }
82
83 return 0;
84}
85
49static void wl1251_event_mbox_dump(struct event_mailbox *mbox) 86static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
50{ 87{
51 wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); 88 wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -80,7 +117,14 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
80 } 117 }
81 } 118 }
82 119
83 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { 120 if (vector & PS_REPORT_EVENT_ID) {
121 wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
122 ret = wl1251_event_ps_report(wl, mbox);
123 if (ret < 0)
124 return ret;
125 }
126
127 if (wl->vif && vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
84 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); 128 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
85 129
86 /* indicate to the stack, that beacons have been lost */ 130 /* indicate to the stack, that beacons have been lost */
diff --git a/drivers/net/wireless/ti/wl1251/event.h b/drivers/net/wireless/ti/wl1251/event.h
index 30eb5d150bf7..88570a5cd042 100644
--- a/drivers/net/wireless/ti/wl1251/event.h
+++ b/drivers/net/wireless/ti/wl1251/event.h
@@ -112,6 +112,13 @@ struct event_mailbox {
112 u8 padding[19]; 112 u8 padding[19];
113} __packed; 113} __packed;
114 114
115enum {
116 EVENT_ENTER_POWER_SAVE_FAIL = 0,
117 EVENT_ENTER_POWER_SAVE_SUCCESS,
118 EVENT_EXIT_POWER_SAVE_FAIL,
119 EVENT_EXIT_POWER_SAVE_SUCCESS,
120};
121
115int wl1251_event_unmask(struct wl1251 *wl); 122int wl1251_event_unmask(struct wl1251 *wl);
116void wl1251_event_mbox_config(struct wl1251 *wl); 123void wl1251_event_mbox_config(struct wl1251 *wl);
117int wl1251_event_handle(struct wl1251 *wl, u8 mbox); 124int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c
index 89b43d35473c..1d799bffaa9f 100644
--- a/drivers/net/wireless/ti/wl1251/init.c
+++ b/drivers/net/wireless/ti/wl1251/init.c
@@ -33,7 +33,7 @@ int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
33{ 33{
34 int ret; 34 int ret;
35 35
36 ret = wl1251_acx_feature_cfg(wl); 36 ret = wl1251_acx_feature_cfg(wl, 0);
37 if (ret < 0) { 37 if (ret < 0) {
38 wl1251_warning("couldn't set feature config"); 38 wl1251_warning("couldn't set feature config");
39 return ret; 39 return ret;
@@ -127,7 +127,7 @@ int wl1251_hw_init_phy_config(struct wl1251 *wl)
127 if (ret < 0) 127 if (ret < 0)
128 return ret; 128 return ret;
129 129
130 ret = wl1251_acx_group_address_tbl(wl); 130 ret = wl1251_acx_group_address_tbl(wl, true, NULL, 0);
131 if (ret < 0) 131 if (ret < 0)
132 return ret; 132 return ret;
133 133
@@ -394,8 +394,13 @@ int wl1251_hw_init(struct wl1251 *wl)
394 if (ret < 0) 394 if (ret < 0)
395 goto out_free_data_path; 395 goto out_free_data_path;
396 396
397 /* Enable data path */ 397 /* Enable rx data path */
398 ret = wl1251_cmd_data_path(wl, wl->channel, 1); 398 ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
399 if (ret < 0)
400 goto out_free_data_path;
401
402 /* Enable tx data path */
403 ret = wl1251_cmd_data_path_tx(wl, wl->channel, 1);
399 if (ret < 0) 404 if (ret < 0)
400 goto out_free_data_path; 405 goto out_free_data_path;
401 406
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 3291ffa95273..757e25784a8a 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -28,6 +28,7 @@
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/netdevice.h>
31 32
32#include "wl1251.h" 33#include "wl1251.h"
33#include "wl12xx_80211.h" 34#include "wl12xx_80211.h"
@@ -479,10 +480,13 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
479 wl->next_tx_complete = 0; 480 wl->next_tx_complete = 0;
480 wl->elp = false; 481 wl->elp = false;
481 wl->station_mode = STATION_ACTIVE_MODE; 482 wl->station_mode = STATION_ACTIVE_MODE;
483 wl->psm_entry_retry = 0;
482 wl->tx_queue_stopped = false; 484 wl->tx_queue_stopped = false;
483 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 485 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
484 wl->rssi_thold = 0; 486 wl->rssi_thold = 0;
485 wl->channel = WL1251_DEFAULT_CHANNEL; 487 wl->channel = WL1251_DEFAULT_CHANNEL;
488 wl->monitor_present = false;
489 wl->joined = false;
486 490
487 wl1251_debugfs_reset(wl); 491 wl1251_debugfs_reset(wl);
488 492
@@ -521,7 +525,7 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
521 goto out; 525 goto out;
522 } 526 }
523 527
524 if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) { 528 if (!ether_addr_equal_unaligned(wl->mac_addr, vif->addr)) {
525 memcpy(wl->mac_addr, vif->addr, ETH_ALEN); 529 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
526 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); 530 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
527 ret = wl1251_acx_station_id(wl); 531 ret = wl1251_acx_station_id(wl);
@@ -542,6 +546,7 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
542 mutex_lock(&wl->mutex); 546 mutex_lock(&wl->mutex);
543 wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); 547 wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
544 wl->vif = NULL; 548 wl->vif = NULL;
549 memset(wl->bssid, 0, ETH_ALEN);
545 mutex_unlock(&wl->mutex); 550 mutex_unlock(&wl->mutex);
546} 551}
547 552
@@ -566,6 +571,11 @@ static int wl1251_build_qos_null_data(struct wl1251 *wl)
566 sizeof(template)); 571 sizeof(template));
567} 572}
568 573
574static bool wl1251_can_do_pm(struct ieee80211_conf *conf, struct wl1251 *wl)
575{
576 return (conf->flags & IEEE80211_CONF_PS) && !wl->monitor_present;
577}
578
569static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) 579static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
570{ 580{
571 struct wl1251 *wl = hw->priv; 581 struct wl1251 *wl = hw->priv;
@@ -575,8 +585,10 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
575 channel = ieee80211_frequency_to_channel( 585 channel = ieee80211_frequency_to_channel(
576 conf->chandef.chan->center_freq); 586 conf->chandef.chan->center_freq);
577 587
578 wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d", 588 wl1251_debug(DEBUG_MAC80211,
589 "mac80211 config ch %d monitor %s psm %s power %d",
579 channel, 590 channel,
591 conf->flags & IEEE80211_CONF_MONITOR ? "on" : "off",
580 conf->flags & IEEE80211_CONF_PS ? "on" : "off", 592 conf->flags & IEEE80211_CONF_PS ? "on" : "off",
581 conf->power_level); 593 conf->power_level);
582 594
@@ -586,16 +598,44 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
586 if (ret < 0) 598 if (ret < 0)
587 goto out; 599 goto out;
588 600
601 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
602 u32 mode;
603
604 if (conf->flags & IEEE80211_CONF_MONITOR) {
605 wl->monitor_present = true;
606 mode = DF_SNIFF_MODE_ENABLE | DF_ENCRYPTION_DISABLE;
607 } else {
608 wl->monitor_present = false;
609 mode = 0;
610 }
611
612 ret = wl1251_acx_feature_cfg(wl, mode);
613 if (ret < 0)
614 goto out_sleep;
615 }
616
589 if (channel != wl->channel) { 617 if (channel != wl->channel) {
590 wl->channel = channel; 618 wl->channel = channel;
591 619
592 ret = wl1251_join(wl, wl->bss_type, wl->channel, 620 /*
593 wl->beacon_int, wl->dtim_period); 621 * Use ENABLE_RX command for channel switching when no
622 * interface is present (monitor mode only).
623 * This leaves the tx path disabled in firmware, whereas
624 * the usual JOIN command seems to transmit some frames
625 * at firmware level.
626 */
627 if (wl->vif == NULL) {
628 wl->joined = false;
629 ret = wl1251_cmd_data_path_rx(wl, wl->channel, 1);
630 } else {
631 ret = wl1251_join(wl, wl->bss_type, wl->channel,
632 wl->beacon_int, wl->dtim_period);
633 }
594 if (ret < 0) 634 if (ret < 0)
595 goto out_sleep; 635 goto out_sleep;
596 } 636 }
597 637
598 if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) { 638 if (wl1251_can_do_pm(conf, wl) && !wl->psm_requested) {
599 wl1251_debug(DEBUG_PSM, "psm enabled"); 639 wl1251_debug(DEBUG_PSM, "psm enabled");
600 640
601 wl->psm_requested = true; 641 wl->psm_requested = true;
@@ -611,8 +651,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
611 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 651 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
612 if (ret < 0) 652 if (ret < 0)
613 goto out_sleep; 653 goto out_sleep;
614 } else if (!(conf->flags & IEEE80211_CONF_PS) && 654 } else if (!wl1251_can_do_pm(conf, wl) && wl->psm_requested) {
615 wl->psm_requested) {
616 wl1251_debug(DEBUG_PSM, "psm disabled"); 655 wl1251_debug(DEBUG_PSM, "psm disabled");
617 656
618 wl->psm_requested = false; 657 wl->psm_requested = false;
@@ -648,6 +687,16 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
648 wl->power_level = conf->power_level; 687 wl->power_level = conf->power_level;
649 } 688 }
650 689
690 /*
691 * Tell stack that connection is lost because hw encryption isn't
692 * supported in monitor mode.
693 * This requires temporary enabling of the hw connection monitor flag
694 */
695 if ((changed & IEEE80211_CONF_CHANGE_MONITOR) && wl->vif) {
696 wl->hw->flags |= IEEE80211_HW_CONNECTION_MONITOR;
697 ieee80211_connection_loss(wl->vif);
698 }
699
651out_sleep: 700out_sleep:
652 wl1251_ps_elp_sleep(wl); 701 wl1251_ps_elp_sleep(wl);
653 702
@@ -657,6 +706,44 @@ out:
657 return ret; 706 return ret;
658} 707}
659 708
709struct wl1251_filter_params {
710 bool enabled;
711 int mc_list_length;
712 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
713};
714
715static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw,
716 struct netdev_hw_addr_list *mc_list)
717{
718 struct wl1251_filter_params *fp;
719 struct netdev_hw_addr *ha;
720 struct wl1251 *wl = hw->priv;
721
722 if (unlikely(wl->state == WL1251_STATE_OFF))
723 return 0;
724
725 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
726 if (!fp) {
727 wl1251_error("Out of memory setting filters.");
728 return 0;
729 }
730
731 /* update multicast filtering parameters */
732 fp->mc_list_length = 0;
733 if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
734 fp->enabled = false;
735 } else {
736 fp->enabled = true;
737 netdev_hw_addr_list_for_each(ha, mc_list) {
738 memcpy(fp->mc_list[fp->mc_list_length],
739 ha->addr, ETH_ALEN);
740 fp->mc_list_length++;
741 }
742 }
743
744 return (u64)(unsigned long)fp;
745}
746
660#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ 747#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
661 FIF_ALLMULTI | \ 748 FIF_ALLMULTI | \
662 FIF_FCSFAIL | \ 749 FIF_FCSFAIL | \
@@ -667,8 +754,9 @@ out:
667 754
668static void wl1251_op_configure_filter(struct ieee80211_hw *hw, 755static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
669 unsigned int changed, 756 unsigned int changed,
670 unsigned int *total,u64 multicast) 757 unsigned int *total, u64 multicast)
671{ 758{
759 struct wl1251_filter_params *fp = (void *)(unsigned long)multicast;
672 struct wl1251 *wl = hw->priv; 760 struct wl1251 *wl = hw->priv;
673 int ret; 761 int ret;
674 762
@@ -677,9 +765,11 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
677 *total &= WL1251_SUPPORTED_FILTERS; 765 *total &= WL1251_SUPPORTED_FILTERS;
678 changed &= WL1251_SUPPORTED_FILTERS; 766 changed &= WL1251_SUPPORTED_FILTERS;
679 767
680 if (changed == 0) 768 if (changed == 0) {
681 /* no filters which we support changed */ 769 /* no filters which we support changed */
770 kfree(fp);
682 return; 771 return;
772 }
683 773
684 mutex_lock(&wl->mutex); 774 mutex_lock(&wl->mutex);
685 775
@@ -716,6 +806,15 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
716 if (ret < 0) 806 if (ret < 0)
717 goto out; 807 goto out;
718 808
809 if (*total & FIF_ALLMULTI || *total & FIF_PROMISC_IN_BSS)
810 ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0);
811 else if (fp)
812 ret = wl1251_acx_group_address_tbl(wl, fp->enabled,
813 fp->mc_list,
814 fp->mc_list_length);
815 if (ret < 0)
816 goto out;
817
719 /* send filters to firmware */ 818 /* send filters to firmware */
720 wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); 819 wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
721 820
@@ -723,6 +822,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
723 822
724out: 823out:
725 mutex_unlock(&wl->mutex); 824 mutex_unlock(&wl->mutex);
825 kfree(fp);
726} 826}
727 827
728/* HW encryption */ 828/* HW encryption */
@@ -802,12 +902,12 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
802 902
803 mutex_lock(&wl->mutex); 903 mutex_lock(&wl->mutex);
804 904
805 ret = wl1251_ps_elp_wakeup(wl);
806 if (ret < 0)
807 goto out_unlock;
808
809 switch (cmd) { 905 switch (cmd) {
810 case SET_KEY: 906 case SET_KEY:
907 if (wl->monitor_present) {
908 ret = -EOPNOTSUPP;
909 goto out_unlock;
910 }
811 wl_cmd->key_action = KEY_ADD_OR_REPLACE; 911 wl_cmd->key_action = KEY_ADD_OR_REPLACE;
812 break; 912 break;
813 case DISABLE_KEY: 913 case DISABLE_KEY:
@@ -818,6 +918,10 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
818 break; 918 break;
819 } 919 }
820 920
921 ret = wl1251_ps_elp_wakeup(wl);
922 if (ret < 0)
923 goto out_unlock;
924
821 ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr); 925 ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
822 if (ret < 0) { 926 if (ret < 0) {
823 wl1251_error("Set KEY type failed"); 927 wl1251_error("Set KEY type failed");
@@ -930,6 +1034,7 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
930 ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels, 1034 ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
931 req->n_channels, WL1251_SCAN_NUM_PROBES); 1035 req->n_channels, WL1251_SCAN_NUM_PROBES);
932 if (ret < 0) { 1036 if (ret < 0) {
1037 wl1251_debug(DEBUG_SCAN, "scan failed %d", ret);
933 wl->scanning = false; 1038 wl->scanning = false;
934 goto out_idle; 1039 goto out_idle;
935 } 1040 }
@@ -977,6 +1082,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
977{ 1082{
978 struct wl1251 *wl = hw->priv; 1083 struct wl1251 *wl = hw->priv;
979 struct sk_buff *beacon, *skb; 1084 struct sk_buff *beacon, *skb;
1085 bool enable;
980 int ret; 1086 int ret;
981 1087
982 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1088 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1023,6 +1129,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1023 } 1129 }
1024 1130
1025 if (changed & BSS_CHANGED_ASSOC) { 1131 if (changed & BSS_CHANGED_ASSOC) {
1132 /* Disable temporary enabled hw connection monitor flag */
1133 wl->hw->flags &= ~IEEE80211_HW_CONNECTION_MONITOR;
1134
1026 if (bss_conf->assoc) { 1135 if (bss_conf->assoc) {
1027 wl->beacon_int = bss_conf->beacon_int; 1136 wl->beacon_int = bss_conf->beacon_int;
1028 1137
@@ -1075,6 +1184,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1075 } 1184 }
1076 } 1185 }
1077 1186
1187 if (changed & BSS_CHANGED_ARP_FILTER) {
1188 __be32 addr = bss_conf->arp_addr_list[0];
1189 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
1190
1191 enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
1192 wl1251_acx_arp_ip_filter(wl, enable, addr);
1193
1194 if (ret < 0)
1195 goto out_sleep;
1196 }
1197
1078 if (changed & BSS_CHANGED_BEACON) { 1198 if (changed & BSS_CHANGED_BEACON) {
1079 beacon = ieee80211_beacon_get(hw, vif); 1199 beacon = ieee80211_beacon_get(hw, vif);
1080 if (!beacon) 1200 if (!beacon)
@@ -1245,6 +1365,7 @@ static const struct ieee80211_ops wl1251_ops = {
1245 .add_interface = wl1251_op_add_interface, 1365 .add_interface = wl1251_op_add_interface,
1246 .remove_interface = wl1251_op_remove_interface, 1366 .remove_interface = wl1251_op_remove_interface,
1247 .config = wl1251_op_config, 1367 .config = wl1251_op_config,
1368 .prepare_multicast = wl1251_op_prepare_multicast,
1248 .configure_filter = wl1251_op_configure_filter, 1369 .configure_filter = wl1251_op_configure_filter,
1249 .tx = wl1251_op_tx, 1370 .tx = wl1251_op_tx,
1250 .set_key = wl1251_op_set_key, 1371 .set_key = wl1251_op_set_key,
@@ -1347,7 +1468,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1347 1468
1348 /* unit us */ 1469 /* unit us */
1349 /* FIXME: find a proper value */ 1470 /* FIXME: find a proper value */
1350 wl->hw->channel_change_time = 10000;
1351 1471
1352 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1472 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1353 IEEE80211_HW_SUPPORTS_PS | 1473 IEEE80211_HW_SUPPORTS_PS |
@@ -1401,7 +1521,10 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1401 1521
1402 INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); 1522 INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
1403 wl->channel = WL1251_DEFAULT_CHANNEL; 1523 wl->channel = WL1251_DEFAULT_CHANNEL;
1524 wl->monitor_present = false;
1525 wl->joined = false;
1404 wl->scanning = false; 1526 wl->scanning = false;
1527 wl->bss_type = MAX_BSS_TYPE;
1405 wl->default_key = 0; 1528 wl->default_key = 0;
1406 wl->listen_int = 1; 1529 wl->listen_int = 1;
1407 wl->rx_counter = 0; 1530 wl->rx_counter = 0;
@@ -1413,6 +1536,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1413 wl->elp = false; 1536 wl->elp = false;
1414 wl->station_mode = STATION_ACTIVE_MODE; 1537 wl->station_mode = STATION_ACTIVE_MODE;
1415 wl->psm_requested = false; 1538 wl->psm_requested = false;
1539 wl->psm_entry_retry = 0;
1416 wl->tx_queue_stopped = false; 1540 wl->tx_queue_stopped = false;
1417 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 1541 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
1418 wl->rssi_thold = 0; 1542 wl->rssi_thold = 0;
@@ -1478,3 +1602,4 @@ MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
1478MODULE_LICENSE("GPL"); 1602MODULE_LICENSE("GPL");
1479MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); 1603MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
1480MODULE_FIRMWARE(WL1251_FW_NAME); 1604MODULE_FIRMWARE(WL1251_FW_NAME);
1605MODULE_FIRMWARE(WL1251_NVS_NAME);
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 23289d49dd31..123c4bb50e0a 100644
--- a/drivers/net/wireless/ti/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
@@ -83,7 +83,7 @@ static void wl1251_rx_status(struct wl1251 *wl,
83 83
84 status->flag |= RX_FLAG_MACTIME_START; 84 status->flag |= RX_FLAG_MACTIME_START;
85 85
86 if (desc->flags & RX_DESC_ENCRYPTION_MASK) { 86 if (!wl->monitor_present && (desc->flags & RX_DESC_ENCRYPTION_MASK)) {
87 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; 87 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
88 88
89 if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL))) 89 if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 28121c590a2b..81de83c6fcf6 100644
--- a/drivers/net/wireless/ti/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
@@ -28,6 +28,7 @@
28#include "tx.h" 28#include "tx.h"
29#include "ps.h" 29#include "ps.h"
30#include "io.h" 30#include "io.h"
31#include "event.h"
31 32
32static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) 33static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
33{ 34{
@@ -89,8 +90,12 @@ static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
89 /* 802.11 packets */ 90 /* 802.11 packets */
90 tx_hdr->control.packet_type = 0; 91 tx_hdr->control.packet_type = 0;
91 92
92 if (control->flags & IEEE80211_TX_CTL_NO_ACK) 93 /* Also disable retry and ACK policy for injected packets */
94 if ((control->flags & IEEE80211_TX_CTL_NO_ACK) ||
95 (control->flags & IEEE80211_TX_CTL_INJECTED)) {
96 tx_hdr->control.rate_policy = 1;
93 tx_hdr->control.ack_policy = 1; 97 tx_hdr->control.ack_policy = 1;
98 }
94 99
95 tx_hdr->control.tx_complete = 1; 100 tx_hdr->control.tx_complete = 1;
96 101
@@ -277,6 +282,26 @@ static void wl1251_tx_trigger(struct wl1251 *wl)
277 TX_STATUS_DATA_OUT_COUNT_MASK; 282 TX_STATUS_DATA_OUT_COUNT_MASK;
278} 283}
279 284
285static void enable_tx_for_packet_injection(struct wl1251 *wl)
286{
287 int ret;
288
289 ret = wl1251_cmd_join(wl, BSS_TYPE_STA_BSS, wl->channel,
290 wl->beacon_int, wl->dtim_period);
291 if (ret < 0) {
292 wl1251_warning("join failed");
293 return;
294 }
295
296 ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
297 if (ret < 0) {
298 wl1251_warning("join timeout");
299 return;
300 }
301
302 wl->joined = true;
303}
304
280/* caller must hold wl->mutex */ 305/* caller must hold wl->mutex */
281static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) 306static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
282{ 307{
@@ -287,6 +312,9 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
287 info = IEEE80211_SKB_CB(skb); 312 info = IEEE80211_SKB_CB(skb);
288 313
289 if (info->control.hw_key) { 314 if (info->control.hw_key) {
315 if (unlikely(wl->monitor_present))
316 return -EINVAL;
317
290 idx = info->control.hw_key->hw_key_idx; 318 idx = info->control.hw_key->hw_key_idx;
291 if (unlikely(wl->default_key != idx)) { 319 if (unlikely(wl->default_key != idx)) {
292 ret = wl1251_acx_default_key(wl, idx); 320 ret = wl1251_acx_default_key(wl, idx);
@@ -295,6 +323,10 @@ static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
295 } 323 }
296 } 324 }
297 325
326 /* Enable tx path in monitor mode for packet injection */
327 if ((wl->vif == NULL) && !wl->joined)
328 enable_tx_for_packet_injection(wl);
329
298 ret = wl1251_tx_path_status(wl); 330 ret = wl1251_tx_path_status(wl);
299 if (ret < 0) 331 if (ret < 0)
300 return ret; 332 return ret;
@@ -394,6 +426,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl,
394 info = IEEE80211_SKB_CB(skb); 426 info = IEEE80211_SKB_CB(skb);
395 427
396 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && 428 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
429 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
397 (result->status == TX_SUCCESS)) 430 (result->status == TX_SUCCESS))
398 info->flags |= IEEE80211_TX_STAT_ACK; 431 info->flags |= IEEE80211_TX_STAT_ACK;
399 432
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 2c3bd1bff3f6..235617a7716d 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -93,6 +93,7 @@ enum {
93 } while (0) 93 } while (0)
94 94
95#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ 95#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
96 CFG_MC_FILTER_EN | \
96 CFG_BSSID_FILTER_EN) 97 CFG_BSSID_FILTER_EN)
97 98
98#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \ 99#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
@@ -303,6 +304,8 @@ struct wl1251 {
303 u8 bss_type; 304 u8 bss_type;
304 u8 listen_int; 305 u8 listen_int;
305 int channel; 306 int channel;
307 bool monitor_present;
308 bool joined;
306 309
307 void *target_mem_map; 310 void *target_mem_map;
308 struct acx_data_path_params_resp *data_path; 311 struct acx_data_path_params_resp *data_path;
@@ -368,6 +371,9 @@ struct wl1251 {
368 /* PSM mode requested */ 371 /* PSM mode requested */
369 bool psm_requested; 372 bool psm_requested;
370 373
374 /* retry counter for PSM entries */
375 u8 psm_entry_retry;
376
371 u16 beacon_int; 377 u16 beacon_int;
372 u8 dtim_period; 378 u8 dtim_period;
373 379
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index 4a0bbb13806b..7541bd1a4a4b 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -47,7 +47,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
47 * In active scans, we only scan channels not 47 * In active scans, we only scan channels not
48 * marked as passive. 48 * marked as passive.
49 */ 49 */
50 (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { 50 (passive || !(flags & IEEE80211_CHAN_NO_IR))) {
51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
52 req->channels[i]->band, 52 req->channels[i]->band,
53 req->channels[i]->center_freq); 53 req->channels[i]->center_freq);
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 34d9dfff2ad3..9b2ecf52449f 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1688,7 +1688,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1688 1688
1689 if (channel->flags & (IEEE80211_CHAN_DISABLED | 1689 if (channel->flags & (IEEE80211_CHAN_DISABLED |
1690 IEEE80211_CHAN_RADAR | 1690 IEEE80211_CHAN_RADAR |
1691 IEEE80211_CHAN_PASSIVE_SCAN)) 1691 IEEE80211_CHAN_NO_IR))
1692 continue; 1692 continue;
1693 1693
1694 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch); 1694 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 0368b9cbfb89..b46b3116cc55 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -91,8 +91,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
91 continue; 91 continue;
92 92
93 if (ch->flags & IEEE80211_CHAN_RADAR) 93 if (ch->flags & IEEE80211_CHAN_RADAR)
94 ch->flags |= IEEE80211_CHAN_NO_IBSS | 94 ch->flags |= IEEE80211_CHAN_NO_IR;
95 IEEE80211_CHAN_PASSIVE_SCAN;
96 95
97 } 96 }
98 97
@@ -4458,6 +4457,16 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
4458 if (ret < 0) 4457 if (ret < 0)
4459 goto out; 4458 goto out;
4460 4459
4460 if ((changed & BSS_CHANGED_TXPOWER) &&
4461 bss_conf->txpower != wlvif->power_level) {
4462
4463 ret = wl1271_acx_tx_power(wl, wlvif, bss_conf->txpower);
4464 if (ret < 0)
4465 goto out;
4466
4467 wlvif->power_level = bss_conf->txpower;
4468 }
4469
4461 if (is_ap) 4470 if (is_ap)
4462 wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed); 4471 wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed);
4463 else 4472 else
@@ -5711,7 +5720,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5711 5720
5712 /* unit us */ 5721 /* unit us */
5713 /* FIXME: find a proper value */ 5722 /* FIXME: find a proper value */
5714 wl->hw->channel_change_time = 10000;
5715 wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; 5723 wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
5716 5724
5717 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 5725 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index 7ed86203304b..1e3d51cd673a 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -188,16 +188,14 @@ wlcore_scan_get_channels(struct wl1271 *wl,
188 flags = req_channels[i]->flags; 188 flags = req_channels[i]->flags;
189 189
190 if (force_passive) 190 if (force_passive)
191 flags |= IEEE80211_CHAN_PASSIVE_SCAN; 191 flags |= IEEE80211_CHAN_NO_IR;
192 192
193 if ((req_channels[i]->band == band) && 193 if ((req_channels[i]->band == band) &&
194 !(flags & IEEE80211_CHAN_DISABLED) && 194 !(flags & IEEE80211_CHAN_DISABLED) &&
195 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 195 (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
196 /* if radar is set, we ignore the passive flag */ 196 /* if radar is set, we ignore the passive flag */
197 (radar || 197 (radar ||
198 !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { 198 !!(flags & IEEE80211_CHAN_NO_IR) == passive)) {
199
200
201 if (flags & IEEE80211_CHAN_RADAR) { 199 if (flags & IEEE80211_CHAN_RADAR) {
202 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 200 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
203 201
@@ -220,7 +218,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
220 (band == IEEE80211_BAND_2GHZ) && 218 (band == IEEE80211_BAND_2GHZ) &&
221 (channels[j].channel >= 12) && 219 (channels[j].channel >= 12) &&
222 (channels[j].channel <= 14) && 220 (channels[j].channel <= 14) &&
223 (flags & IEEE80211_CHAN_PASSIVE_SCAN) && 221 (flags & IEEE80211_CHAN_NO_IR) &&
224 !force_passive) { 222 !force_passive) {
225 /* pactive channels treated as DFS */ 223 /* pactive channels treated as DFS */
226 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; 224 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS;
@@ -243,8 +241,8 @@ wlcore_scan_get_channels(struct wl1271 *wl,
243 max_dwell_time_active, 241 max_dwell_time_active,
244 flags & IEEE80211_CHAN_RADAR ? 242 flags & IEEE80211_CHAN_RADAR ?
245 ", DFS" : "", 243 ", DFS" : "",
246 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 244 flags & IEEE80211_CHAN_NO_IR ?
247 ", PASSIVE" : ""); 245 ", NO-IR" : "");
248 j++; 246 j++;
249 } 247 }
250 } 248 }
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 38d2089f338a..d24d4a958c67 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/init.h>
33#include <linux/interrupt.h> 32#include <linux/interrupt.h>
34#include <linux/in.h> 33#include <linux/in.h>
35#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -44,6 +43,7 @@
44#include <linux/string.h> 43#include <linux/string.h>
45#include <linux/wireless.h> 44#include <linux/wireless.h>
46#include <linux/ieee80211.h> 45#include <linux/ieee80211.h>
46#include <linux/etherdevice.h>
47 47
48#include <net/iw_handler.h> 48#include <net/iw_handler.h>
49 49
@@ -673,8 +673,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
673 matchflag = 1; 673 matchflag = 1;
674 if (matchflag) { 674 if (matchflag) {
675 for (i = 0; i < this->bss_cnt; i++) { 675 for (i = 0; i < this->bss_cnt; i++) {
676 if (!memcmp(this->bss_set[i].bssid, 676 if (ether_addr_equal_unaligned(this->bss_set[i].bssid, sig.bssid)) {
677 sig.bssid, ETH_ALEN)) {
678 matchflag = 0; 677 matchflag = 0;
679 break; 678 break;
680 } 679 }
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 71ab320fae82..73a49b868035 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21/* This file implements all the hardware specific functions for the ZD1211 20/* This file implements all the hardware specific functions for the ZD1211
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 7ab922209b25..b03786c9f3aa 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#ifndef _ZD_CHIP_H 20#ifndef _ZD_CHIP_H
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 9a1b013f81be..41bd755bc135 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#ifndef _ZD_DEF_H 20#ifndef _ZD_DEF_H
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index c6208a7988e4..e7af261e9198 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -16,8 +16,7 @@
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 20 */
22 21
23#include <linux/netdevice.h> 22#include <linux/netdevice.h>
@@ -533,9 +532,8 @@ void zd_mac_tx_failed(struct urb *urb)
533 tx_hdr = (struct ieee80211_hdr *)skb->data; 532 tx_hdr = (struct ieee80211_hdr *)skb->data;
534 533
535 /* we skip all frames not matching the reported destination */ 534 /* we skip all frames not matching the reported destination */
536 if (unlikely(memcmp(tx_hdr->addr1, tx_status->mac, ETH_ALEN))) { 535 if (unlikely(!ether_addr_equal(tx_hdr->addr1, tx_status->mac)))
537 continue; 536 continue;
538 }
539 537
540 /* we skip all frames not matching the reported final rate */ 538 /* we skip all frames not matching the reported final rate */
541 539
@@ -998,7 +996,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
998 continue; 996 continue;
999 997
1000 tx_hdr = (struct ieee80211_hdr *)skb->data; 998 tx_hdr = (struct ieee80211_hdr *)skb->data;
1001 if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN))) 999 if (likely(ether_addr_equal(tx_hdr->addr2, rx_hdr->addr1)))
1002 { 1000 {
1003 found = 1; 1001 found = 1;
1004 break; 1002 break;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index c01eca859f95..5a484235308f 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#ifndef _ZD_MAC_H 20#ifndef _ZD_MAC_H
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index c875ee05e22e..dc179c414518 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#include <linux/errno.h> 20#include <linux/errno.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index 725b7c99b23d..8f14e25e1041 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#ifndef _ZD_RF_H 20#ifndef _ZD_RF_H
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 12babcb633c3..99aed7d78952 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#include <linux/kernel.h> 20#include <linux/kernel.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index 385c670d1293..5fea485be574 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#include <linux/kernel.h> 20#include <linux/kernel.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index 784d9ccb8fef..a93f657a41c7 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#include <linux/kernel.h> 20#include <linux/kernel.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index c4d324e19c24..61b924027356 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#include <linux/kernel.h> 20#include <linux/kernel.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 84d94f572a46..a912dc051111 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -15,8 +15,7 @@
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 19 */
21 20
22#include <linux/kernel.h> 21#include <linux/kernel.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 45e3bb28a01c..a9075f225178 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -14,8 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 18 */
20 19
21#ifndef _ZD_USB_H 20#ifndef _ZD_USB_H