aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
commitf8965467f366fd18f01feafb5db10512d7b4422c (patch)
tree3706a9cd779859271ca61b85c63a1bc3f82d626e /drivers/net/wireless
parenta26272e5200765691e67d6780e52b32498fdb659 (diff)
parent2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits) qlcnic: adding co maintainer ixgbe: add support for active DA cables ixgbe: dcb, do not tag tc_prio_control frames ixgbe: fix ixgbe_tx_is_paused logic ixgbe: always enable vlan strip/insert when DCB is enabled ixgbe: remove some redundant code in setting FCoE FIP filter ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp ixgbe: fix header len when unsplit packet overflows to data buffer ipv6: Never schedule DAD timer on dead address ipv6: Use POSTDAD state ipv6: Use state_lock to protect ifa state ipv6: Replace inet6_ifaddr->dead with state cxgb4: notify upper drivers if the device is already up when they load cxgb4: keep interrupts available when the ports are brought down cxgb4: fix initial addition of MAC address cnic: Return SPQ credit to bnx2x after ring setup and shutdown. cnic: Convert cnic_local_flags to atomic ops. can: Fix SJA1000 command register writes on SMP systems bridge: fix build for CONFIG_SYSFS disabled ARCNET: Limit com20020 PCI ID matches for SOHARD cards ... Fix up various conflicts with pcmcia tree drivers/net/ {pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and wireless/orinoco/spectrum_cs.c} and feature removal (Documentation/feature-removal-schedule.txt). Also fix a non-content conflict due to pm_qos_requirement getting renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig92
-rw-r--r--drivers/net/wireless/adm8211.c12
-rw-r--r--drivers/net/wireless/airo.c37
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/ath/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h52
-rw-r--r--drivers/net/wireless/ath/ar9170/cmd.h2
-rw-r--r--drivers/net/wireless/ath/ar9170/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h1
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c587
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c17
-rw-r--r--drivers/net/wireless/ath/ath.h27
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c744
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h104
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h313
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c329
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h39
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c382
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c19
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h35
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h88
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c379
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c77
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c17
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h42
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c41
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile26
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c217
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_initvals.h742
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c1374
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9001_initvals.h1254
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c1000
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c598
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h (renamed from drivers/net/wireless/ath/ath9k/initvals.h)2292
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c480
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c535
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h572
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c802
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c1838
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h323
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c205
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_initvals.h1784
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c614
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h120
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c1134
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h847
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h28
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c1024
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h19
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c392
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c297
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c1008
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h104
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h464
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c255
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c834
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1775
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c707
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c480
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h245
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h280
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c1913
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h275
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c88
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c571
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h93
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c158
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c978
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h596
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c533
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h183
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c336
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h139
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c591
-rw-r--r--drivers/net/wireless/ath/debug.h1
-rw-r--r--drivers/net/wireless/ath/hw.c4
-rw-r--r--drivers/net/wireless/ath/regd.c4
-rw-r--r--drivers/net/wireless/atmel.c1
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/main.c26
-rw-r--r--drivers/net/wireless/b43/phy_n.c479
-rw-r--r--drivers/net/wireless/b43/phy_n.h21
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c22
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h37
-rw-r--r--drivers/net/wireless/b43/xmit.c1
-rw-r--r--drivers/net/wireless/b43legacy/main.c21
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c3
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c49
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c190
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h14
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c13
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c102
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c500
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c361
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c198
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1493
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c331
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c850
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c276
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h118
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ict.c307
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c1530
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c208
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c1340
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c425
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1021
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h181
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h116
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1021
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h136
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c912
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h288
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h94
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c826
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c536
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c901
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1074
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c406
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/bus.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c17
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c14
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debug.h7
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c123
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c15
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.h5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c79
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c19
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.h283
-rw-r--r--drivers/net/wireless/iwmc3200wifi/tx.c12
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h2
-rw-r--r--drivers/net/wireless/libertas/assoc.c22
-rw-r--r--drivers/net/wireless/libertas/cfg.c1
-rw-r--r--drivers/net/wireless/libertas/debugfs.c5
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c127
-rw-r--r--drivers/net/wireless/libertas/if_usb.c4
-rw-r--r--drivers/net/wireless/libertas/main.c15
-rw-r--r--drivers/net/wireless/libertas/rx.c51
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c4
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c203
-rw-r--r--drivers/net/wireless/libertas_tf/deb_defs.h104
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c252
-rw-r--r--drivers/net/wireless/libertas_tf/libertas_tf.h2
-rw-r--r--drivers/net/wireless/libertas_tf/main.c106
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c96
-rw-r--r--drivers/net/wireless/mwl8k.c30
-rw-r--r--drivers/net/wireless/orinoco/Kconfig20
-rw-r--r--drivers/net/wireless/orinoco/Makefile4
-rw-r--r--drivers/net/wireless/orinoco/airport.c8
-rw-r--r--drivers/net/wireless/orinoco/cfg.c91
-rw-r--r--drivers/net/wireless/orinoco/fw.c10
-rw-r--r--drivers/net/wireless/orinoco/hermes.c286
-rw-r--r--drivers/net/wireless/orinoco/hermes.h62
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c243
-rw-r--r--drivers/net/wireless/orinoco/hw.c102
-rw-r--r--drivers/net/wireless/orinoco/hw.h1
-rw-r--r--drivers/net/wireless/orinoco/main.c307
-rw-r--r--drivers/net/wireless/orinoco/main.h12
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h38
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c85
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1795
-rw-r--r--drivers/net/wireless/orinoco/scan.c4
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c7
-rw-r--r--drivers/net/wireless/orinoco/wext.c273
-rw-r--r--drivers/net/wireless/p54/main.c2
-rw-r--r--drivers/net/wireless/p54/p54pci.c10
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/p54/txrx.c3
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c18
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c10
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c8
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c2
-rw-r--r--drivers/net/wireless/ray_cs.c242
-rw-r--r--drivers/net/wireless/rndis_wlan.c374
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c54
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c130
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h119
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c676
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c318
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c297
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h35
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c47
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c95
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c128
-rw-r--r--drivers/net/wireless/rtl818x/Kconfig88
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180.h11
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c115
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c14
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig24
-rw-r--r--drivers/net/wireless/wl12xx/Makefile6
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.h20
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c73
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_reg.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c144
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h63
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c179
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h157
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c46
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h10
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c337
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h27
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h488
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c69
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c57
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.c87
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h139
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1272
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c94
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c291
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c315
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.h96
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c133
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h9
-rw-r--r--drivers/net/wireless/wl3501_cs.c57
-rw-r--r--drivers/net/wireless/zd1201.c12
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c13
301 files changed, 44078 insertions, 19948 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 588943660755..174e3442d519 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -5,6 +5,7 @@
5menuconfig WLAN 5menuconfig WLAN
6 bool "Wireless LAN" 6 bool "Wireless LAN"
7 depends on !S390 7 depends on !S390
8 depends on NET
8 select WIRELESS 9 select WIRELESS
9 default y 10 default y
10 ---help--- 11 ---help---
@@ -38,6 +39,12 @@ config LIBERTAS_THINFIRM
38 ---help--- 39 ---help---
39 A library for Marvell Libertas 8xxx devices using thinfirm. 40 A library for Marvell Libertas 8xxx devices using thinfirm.
40 41
42config LIBERTAS_THINFIRM_DEBUG
43 bool "Enable full debugging output in the Libertas thin firmware module."
44 depends on LIBERTAS_THINFIRM
45 ---help---
46 Debugging support.
47
41config LIBERTAS_THINFIRM_USB 48config LIBERTAS_THINFIRM_USB
42 tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" 49 tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware"
43 depends on LIBERTAS_THINFIRM && USB 50 depends on LIBERTAS_THINFIRM && USB
@@ -210,90 +217,7 @@ config USB_NET_RNDIS_WLAN
210 217
211 If you choose to build a module, it'll be called rndis_wlan. 218 If you choose to build a module, it'll be called rndis_wlan.
212 219
213config RTL8180 220source "drivers/net/wireless/rtl818x/Kconfig"
214 tristate "Realtek 8180/8185 PCI support"
215 depends on MAC80211 && PCI && EXPERIMENTAL
216 select EEPROM_93CX6
217 ---help---
218 This is a driver for RTL8180 and RTL8185 based cards.
219 These are PCI based chips found in cards such as:
220
221 (RTL8185 802.11g)
222 A-Link WL54PC
223
224 (RTL8180 802.11b)
225 Belkin F5D6020 v3
226 Belkin F5D6020 v3
227 Dlink DWL-610
228 Dlink DWL-510
229 Netgear MA521
230 Level-One WPC-0101
231 Acer Aspire 1357 LMi
232 VCTnet PC-11B1
233 Ovislink AirLive WL-1120PCM
234 Mentor WL-PCI
235 Linksys WPC11 v4
236 TrendNET TEW-288PI
237 D-Link DWL-520 Rev D
238 Repotec RP-WP7126
239 TP-Link TL-WN250/251
240 Zonet ZEW1000
241 Longshine LCS-8031-R
242 HomeLine HLW-PCC200
243 GigaFast WF721-AEX
244 Planet WL-3553
245 Encore ENLWI-PCI1-NT
246 TrendNET TEW-266PC
247 Gigabyte GN-WLMR101
248 Siemens-fujitsu Amilo D1840W
249 Edimax EW-7126
250 PheeNet WL-11PCIR
251 Tonze PC-2100T
252 Planet WL-8303
253 Dlink DWL-650 v M1
254 Edimax EW-7106
255 Q-Tec 770WC
256 Topcom Skyr@cer 4011b
257 Roper FreeLan 802.11b (edition 2004)
258 Wistron Neweb Corp CB-200B
259 Pentagram HorNET
260 QTec 775WC
261 TwinMOS Booming B Series
262 Micronet SP906BB
263 Sweex LC700010
264 Surecom EP-9428
265 Safecom SWLCR-1100
266
267 Thanks to Realtek for their support!
268
269config RTL8187
270 tristate "Realtek 8187 and 8187B USB support"
271 depends on MAC80211 && USB
272 select EEPROM_93CX6
273 ---help---
274 This is a driver for RTL8187 and RTL8187B based cards.
275 These are USB based chips found in devices such as:
276
277 Netgear WG111v2
278 Level 1 WNC-0301USB
279 Micronet SP907GK V5
280 Encore ENUWI-G2
281 Trendnet TEW-424UB
282 ASUS P5B Deluxe/P5K Premium motherboards
283 Toshiba Satellite Pro series of laptops
284 Asus Wireless Link
285 Linksys WUSB54GC-EU v2
286 (v1 = rt73usb; v3 is rt2070-based,
287 use staging/rt3070 or try rt2800usb)
288
289 Thanks to Realtek for their support!
290
291# If possible, automatically enable LEDs for RTL8187.
292
293config RTL8187_LEDS
294 bool
295 depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
296 default y
297 221
298config ADM8211 222config ADM8211
299 tristate "ADMtek ADM8211 support" 223 tristate "ADMtek ADM8211 support"
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index ab61d2b558d6..880ad9d170c2 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1318,21 +1318,19 @@ static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
1318} 1318}
1319 1319
1320static u64 adm8211_prepare_multicast(struct ieee80211_hw *hw, 1320static u64 adm8211_prepare_multicast(struct ieee80211_hw *hw,
1321 int mc_count, struct dev_addr_list *mclist) 1321 struct netdev_hw_addr_list *mc_list)
1322{ 1322{
1323 unsigned int bit_nr, i; 1323 unsigned int bit_nr;
1324 u32 mc_filter[2]; 1324 u32 mc_filter[2];
1325 struct netdev_hw_addr *ha;
1325 1326
1326 mc_filter[1] = mc_filter[0] = 0; 1327 mc_filter[1] = mc_filter[0] = 0;
1327 1328
1328 for (i = 0; i < mc_count; i++) { 1329 netdev_hw_addr_list_for_each(ha, mc_list) {
1329 if (!mclist) 1330 bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
1330 break;
1331 bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1332 1331
1333 bit_nr &= 0x3F; 1332 bit_nr &= 0x3F;
1334 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); 1333 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1335 mclist = mclist->next;
1336 } 1334 }
1337 1335
1338 return mc_filter[0] | ((u64)(mc_filter[1]) << 32); 1336 return mc_filter[0] | ((u64)(mc_filter[1]) << 32);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index dc5018a6d9ed..a441aad922c2 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2876,7 +2876,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2876 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0; 2876 ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2877 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0; 2877 ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2878 2878
2879 airo_print_info(dev->name, "Firmware version %x.%x.%02x", 2879 airo_print_info(dev->name, "Firmware version %x.%x.%02d",
2880 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF), 2880 ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2881 (le16_to_cpu(cap_rid.softVer) & 0xFF), 2881 (le16_to_cpu(cap_rid.softVer) & 0xFF),
2882 le16_to_cpu(cap_rid.softSubVer)); 2882 le16_to_cpu(cap_rid.softSubVer));
@@ -3193,19 +3193,26 @@ static void airo_print_status(const char *devname, u16 status)
3193{ 3193{
3194 u8 reason = status & 0xFF; 3194 u8 reason = status & 0xFF;
3195 3195
3196 switch (status) { 3196 switch (status & 0xFF00) {
3197 case STAT_NOBEACON: 3197 case STAT_NOBEACON:
3198 airo_print_dbg(devname, "link lost (missed beacons)"); 3198 switch (status) {
3199 break; 3199 case STAT_NOBEACON:
3200 case STAT_MAXRETRIES: 3200 airo_print_dbg(devname, "link lost (missed beacons)");
3201 case STAT_MAXARL: 3201 break;
3202 airo_print_dbg(devname, "link lost (max retries)"); 3202 case STAT_MAXRETRIES:
3203 break; 3203 case STAT_MAXARL:
3204 case STAT_FORCELOSS: 3204 airo_print_dbg(devname, "link lost (max retries)");
3205 airo_print_dbg(devname, "link lost (local choice)"); 3205 break;
3206 break; 3206 case STAT_FORCELOSS:
3207 case STAT_TSFSYNC: 3207 airo_print_dbg(devname, "link lost (local choice)");
3208 airo_print_dbg(devname, "link lost (TSF sync lost)"); 3208 break;
3209 case STAT_TSFSYNC:
3210 airo_print_dbg(devname, "link lost (TSF sync lost)");
3211 break;
3212 default:
3213 airo_print_dbg(devname, "unknow status %x\n", status);
3214 break;
3215 }
3209 break; 3216 break;
3210 case STAT_DEAUTH: 3217 case STAT_DEAUTH:
3211 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason); 3218 airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
@@ -3221,7 +3228,11 @@ static void airo_print_status(const char *devname, u16 status)
3221 airo_print_dbg(devname, "authentication failed (reason: %d)", 3228 airo_print_dbg(devname, "authentication failed (reason: %d)",
3222 reason); 3229 reason);
3223 break; 3230 break;
3231 case STAT_ASSOC:
3232 case STAT_REASSOC:
3233 break;
3224 default: 3234 default:
3235 airo_print_dbg(devname, "unknow status %x\n", status);
3225 break; 3236 break;
3226 } 3237 }
3227} 3238}
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 0fb419936dff..8a2d4afc74f8 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1223,7 +1223,6 @@ static void at76_rx_callback(struct urb *urb)
1223 1223
1224 priv->rx_tasklet.data = (unsigned long)urb; 1224 priv->rx_tasklet.data = (unsigned long)urb;
1225 tasklet_schedule(&priv->rx_tasklet); 1225 tasklet_schedule(&priv->rx_tasklet);
1226 return;
1227} 1226}
1228 1227
1229static int at76_submit_rx_urb(struct at76_priv *priv) 1228static int at76_submit_rx_urb(struct at76_priv *priv)
@@ -1889,6 +1888,7 @@ static void at76_dwork_hw_scan(struct work_struct *work)
1889} 1888}
1890 1889
1891static int at76_hw_scan(struct ieee80211_hw *hw, 1890static int at76_hw_scan(struct ieee80211_hw *hw,
1891 struct ieee80211_vif *vif,
1892 struct cfg80211_scan_request *req) 1892 struct cfg80211_scan_request *req)
1893{ 1893{
1894 struct at76_priv *priv = hw->priv; 1894 struct at76_priv *priv = hw->priv;
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 4e7a7fd695c8..0a75be027afa 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This will enable the support for the Atheros wireless drivers. 5 This will enable the support for the Atheros wireless drivers.
6 ath5k, ath9k and ar9170 drivers share some common code, this option 6 ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
7 enables the common ath.ko module which shares common helpers. 7 enables the common ath.ko module which shares common helpers.
8 8
9 For more information and documentation on this module you can visit: 9 For more information and documentation on this module you can visit:
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index dc662b76a1c8..4f845f80c098 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -109,41 +109,6 @@ struct ar9170_rxstream_mpdu_merge {
109 bool has_plcp; 109 bool has_plcp;
110}; 110};
111 111
112#define AR9170_NUM_TID 16
113#define WME_BA_BMP_SIZE 64
114#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE)
115
116#define WME_AC_BE 2
117#define WME_AC_BK 3
118#define WME_AC_VI 1
119#define WME_AC_VO 0
120
121#define TID_TO_WME_AC(_tid) \
122 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
123 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
124 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
125 WME_AC_VO)
126
127#define BAW_WITHIN(_start, _bawsz, _seqno) \
128 ((((_seqno) - (_start)) & 0xfff) < (_bawsz))
129
130enum ar9170_tid_state {
131 AR9170_TID_STATE_INVALID,
132 AR9170_TID_STATE_SHUTDOWN,
133 AR9170_TID_STATE_PROGRESS,
134 AR9170_TID_STATE_COMPLETE,
135};
136
137struct ar9170_sta_tid {
138 struct list_head list;
139 struct sk_buff_head queue;
140 u8 addr[ETH_ALEN];
141 u16 ssn;
142 u16 tid;
143 enum ar9170_tid_state state;
144 bool active;
145};
146
147struct ar9170_tx_queue_stats { 112struct ar9170_tx_queue_stats {
148 unsigned int len; 113 unsigned int len;
149 unsigned int limit; 114 unsigned int limit;
@@ -152,14 +117,11 @@ struct ar9170_tx_queue_stats {
152 117
153#define AR9170_QUEUE_TIMEOUT 64 118#define AR9170_QUEUE_TIMEOUT 64
154#define AR9170_TX_TIMEOUT 8 119#define AR9170_TX_TIMEOUT 8
155#define AR9170_BA_TIMEOUT 4
156#define AR9170_JANITOR_DELAY 128 120#define AR9170_JANITOR_DELAY 128
157#define AR9170_TX_INVALID_RATE 0xffffffff 121#define AR9170_TX_INVALID_RATE 0xffffffff
158 122
159#define AR9170_NUM_TX_STATUS 128 123#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
160#define AR9170_NUM_TX_AGG_MAX 30 124#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
161#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH
162#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10)
163 125
164struct ar9170 { 126struct ar9170 {
165 struct ieee80211_hw *hw; 127 struct ieee80211_hw *hw;
@@ -234,11 +196,6 @@ struct ar9170 {
234 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; 196 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
235 struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; 197 struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
236 struct delayed_work tx_janitor; 198 struct delayed_work tx_janitor;
237 /* tx ampdu */
238 struct sk_buff_head tx_status_ampdu;
239 spinlock_t tx_ampdu_list_lock;
240 struct list_head tx_ampdu_list;
241 atomic_t tx_ampdu_pending;
242 199
243 /* rxstream mpdu merge */ 200 /* rxstream mpdu merge */
244 struct ar9170_rxstream_mpdu_merge rx_mpdu; 201 struct ar9170_rxstream_mpdu_merge rx_mpdu;
@@ -250,11 +207,6 @@ struct ar9170 {
250 u8 global_ampdu_factor; 207 u8 global_ampdu_factor;
251}; 208};
252 209
253struct ar9170_sta_info {
254 struct ar9170_sta_tid agg[AR9170_NUM_TID];
255 unsigned int ampdu_max_len;
256};
257
258struct ar9170_tx_info { 210struct ar9170_tx_info {
259 unsigned long timeout; 211 unsigned long timeout;
260}; 212};
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
index 826c45e6b274..ec8134b4b949 100644
--- a/drivers/net/wireless/ath/ar9170/cmd.h
+++ b/drivers/net/wireless/ath/ar9170/cmd.h
@@ -79,7 +79,7 @@ __regwrite_out : \
79 if (__nreg) { \ 79 if (__nreg) { \
80 if (IS_ACCEPTING_CMD(__ar)) \ 80 if (IS_ACCEPTING_CMD(__ar)) \
81 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ 81 __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
82 8 * __nreg, \ 82 8 * __nreg, \
83 (u8 *) &__ar->cmdbuf[1], \ 83 (u8 *) &__ar->cmdbuf[1], \
84 0, NULL); \ 84 0, NULL); \
85 __nreg = 0; \ 85 __nreg = 0; \
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
index d2c8cc83f1dd..6c4663883423 100644
--- a/drivers/net/wireless/ath/ar9170/eeprom.h
+++ b/drivers/net/wireless/ath/ar9170/eeprom.h
@@ -127,8 +127,8 @@ struct ar9170_eeprom {
127 __le16 checksum; 127 __le16 checksum;
128 __le16 version; 128 __le16 version;
129 u8 operating_flags; 129 u8 operating_flags;
130#define AR9170_OPFLAG_5GHZ 1 130#define AR9170_OPFLAG_5GHZ 1
131#define AR9170_OPFLAG_2GHZ 2 131#define AR9170_OPFLAG_2GHZ 2
132 u8 misc; 132 u8 misc;
133 __le16 reg_domain[2]; 133 __le16 reg_domain[2];
134 u8 mac_address[6]; 134 u8 mac_address[6];
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 0a1d4c28e68a..06f1f3c951a4 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -425,5 +425,6 @@ enum ar9170_txq {
425 425
426#define AR9170_TXQ_DEPTH 32 426#define AR9170_TXQ_DEPTH 32
427#define AR9170_TX_MAX_PENDING 128 427#define AR9170_TX_MAX_PENDING 128
428#define AR9170_RX_STREAM_MAX_SIZE 65535
428 429
429#endif /* __AR9170_HW_H */ 430#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index c53692980990..2abc87578994 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -50,10 +50,6 @@ static int modparam_nohwcrypt;
50module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 50module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
51MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 51MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
52 52
53static int modparam_ht;
54module_param_named(ht, modparam_ht, bool, S_IRUGO);
55MODULE_PARM_DESC(ht, "enable MPDU aggregation.");
56
57#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ 53#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
58 .bitrate = (_bitrate), \ 54 .bitrate = (_bitrate), \
59 .flags = (_flags), \ 55 .flags = (_flags), \
@@ -182,7 +178,6 @@ static struct ieee80211_supported_band ar9170_band_5GHz = {
182}; 178};
183 179
184static void ar9170_tx(struct ar9170 *ar); 180static void ar9170_tx(struct ar9170 *ar);
185static bool ar9170_tx_ampdu(struct ar9170 *ar);
186 181
187static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr) 182static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
188{ 183{
@@ -195,21 +190,7 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb)
195 return ar9170_get_seq_h((void *) txc->frame_data); 190 return ar9170_get_seq_h((void *) txc->frame_data);
196} 191}
197 192
198static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr) 193#ifdef AR9170_QUEUE_DEBUG
199{
200 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
201}
202
203static inline u16 ar9170_get_tid(struct sk_buff *skb)
204{
205 struct ar9170_tx_control *txc = (void *) skb->data;
206 return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data);
207}
208
209#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
210#define GET_NEXT_SEQ_FROM_SKB(skb) (GET_NEXT_SEQ(ar9170_get_seq(skb)))
211
212#if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG)
213static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) 194static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
214{ 195{
215 struct ar9170_tx_control *txc = (void *) skb->data; 196 struct ar9170_tx_control *txc = (void *) skb->data;
@@ -236,7 +217,7 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
236 wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); 217 wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
237 218
238 skb_queue_walk(queue, skb) { 219 skb_queue_walk(queue, skb) {
239 printk(KERN_DEBUG "index:%d => \n", i++); 220 printk(KERN_DEBUG "index:%d =>\n", i++);
240 ar9170_print_txheader(ar, skb); 221 ar9170_print_txheader(ar, skb);
241 } 222 }
242 if (i != skb_queue_len(queue)) 223 if (i != skb_queue_len(queue))
@@ -244,7 +225,7 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
244 "mismatch %d != %d\n", skb_queue_len(queue), i); 225 "mismatch %d != %d\n", skb_queue_len(queue), i);
245 printk(KERN_DEBUG "---[ end ]---\n"); 226 printk(KERN_DEBUG "---[ end ]---\n");
246} 227}
247#endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */ 228#endif /* AR9170_QUEUE_DEBUG */
248 229
249#ifdef AR9170_QUEUE_DEBUG 230#ifdef AR9170_QUEUE_DEBUG
250static void ar9170_dump_txqueue(struct ar9170 *ar, 231static void ar9170_dump_txqueue(struct ar9170 *ar,
@@ -275,20 +256,6 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
275} 256}
276#endif /* AR9170_QUEUE_STOP_DEBUG */ 257#endif /* AR9170_QUEUE_STOP_DEBUG */
277 258
278#ifdef AR9170_TXAGG_DEBUG
279static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
280{
281 unsigned long flags;
282
283 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
284 printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n",
285 wiphy_name(ar->hw->wiphy));
286 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
287 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
288}
289
290#endif /* AR9170_TXAGG_DEBUG */
291
292/* caller must guarantee exclusive access for _bin_ queue. */ 259/* caller must guarantee exclusive access for _bin_ queue. */
293static void ar9170_recycle_expired(struct ar9170 *ar, 260static void ar9170_recycle_expired(struct ar9170 *ar,
294 struct sk_buff_head *queue, 261 struct sk_buff_head *queue,
@@ -308,7 +275,7 @@ static void ar9170_recycle_expired(struct ar9170 *ar,
308 if (time_is_before_jiffies(arinfo->timeout)) { 275 if (time_is_before_jiffies(arinfo->timeout)) {
309#ifdef AR9170_QUEUE_DEBUG 276#ifdef AR9170_QUEUE_DEBUG
310 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " 277 printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
311 "recycle \n", wiphy_name(ar->hw->wiphy), 278 "recycle\n", wiphy_name(ar->hw->wiphy),
312 jiffies, arinfo->timeout); 279 jiffies, arinfo->timeout);
313 ar9170_print_txheader(ar, skb); 280 ar9170_print_txheader(ar, skb);
314#endif /* AR9170_QUEUE_DEBUG */ 281#endif /* AR9170_QUEUE_DEBUG */
@@ -360,70 +327,6 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
360 ieee80211_tx_status_irqsafe(ar->hw, skb); 327 ieee80211_tx_status_irqsafe(ar->hw, skb);
361} 328}
362 329
363static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
364{
365 struct sk_buff_head success;
366 struct sk_buff *skb;
367 unsigned int i;
368 unsigned long queue_bitmap = 0;
369
370 skb_queue_head_init(&success);
371
372 while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS)
373 __skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu));
374
375 ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success);
376
377#ifdef AR9170_TXAGG_DEBUG
378 printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n",
379 wiphy_name(ar->hw->wiphy), skb_queue_len(&success));
380 __ar9170_dump_txqueue(ar, &success);
381#endif /* AR9170_TXAGG_DEBUG */
382
383 while ((skb = __skb_dequeue(&success))) {
384 struct ieee80211_tx_info *txinfo;
385
386 queue_bitmap |= BIT(skb_get_queue_mapping(skb));
387
388 txinfo = IEEE80211_SKB_CB(skb);
389 ieee80211_tx_info_clear_status(txinfo);
390
391 txinfo->flags |= IEEE80211_TX_STAT_ACK;
392 txinfo->status.rates[0].count = 1;
393
394 skb_pull(skb, sizeof(struct ar9170_tx_control));
395 ieee80211_tx_status_irqsafe(ar->hw, skb);
396 }
397
398 for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) {
399#ifdef AR9170_QUEUE_STOP_DEBUG
400 printk(KERN_DEBUG "%s: wake queue %d\n",
401 wiphy_name(ar->hw->wiphy), i);
402 __ar9170_dump_txstats(ar);
403#endif /* AR9170_QUEUE_STOP_DEBUG */
404 ieee80211_wake_queue(ar->hw, i);
405 }
406
407 if (queue_bitmap)
408 ar9170_tx(ar);
409}
410
411static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb)
412{
413 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
414 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
415
416 arinfo->timeout = jiffies +
417 msecs_to_jiffies(AR9170_BA_TIMEOUT);
418
419 skb_queue_tail(&ar->tx_status_ampdu, skb);
420 ar9170_tx_fake_ampdu_status(ar);
421
422 if (atomic_dec_and_test(&ar->tx_ampdu_pending) &&
423 !list_empty(&ar->tx_ampdu_list))
424 ar9170_tx_ampdu(ar);
425}
426
427void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) 330void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
428{ 331{
429 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 332 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -447,14 +350,10 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
447 if (info->flags & IEEE80211_TX_CTL_NO_ACK) { 350 if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
448 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); 351 ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
449 } else { 352 } else {
450 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 353 arinfo->timeout = jiffies +
451 ar9170_tx_ampdu_callback(ar, skb); 354 msecs_to_jiffies(AR9170_TX_TIMEOUT);
452 } else {
453 arinfo->timeout = jiffies +
454 msecs_to_jiffies(AR9170_TX_TIMEOUT);
455 355
456 skb_queue_tail(&ar->tx_status[queue], skb); 356 skb_queue_tail(&ar->tx_status[queue], skb);
457 }
458 } 357 }
459 358
460 if (!ar->tx_stats[queue].len && 359 if (!ar->tx_stats[queue].len &&
@@ -524,38 +423,6 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
524 return NULL; 423 return NULL;
525} 424}
526 425
527static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
528{
529 struct sk_buff *skb;
530 struct ieee80211_tx_info *txinfo;
531
532 while (count) {
533 skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
534 if (!skb)
535 break;
536
537 txinfo = IEEE80211_SKB_CB(skb);
538 ieee80211_tx_info_clear_status(txinfo);
539
540 /* FIXME: maybe more ? */
541 txinfo->status.rates[0].count = 1;
542
543 skb_pull(skb, sizeof(struct ar9170_tx_control));
544 ieee80211_tx_status_irqsafe(ar->hw, skb);
545 count--;
546 }
547
548#ifdef AR9170_TXAGG_DEBUG
549 if (count) {
550 printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
551 "suitable frames left in tx_status queue.\n",
552 wiphy_name(ar->hw->wiphy), count);
553
554 ar9170_dump_tx_status_ampdu(ar);
555 }
556#endif /* AR9170_TXAGG_DEBUG */
557}
558
559/* 426/*
560 * This worker tries to keeps an maintain tx_status queues. 427 * This worker tries to keeps an maintain tx_status queues.
561 * So we can guarantee that incoming tx_status reports are 428 * So we can guarantee that incoming tx_status reports are
@@ -592,8 +459,6 @@ static void ar9170_tx_janitor(struct work_struct *work)
592 resched = true; 459 resched = true;
593 } 460 }
594 461
595 ar9170_tx_fake_ampdu_status(ar);
596
597 if (!resched) 462 if (!resched)
598 return; 463 return;
599 464
@@ -673,10 +538,6 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
673 538
674 case 0xc5: 539 case 0xc5:
675 /* BlockACK events */ 540 /* BlockACK events */
676 ar9170_handle_block_ack(ar,
677 le16_to_cpu(cmd->ba_fail_cnt.failed),
678 le16_to_cpu(cmd->ba_fail_cnt.rate));
679 ar9170_tx_fake_ampdu_status(ar);
680 break; 541 break;
681 542
682 case 0xc6: 543 case 0xc6:
@@ -689,7 +550,8 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
689 550
690 /* firmware debug */ 551 /* firmware debug */
691 case 0xca: 552 case 0xca:
692 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); 553 printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
554 (char *)buf + 4);
693 break; 555 break;
694 case 0xcb: 556 case 0xcb:
695 len -= 4; 557 len -= 4;
@@ -926,7 +788,6 @@ static void ar9170_rx_phy_status(struct ar9170 *ar,
926 788
927 /* TODO: we could do something with phy_errors */ 789 /* TODO: we could do something with phy_errors */
928 status->signal = ar->noise[0] + phy->rssi_combined; 790 status->signal = ar->noise[0] + phy->rssi_combined;
929 status->noise = ar->noise[0];
930} 791}
931 792
932static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) 793static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
@@ -1247,7 +1108,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
1247 ar->global_ampdu_density = 6; 1108 ar->global_ampdu_density = 6;
1248 ar->global_ampdu_factor = 3; 1109 ar->global_ampdu_factor = 3;
1249 1110
1250 atomic_set(&ar->tx_ampdu_pending, 0);
1251 ar->bad_hw_nagger = jiffies; 1111 ar->bad_hw_nagger = jiffies;
1252 1112
1253 err = ar->open(ar); 1113 err = ar->open(ar);
@@ -1310,40 +1170,10 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1310 skb_queue_purge(&ar->tx_pending[i]); 1170 skb_queue_purge(&ar->tx_pending[i]);
1311 skb_queue_purge(&ar->tx_status[i]); 1171 skb_queue_purge(&ar->tx_status[i]);
1312 } 1172 }
1313 skb_queue_purge(&ar->tx_status_ampdu);
1314 1173
1315 mutex_unlock(&ar->mutex); 1174 mutex_unlock(&ar->mutex);
1316} 1175}
1317 1176
1318static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1319{
1320 struct ar9170_tx_control *txc = (void *) skb->data;
1321
1322 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1323}
1324
1325static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1326 struct sk_buff *src)
1327{
1328 struct ar9170_tx_control *dst_txc, *src_txc;
1329 struct ieee80211_tx_info *dst_info, *src_info;
1330 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1331
1332 src_txc = (void *) src->data;
1333 src_info = IEEE80211_SKB_CB(src);
1334 src_arinfo = (void *) src_info->rate_driver_data;
1335
1336 dst_txc = (void *) dst->data;
1337 dst_info = IEEE80211_SKB_CB(dst);
1338 dst_arinfo = (void *) dst_info->rate_driver_data;
1339
1340 dst_txc->phy_control = src_txc->phy_control;
1341
1342 /* same MCS for the whole aggregate */
1343 memcpy(dst_info->driver_rates, src_info->driver_rates,
1344 sizeof(dst_info->driver_rates));
1345}
1346
1347static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) 1177static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1348{ 1178{
1349 struct ieee80211_hdr *hdr; 1179 struct ieee80211_hdr *hdr;
@@ -1420,14 +1250,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1420 txc->phy_control |= 1250 txc->phy_control |=
1421 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); 1251 cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
1422 1252
1423 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1253 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1424 if (unlikely(!info->control.sta))
1425 goto err_out;
1426
1427 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1428 } else {
1429 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
1430 }
1431 } 1254 }
1432 1255
1433 return 0; 1256 return 0;
@@ -1537,158 +1360,6 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1537 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); 1360 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
1538} 1361}
1539 1362
1540static bool ar9170_tx_ampdu(struct ar9170 *ar)
1541{
1542 struct sk_buff_head agg;
1543 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1544 struct sk_buff *skb, *first = NULL;
1545 unsigned long flags, f2;
1546 unsigned int i = 0;
1547 u16 seq, queue, tmpssn;
1548 bool run = false;
1549
1550 skb_queue_head_init(&agg);
1551
1552 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1553 if (list_empty(&ar->tx_ampdu_list)) {
1554#ifdef AR9170_TXAGG_DEBUG
1555 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1556 wiphy_name(ar->hw->wiphy));
1557#endif /* AR9170_TXAGG_DEBUG */
1558 goto out_unlock;
1559 }
1560
1561 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1562 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1563#ifdef AR9170_TXAGG_DEBUG
1564 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1565 wiphy_name(ar->hw->wiphy));
1566#endif /* AR9170_TXAGG_DEBUG */
1567 continue;
1568 }
1569
1570 if (++i > 64) {
1571#ifdef AR9170_TXAGG_DEBUG
1572 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1573 wiphy_name(ar->hw->wiphy));
1574#endif /* AR9170_TXAGG_DEBUG */
1575 break;
1576 }
1577
1578 queue = TID_TO_WME_AC(tid_info->tid);
1579
1580 if (skb_queue_len(&ar->tx_pending[queue]) >=
1581 AR9170_NUM_TX_AGG_MAX) {
1582#ifdef AR9170_TXAGG_DEBUG
1583 printk(KERN_DEBUG "%s: queue %d full.\n",
1584 wiphy_name(ar->hw->wiphy), queue);
1585#endif /* AR9170_TXAGG_DEBUG */
1586 continue;
1587 }
1588
1589 list_del_init(&tid_info->list);
1590
1591 spin_lock_irqsave(&tid_info->queue.lock, f2);
1592 tmpssn = seq = tid_info->ssn;
1593 first = skb_peek(&tid_info->queue);
1594
1595 if (likely(first))
1596 tmpssn = ar9170_get_seq(first);
1597
1598 if (unlikely(tmpssn != seq)) {
1599#ifdef AR9170_TXAGG_DEBUG
1600 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1601 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1602#endif /* AR9170_TXAGG_DEBUG */
1603 tid_info->ssn = tmpssn;
1604 }
1605
1606#ifdef AR9170_TXAGG_DEBUG
1607 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1608 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1609 tid_info->tid, tid_info->ssn,
1610 skb_queue_len(&tid_info->queue));
1611 __ar9170_dump_txqueue(ar, &tid_info->queue);
1612#endif /* AR9170_TXAGG_DEBUG */
1613
1614 while ((skb = skb_peek(&tid_info->queue))) {
1615 if (unlikely(ar9170_get_seq(skb) != seq))
1616 break;
1617
1618 __skb_unlink(skb, &tid_info->queue);
1619 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1620
1621 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1622#ifdef AR9170_TXAGG_DEBUG
1623 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1624 "!match.\n", wiphy_name(ar->hw->wiphy),
1625 tid_info->tid,
1626 TID_TO_WME_AC(tid_info->tid),
1627 skb_get_queue_mapping(skb));
1628#endif /* AR9170_TXAGG_DEBUG */
1629 dev_kfree_skb_any(skb);
1630 continue;
1631 }
1632
1633 if (unlikely(first == skb)) {
1634 ar9170_tx_prepare_phy(ar, skb);
1635 __skb_queue_tail(&agg, skb);
1636 first = skb;
1637 } else {
1638 ar9170_tx_copy_phy(ar, skb, first);
1639 __skb_queue_tail(&agg, skb);
1640 }
1641
1642 if (unlikely(skb_queue_len(&agg) ==
1643 AR9170_NUM_TX_AGG_MAX))
1644 break;
1645 }
1646
1647 if (skb_queue_empty(&tid_info->queue))
1648 tid_info->active = false;
1649 else
1650 list_add_tail(&tid_info->list,
1651 &ar->tx_ampdu_list);
1652
1653 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1654
1655 if (unlikely(skb_queue_empty(&agg))) {
1656#ifdef AR9170_TXAGG_DEBUG
1657 printk(KERN_DEBUG "%s: queued empty list!\n",
1658 wiphy_name(ar->hw->wiphy));
1659#endif /* AR9170_TXAGG_DEBUG */
1660 continue;
1661 }
1662
1663 /*
1664 * tell the FW/HW that this is the last frame,
1665 * that way it will wait for the immediate block ack.
1666 */
1667 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1668
1669#ifdef AR9170_TXAGG_DEBUG
1670 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1671 wiphy_name(ar->hw->wiphy));
1672 __ar9170_dump_txqueue(ar, &agg);
1673#endif /* AR9170_TXAGG_DEBUG */
1674
1675 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1676
1677 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1678 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1679 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1680 run = true;
1681
1682 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1683 }
1684
1685out_unlock:
1686 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1687 __skb_queue_purge(&agg);
1688
1689 return run;
1690}
1691
1692static void ar9170_tx(struct ar9170 *ar) 1363static void ar9170_tx(struct ar9170 *ar)
1693{ 1364{
1694 struct sk_buff *skb; 1365 struct sk_buff *skb;
@@ -1728,7 +1399,7 @@ static void ar9170_tx(struct ar9170 *ar)
1728 printk(KERN_DEBUG "%s: queue %d full\n", 1399 printk(KERN_DEBUG "%s: queue %d full\n",
1729 wiphy_name(ar->hw->wiphy), i); 1400 wiphy_name(ar->hw->wiphy), i);
1730 1401
1731 printk(KERN_DEBUG "%s: stuck frames: ===> \n", 1402 printk(KERN_DEBUG "%s: stuck frames: ===>\n",
1732 wiphy_name(ar->hw->wiphy)); 1403 wiphy_name(ar->hw->wiphy));
1733 ar9170_dump_txqueue(ar, &ar->tx_pending[i]); 1404 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1734 ar9170_dump_txqueue(ar, &ar->tx_status[i]); 1405 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
@@ -1763,9 +1434,6 @@ static void ar9170_tx(struct ar9170 *ar)
1763 arinfo->timeout = jiffies + 1434 arinfo->timeout = jiffies +
1764 msecs_to_jiffies(AR9170_TX_TIMEOUT); 1435 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1765 1436
1766 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1767 atomic_inc(&ar->tx_ampdu_pending);
1768
1769#ifdef AR9170_QUEUE_DEBUG 1437#ifdef AR9170_QUEUE_DEBUG
1770 printk(KERN_DEBUG "%s: send frame q:%d =>\n", 1438 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1771 wiphy_name(ar->hw->wiphy), i); 1439 wiphy_name(ar->hw->wiphy), i);
@@ -1774,9 +1442,6 @@ static void ar9170_tx(struct ar9170 *ar)
1774 1442
1775 err = ar->tx(ar, skb); 1443 err = ar->tx(ar, skb);
1776 if (unlikely(err)) { 1444 if (unlikely(err)) {
1777 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1778 atomic_dec(&ar->tx_ampdu_pending);
1779
1780 frames_failed++; 1445 frames_failed++;
1781 dev_kfree_skb_any(skb); 1446 dev_kfree_skb_any(skb);
1782 } else { 1447 } else {
@@ -1823,94 +1488,11 @@ static void ar9170_tx(struct ar9170 *ar)
1823 msecs_to_jiffies(AR9170_JANITOR_DELAY)); 1488 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1824} 1489}
1825 1490
1826static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1827{
1828 struct ieee80211_tx_info *txinfo;
1829 struct ar9170_sta_info *sta_info;
1830 struct ar9170_sta_tid *agg;
1831 struct sk_buff *iter;
1832 unsigned long flags, f2;
1833 unsigned int max;
1834 u16 tid, seq, qseq;
1835 bool run = false, queue = false;
1836
1837 tid = ar9170_get_tid(skb);
1838 seq = ar9170_get_seq(skb);
1839 txinfo = IEEE80211_SKB_CB(skb);
1840 sta_info = (void *) txinfo->control.sta->drv_priv;
1841 agg = &sta_info->agg[tid];
1842 max = sta_info->ampdu_max_len;
1843
1844 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1845
1846 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1847#ifdef AR9170_TXAGG_DEBUG
1848 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1849 "for ESS:%pM tid:%d state:%d.\n",
1850 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1851 agg->state);
1852#endif /* AR9170_TXAGG_DEBUG */
1853 goto err_unlock;
1854 }
1855
1856 if (!agg->active) {
1857 agg->active = true;
1858 agg->ssn = seq;
1859 queue = true;
1860 }
1861
1862 /* check if seq is within the BA window */
1863 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1864#ifdef AR9170_TXAGG_DEBUG
1865 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1866 "fit into BA window (%d - %d)\n",
1867 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1868 (agg->ssn + max) & 0xfff);
1869#endif /* AR9170_TXAGG_DEBUG */
1870 goto err_unlock;
1871 }
1872
1873 spin_lock_irqsave(&agg->queue.lock, f2);
1874
1875 skb_queue_reverse_walk(&agg->queue, iter) {
1876 qseq = ar9170_get_seq(iter);
1877
1878 if (GET_NEXT_SEQ(qseq) == seq) {
1879 __skb_queue_after(&agg->queue, iter, skb);
1880 goto queued;
1881 }
1882 }
1883
1884 __skb_queue_head(&agg->queue, skb);
1885
1886queued:
1887 spin_unlock_irqrestore(&agg->queue.lock, f2);
1888
1889#ifdef AR9170_TXAGG_DEBUG
1890 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1891 wiphy_name(ar->hw->wiphy), skb);
1892 __ar9170_dump_txqueue(ar, &agg->queue);
1893#endif /* AR9170_TXAGG_DEBUG */
1894
1895 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1896 run = true;
1897
1898 if (queue)
1899 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1900
1901 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1902 return run;
1903
1904err_unlock:
1905 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1906 dev_kfree_skb_irq(skb);
1907 return false;
1908}
1909
1910int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 1491int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1911{ 1492{
1912 struct ar9170 *ar = hw->priv; 1493 struct ar9170 *ar = hw->priv;
1913 struct ieee80211_tx_info *info; 1494 struct ieee80211_tx_info *info;
1495 unsigned int queue;
1914 1496
1915 if (unlikely(!IS_STARTED(ar))) 1497 if (unlikely(!IS_STARTED(ar)))
1916 goto err_free; 1498 goto err_free;
@@ -1918,18 +1500,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1918 if (unlikely(ar9170_tx_prepare(ar, skb))) 1500 if (unlikely(ar9170_tx_prepare(ar, skb)))
1919 goto err_free; 1501 goto err_free;
1920 1502
1503 queue = skb_get_queue_mapping(skb);
1921 info = IEEE80211_SKB_CB(skb); 1504 info = IEEE80211_SKB_CB(skb);
1922 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1505 ar9170_tx_prepare_phy(ar, skb);
1923 bool run = ar9170_tx_ampdu_queue(ar, skb); 1506 skb_queue_tail(&ar->tx_pending[queue], skb);
1924
1925 if (run || !atomic_read(&ar->tx_ampdu_pending))
1926 ar9170_tx_ampdu(ar);
1927 } else {
1928 unsigned int queue = skb_get_queue_mapping(skb);
1929
1930 ar9170_tx_prepare_phy(ar, skb);
1931 skb_queue_tail(&ar->tx_pending[queue], skb);
1932 }
1933 1507
1934 ar9170_tx(ar); 1508 ar9170_tx(ar);
1935 return NETDEV_TX_OK; 1509 return NETDEV_TX_OK;
@@ -2046,21 +1620,17 @@ out:
2046 return err; 1620 return err;
2047} 1621}
2048 1622
2049static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 1623static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
2050 struct dev_addr_list *mclist) 1624 struct netdev_hw_addr_list *mc_list)
2051{ 1625{
2052 u64 mchash; 1626 u64 mchash;
2053 int i; 1627 struct netdev_hw_addr *ha;
2054 1628
2055 /* always get broadcast frames */ 1629 /* always get broadcast frames */
2056 mchash = 1ULL << (0xff >> 2); 1630 mchash = 1ULL << (0xff >> 2);
2057 1631
2058 for (i = 0; i < mc_count; i++) { 1632 netdev_hw_addr_list_for_each(ha, mc_list)
2059 if (WARN_ON(!mclist)) 1633 mchash |= 1ULL << (ha->addr[5] >> 2);
2060 break;
2061 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2062 mclist = mclist->next;
2063 }
2064 1634
2065 return mchash; 1635 return mchash;
2066} 1636}
@@ -2330,57 +1900,6 @@ out:
2330 return err; 1900 return err;
2331} 1901}
2332 1902
2333static int ar9170_sta_add(struct ieee80211_hw *hw,
2334 struct ieee80211_vif *vif,
2335 struct ieee80211_sta *sta)
2336{
2337 struct ar9170 *ar = hw->priv;
2338 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2339 unsigned int i;
2340
2341 memset(sta_info, 0, sizeof(*sta_info));
2342
2343 if (!sta->ht_cap.ht_supported)
2344 return 0;
2345
2346 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2347 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2348
2349 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2350 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2351
2352 for (i = 0; i < AR9170_NUM_TID; i++) {
2353 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2354 sta_info->agg[i].active = false;
2355 sta_info->agg[i].ssn = 0;
2356 sta_info->agg[i].tid = i;
2357 INIT_LIST_HEAD(&sta_info->agg[i].list);
2358 skb_queue_head_init(&sta_info->agg[i].queue);
2359 }
2360
2361 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2362
2363 return 0;
2364}
2365
2366static int ar9170_sta_remove(struct ieee80211_hw *hw,
2367 struct ieee80211_vif *vif,
2368 struct ieee80211_sta *sta)
2369{
2370 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2371 unsigned int i;
2372
2373 if (!sta->ht_cap.ht_supported)
2374 return 0;
2375
2376 for (i = 0; i < AR9170_NUM_TID; i++) {
2377 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2378 skb_queue_purge(&sta_info->agg[i].queue);
2379 }
2380
2381 return 0;
2382}
2383
2384static int ar9170_get_stats(struct ieee80211_hw *hw, 1903static int ar9170_get_stats(struct ieee80211_hw *hw,
2385 struct ieee80211_low_level_stats *stats) 1904 struct ieee80211_low_level_stats *stats)
2386{ 1905{
@@ -2423,55 +1942,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw,
2423 enum ieee80211_ampdu_mlme_action action, 1942 enum ieee80211_ampdu_mlme_action action,
2424 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 1943 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2425{ 1944{
2426 struct ar9170 *ar = hw->priv;
2427 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2428 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2429 unsigned long flags;
2430
2431 if (!modparam_ht)
2432 return -EOPNOTSUPP;
2433
2434 switch (action) { 1945 switch (action) {
2435 case IEEE80211_AMPDU_TX_START:
2436 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2437 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2438 !list_empty(&tid_info->list)) {
2439 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2440#ifdef AR9170_TXAGG_DEBUG
2441 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2442 "is in a very bad state!\n",
2443 wiphy_name(hw->wiphy), sta->addr, tid);
2444#endif /* AR9170_TXAGG_DEBUG */
2445 return -EBUSY;
2446 }
2447
2448 *ssn = tid_info->ssn;
2449 tid_info->state = AR9170_TID_STATE_PROGRESS;
2450 tid_info->active = false;
2451 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2452 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2453 break;
2454
2455 case IEEE80211_AMPDU_TX_STOP:
2456 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2457 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2458 list_del_init(&tid_info->list);
2459 tid_info->active = false;
2460 skb_queue_purge(&tid_info->queue);
2461 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2462 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2463 break;
2464
2465 case IEEE80211_AMPDU_TX_OPERATIONAL:
2466#ifdef AR9170_TXAGG_DEBUG
2467 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2468 wiphy_name(hw->wiphy), sta->addr, tid);
2469#endif /* AR9170_TXAGG_DEBUG */
2470 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2471 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2472 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2473 break;
2474
2475 case IEEE80211_AMPDU_RX_START: 1946 case IEEE80211_AMPDU_RX_START:
2476 case IEEE80211_AMPDU_RX_STOP: 1947 case IEEE80211_AMPDU_RX_STOP:
2477 /* Handled by firmware */ 1948 /* Handled by firmware */
@@ -2497,8 +1968,6 @@ static const struct ieee80211_ops ar9170_ops = {
2497 .bss_info_changed = ar9170_op_bss_info_changed, 1968 .bss_info_changed = ar9170_op_bss_info_changed,
2498 .get_tsf = ar9170_op_get_tsf, 1969 .get_tsf = ar9170_op_get_tsf,
2499 .set_key = ar9170_set_key, 1970 .set_key = ar9170_set_key,
2500 .sta_add = ar9170_sta_add,
2501 .sta_remove = ar9170_sta_remove,
2502 .get_stats = ar9170_get_stats, 1971 .get_stats = ar9170_get_stats,
2503 .ampdu_action = ar9170_ampdu_action, 1972 .ampdu_action = ar9170_ampdu_action,
2504}; 1973};
@@ -2516,7 +1985,7 @@ void *ar9170_alloc(size_t priv_size)
2516 * tends to split the streams into separate rx descriptors. 1985 * tends to split the streams into separate rx descriptors.
2517 */ 1986 */
2518 1987
2519 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); 1988 skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
2520 if (!skb) 1989 if (!skb)
2521 goto err_nomem; 1990 goto err_nomem;
2522 1991
@@ -2531,8 +2000,6 @@ void *ar9170_alloc(size_t priv_size)
2531 mutex_init(&ar->mutex); 2000 mutex_init(&ar->mutex);
2532 spin_lock_init(&ar->cmdlock); 2001 spin_lock_init(&ar->cmdlock);
2533 spin_lock_init(&ar->tx_stats_lock); 2002 spin_lock_init(&ar->tx_stats_lock);
2534 spin_lock_init(&ar->tx_ampdu_list_lock);
2535 skb_queue_head_init(&ar->tx_status_ampdu);
2536 for (i = 0; i < __AR9170_NUM_TXQ; i++) { 2003 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2537 skb_queue_head_init(&ar->tx_status[i]); 2004 skb_queue_head_init(&ar->tx_status[i]);
2538 skb_queue_head_init(&ar->tx_pending[i]); 2005 skb_queue_head_init(&ar->tx_pending[i]);
@@ -2540,7 +2007,6 @@ void *ar9170_alloc(size_t priv_size)
2540 ar9170_rx_reset_rx_mpdu(ar); 2007 ar9170_rx_reset_rx_mpdu(ar);
2541 INIT_WORK(&ar->beacon_work, ar9170_new_beacon); 2008 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
2542 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); 2009 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
2543 INIT_LIST_HEAD(&ar->tx_ampdu_list);
2544 2010
2545 /* all hw supports 2.4 GHz, so set channel to 1 by default */ 2011 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2546 ar->channel = &ar9170_2ghz_chantable[0]; 2012 ar->channel = &ar9170_2ghz_chantable[0];
@@ -2551,19 +2017,10 @@ void *ar9170_alloc(size_t priv_size)
2551 BIT(NL80211_IFTYPE_ADHOC); 2017 BIT(NL80211_IFTYPE_ADHOC);
2552 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | 2018 ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
2553 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2019 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2554 IEEE80211_HW_SIGNAL_DBM | 2020 IEEE80211_HW_SIGNAL_DBM;
2555 IEEE80211_HW_NOISE_DBM;
2556
2557 if (modparam_ht) {
2558 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2559 } else {
2560 ar9170_band_2GHz.ht_cap.ht_supported = false;
2561 ar9170_band_5GHz.ht_cap.ht_supported = false;
2562 }
2563 2021
2564 ar->hw->queues = __AR9170_NUM_TXQ; 2022 ar->hw->queues = __AR9170_NUM_TXQ;
2565 ar->hw->extra_tx_headroom = 8; 2023 ar->hw->extra_tx_headroom = 8;
2566 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
2567 2024
2568 ar->hw->max_rates = 1; 2025 ar->hw->max_rates = 1;
2569 ar->hw->max_rate_tries = 3; 2026 ar->hw->max_rate_tries = 3;
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index e1c2fcaa8bed..abd083a357f5 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -42,6 +42,7 @@
42#include <linux/usb.h> 42#include <linux/usb.h>
43#include <linux/firmware.h> 43#include <linux/firmware.h>
44#include <linux/etherdevice.h> 44#include <linux/etherdevice.h>
45#include <linux/device.h>
45#include <net/mac80211.h> 46#include <net/mac80211.h>
46#include "ar9170.h" 47#include "ar9170.h"
47#include "cmd.h" 48#include "cmd.h"
@@ -67,18 +68,28 @@ static struct usb_device_id ar9170_usb_ids[] = {
67 { USB_DEVICE(0x0cf3, 0x1001) }, 68 { USB_DEVICE(0x0cf3, 0x1001) },
68 /* TP-Link TL-WN821N v2 */ 69 /* TP-Link TL-WN821N v2 */
69 { USB_DEVICE(0x0cf3, 0x1002) }, 70 { USB_DEVICE(0x0cf3, 0x1002) },
71 /* 3Com Dual Band 802.11n USB Adapter */
72 { USB_DEVICE(0x0cf3, 0x1010) },
73 /* H3C Dual Band 802.11n USB Adapter */
74 { USB_DEVICE(0x0cf3, 0x1011) },
70 /* Cace Airpcap NX */ 75 /* Cace Airpcap NX */
71 { USB_DEVICE(0xcace, 0x0300) }, 76 { USB_DEVICE(0xcace, 0x0300) },
72 /* D-Link DWA 160 A1 */ 77 /* D-Link DWA 160 A1 */
73 { USB_DEVICE(0x07d1, 0x3c10) }, 78 { USB_DEVICE(0x07d1, 0x3c10) },
74 /* D-Link DWA 160 A2 */ 79 /* D-Link DWA 160 A2 */
75 { USB_DEVICE(0x07d1, 0x3a09) }, 80 { USB_DEVICE(0x07d1, 0x3a09) },
81 /* Netgear WNA1000 */
82 { USB_DEVICE(0x0846, 0x9040) },
76 /* Netgear WNDA3100 */ 83 /* Netgear WNDA3100 */
77 { USB_DEVICE(0x0846, 0x9010) }, 84 { USB_DEVICE(0x0846, 0x9010) },
78 /* Netgear WN111 v2 */ 85 /* Netgear WN111 v2 */
79 { USB_DEVICE(0x0846, 0x9001) }, 86 { USB_DEVICE(0x0846, 0x9001) },
80 /* Zydas ZD1221 */ 87 /* Zydas ZD1221 */
81 { USB_DEVICE(0x0ace, 0x1221) }, 88 { USB_DEVICE(0x0ace, 0x1221) },
89 /* Proxim ORiNOCO 802.11n USB */
90 { USB_DEVICE(0x1435, 0x0804) },
91 /* WNC Generic 11n USB Dongle */
92 { USB_DEVICE(0x1435, 0x0326) },
82 /* ZyXEL NWD271N */ 93 /* ZyXEL NWD271N */
83 { USB_DEVICE(0x0586, 0x3417) }, 94 { USB_DEVICE(0x0586, 0x3417) },
84 /* Z-Com UB81 BG */ 95 /* Z-Com UB81 BG */
@@ -99,6 +110,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
99 { USB_DEVICE(0x0409, 0x0249) }, 110 { USB_DEVICE(0x0409, 0x0249) },
100 /* AVM FRITZ!WLAN USB Stick N 2.4 */ 111 /* AVM FRITZ!WLAN USB Stick N 2.4 */
101 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, 112 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
113 /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
114 { USB_DEVICE(0x1668, 0x1200) },
102 115
103 /* terminate */ 116 /* terminate */
104 {} 117 {}
@@ -731,10 +744,10 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
731 744
732 /* unbind anything failed */ 745 /* unbind anything failed */
733 if (parent) 746 if (parent)
734 down(&parent->sem); 747 device_lock(parent);
735 device_release_driver(&aru->udev->dev); 748 device_release_driver(&aru->udev->dev);
736 if (parent) 749 if (parent)
737 up(&parent->sem); 750 device_unlock(parent);
738 751
739 usb_put_dev(aru->udev); 752 usb_put_dev(aru->udev);
740} 753}
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 71fc960814f0..d32f2828b098 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -48,6 +48,12 @@ enum ath_device_state {
48 ATH_HW_INITIALIZED, 48 ATH_HW_INITIALIZED,
49}; 49};
50 50
51enum ath_bus_type {
52 ATH_PCI,
53 ATH_AHB,
54 ATH_USB,
55};
56
51struct reg_dmn_pair_mapping { 57struct reg_dmn_pair_mapping {
52 u16 regDmnEnum; 58 u16 regDmnEnum;
53 u16 reg_5ghz_ctl; 59 u16 reg_5ghz_ctl;
@@ -65,17 +71,30 @@ struct ath_regulatory {
65 struct reg_dmn_pair_mapping *regpair; 71 struct reg_dmn_pair_mapping *regpair;
66}; 72};
67 73
74/**
75 * struct ath_ops - Register read/write operations
76 *
77 * @read: Register read
78 * @write: Register write
79 * @enable_write_buffer: Enable multiple register writes
80 * @disable_write_buffer: Disable multiple register writes
81 * @write_flush: Flush buffered register writes
82 */
68struct ath_ops { 83struct ath_ops {
69 unsigned int (*read)(void *, u32 reg_offset); 84 unsigned int (*read)(void *, u32 reg_offset);
70 void (*write)(void *, u32 val, u32 reg_offset); 85 void (*write)(void *, u32 val, u32 reg_offset);
86 void (*enable_write_buffer)(void *);
87 void (*disable_write_buffer)(void *);
88 void (*write_flush) (void *);
71}; 89};
72 90
73struct ath_common; 91struct ath_common;
74 92
75struct ath_bus_ops { 93struct ath_bus_ops {
76 void (*read_cachesize)(struct ath_common *common, int *csz); 94 enum ath_bus_type ath_bus_type;
77 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 95 void (*read_cachesize)(struct ath_common *common, int *csz);
78 void (*bt_coex_prep)(struct ath_common *common); 96 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
97 void (*bt_coex_prep)(struct ath_common *common);
79}; 98};
80 99
81struct ath_common { 100struct ath_common {
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index 090dc6d268a3..cc09595b781a 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -12,5 +12,6 @@ ath5k-y += attach.o
12ath5k-y += base.o 12ath5k-y += base.o
13ath5k-y += led.o 13ath5k-y += led.o
14ath5k-y += rfkill.o 14ath5k-y += rfkill.o
15ath5k-y += ani.o
15ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 16ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
16obj-$(CONFIG_ATH5K) += ath5k.o 17obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
new file mode 100644
index 000000000000..f2311ab35504
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -0,0 +1,744 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
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 "ath5k.h"
18#include "base.h"
19#include "reg.h"
20#include "debug.h"
21#include "ani.h"
22
23/**
24 * DOC: Basic ANI Operation
25 *
26 * Adaptive Noise Immunity (ANI) controls five noise immunity parameters
27 * depending on the amount of interference in the environment, increasing
28 * or reducing sensitivity as necessary.
29 *
30 * The parameters are:
31 * - "noise immunity"
32 * - "spur immunity"
33 * - "firstep level"
34 * - "OFDM weak signal detection"
35 * - "CCK weak signal detection"
36 *
37 * Basically we look at the amount of ODFM and CCK timing errors we get and then
38 * raise or lower immunity accordingly by setting one or more of these
39 * parameters.
40 * Newer chipsets have PHY error counters in hardware which will generate a MIB
41 * interrupt when they overflow. Older hardware has too enable PHY error frames
42 * by setting a RX flag and then count every single PHY error. When a specified
43 * threshold of errors has been reached we will raise immunity.
44 * Also we regularly check the amount of errors and lower or raise immunity as
45 * necessary.
46 */
47
48
49/*** ANI parameter control ***/
50
51/**
52 * ath5k_ani_set_noise_immunity_level() - Set noise immunity level
53 *
54 * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL
55 */
56void
57ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
58{
59 /* TODO:
60 * ANI documents suggest the following five levels to use, but the HAL
61 * and ath9k use only use the last two levels, making this
62 * essentially an on/off option. There *may* be a reason for this (???),
63 * so i stick with the HAL version for now...
64 */
65#if 0
66 const s8 hi[] = { -18, -18, -16, -14, -12 };
67 const s8 lo[] = { -52, -56, -60, -64, -70 };
68 const s8 sz[] = { -34, -41, -48, -55, -62 };
69 const s8 fr[] = { -70, -72, -75, -78, -80 };
70#else
71 const s8 sz[] = { -55, -62 };
72 const s8 lo[] = { -64, -70 };
73 const s8 hi[] = { -14, -12 };
74 const s8 fr[] = { -78, -80 };
75#endif
76 if (level < 0 || level >= ARRAY_SIZE(sz)) {
77 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
78 "level out of range %d", level);
79 return;
80 }
81
82 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
83 AR5K_PHY_DESIRED_SIZE_TOT, sz[level]);
84 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
85 AR5K_PHY_AGCCOARSE_LO, lo[level]);
86 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE,
87 AR5K_PHY_AGCCOARSE_HI, hi[level]);
88 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
89 AR5K_PHY_SIG_FIRPWR, fr[level]);
90
91 ah->ah_sc->ani_state.noise_imm_level = level;
92 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
93}
94
95
96/**
97 * ath5k_ani_set_spur_immunity_level() - Set spur immunity level
98 *
99 * @level: level between 0 and @max_spur_level (the maximum level is dependent
100 * on the chip revision).
101 */
102void
103ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
104{
105 const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
106
107 if (level < 0 || level >= ARRAY_SIZE(val) ||
108 level > ah->ah_sc->ani_state.max_spur_level) {
109 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
110 "level out of range %d", level);
111 return;
112 }
113
114 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
115 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]);
116
117 ah->ah_sc->ani_state.spur_level = level;
118 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
119}
120
121
122/**
123 * ath5k_ani_set_firstep_level() - Set "firstep" level
124 *
125 * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL
126 */
127void
128ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
129{
130 const int val[] = { 0, 4, 8 };
131
132 if (level < 0 || level >= ARRAY_SIZE(val)) {
133 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
134 "level out of range %d", level);
135 return;
136 }
137
138 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
139 AR5K_PHY_SIG_FIRSTEP, val[level]);
140
141 ah->ah_sc->ani_state.firstep_level = level;
142 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
143}
144
145
146/**
147 * ath5k_ani_set_ofdm_weak_signal_detection() - Control OFDM weak signal
148 * detection
149 *
150 * @on: turn on or off
151 */
152void
153ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
154{
155 const int m1l[] = { 127, 50 };
156 const int m2l[] = { 127, 40 };
157 const int m1[] = { 127, 0x4d };
158 const int m2[] = { 127, 0x40 };
159 const int m2cnt[] = { 31, 16 };
160 const int m2lcnt[] = { 63, 48 };
161
162 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
163 AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]);
164 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
165 AR5K_PHY_WEAK_OFDM_LOW_THR_M2, m2l[on]);
166 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
167 AR5K_PHY_WEAK_OFDM_HIGH_THR_M1, m1[on]);
168 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
169 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2, m2[on]);
170 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR,
171 AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT, m2cnt[on]);
172 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
173 AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT, m2lcnt[on]);
174
175 if (on)
176 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
177 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
178 else
179 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
180 AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
181
182 ah->ah_sc->ani_state.ofdm_weak_sig = on;
183 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
184 on ? "on" : "off");
185}
186
187
188/**
189 * ath5k_ani_set_cck_weak_signal_detection() - control CCK weak signal detection
190 *
191 * @on: turn on or off
192 */
193void
194ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
195{
196 const int val[] = { 8, 6 };
197 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
198 AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
199 ah->ah_sc->ani_state.cck_weak_sig = on;
200 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
201 on ? "on" : "off");
202}
203
204
205/*** ANI algorithm ***/
206
207/**
208 * ath5k_ani_raise_immunity() - Increase noise immunity
209 *
210 * @ofdm_trigger: If this is true we are called because of too many OFDM errors,
211 * the algorithm will tune more parameters then.
212 *
213 * Try to raise noise immunity (=decrease sensitivity) in several steps
214 * depending on the average RSSI of the beacons we received.
215 */
216static void
217ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
218 bool ofdm_trigger)
219{
220 int rssi = ah->ah_beacon_rssi_avg.avg;
221
222 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
223 ofdm_trigger ? "ODFM" : "CCK");
224
225 /* first: raise noise immunity */
226 if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) {
227 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1);
228 return;
229 }
230
231 /* only OFDM: raise spur immunity level */
232 if (ofdm_trigger &&
233 as->spur_level < ah->ah_sc->ani_state.max_spur_level) {
234 ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
235 return;
236 }
237
238 /* AP mode */
239 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
240 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
241 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
242 return;
243 }
244
245 /* STA and IBSS mode */
246
247 /* TODO: for IBSS mode it would be better to keep a beacon RSSI average
248 * per each neighbour node and use the minimum of these, to make sure we
249 * don't shut out a remote node by raising immunity too high. */
250
251 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
252 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
253 "beacon RSSI high");
254 /* only OFDM: beacon RSSI is high, we can disable ODFM weak
255 * signal detection */
256 if (ofdm_trigger && as->ofdm_weak_sig == true) {
257 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
258 ath5k_ani_set_spur_immunity_level(ah, 0);
259 return;
260 }
261 /* as a last resort or CCK: raise firstep level */
262 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) {
263 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
264 return;
265 }
266 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
267 /* beacon RSSI in mid range, we need OFDM weak signal detect,
268 * but can raise firstep level */
269 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
270 "beacon RSSI mid");
271 if (ofdm_trigger && as->ofdm_weak_sig == false)
272 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
273 if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
274 ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
275 return;
276 } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
277 /* beacon RSSI is low. in B/G mode turn of OFDM weak signal
278 * detect and zero firstep level to maximize CCK sensitivity */
279 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
280 "beacon RSSI low, 2GHz");
281 if (ofdm_trigger && as->ofdm_weak_sig == true)
282 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
283 if (as->firstep_level > 0)
284 ath5k_ani_set_firstep_level(ah, 0);
285 return;
286 }
287
288 /* TODO: why not?:
289 if (as->cck_weak_sig == true) {
290 ath5k_ani_set_cck_weak_signal_detection(ah, false);
291 }
292 */
293}
294
295
296/**
297 * ath5k_ani_lower_immunity() - Decrease noise immunity
298 *
299 * Try to lower noise immunity (=increase sensitivity) in several steps
300 * depending on the average RSSI of the beacons we received.
301 */
302static void
303ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
304{
305 int rssi = ah->ah_beacon_rssi_avg.avg;
306
307 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
308
309 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
310 /* AP mode */
311 if (as->firstep_level > 0) {
312 ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
313 return;
314 }
315 } else {
316 /* STA and IBSS mode (see TODO above) */
317 if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
318 /* beacon signal is high, leave OFDM weak signal
319 * detection off or it may oscillate
320 * TODO: who said it's off??? */
321 } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
322 /* beacon RSSI is mid-range: turn on ODFM weak signal
323 * detection and next, lower firstep level */
324 if (as->ofdm_weak_sig == false) {
325 ath5k_ani_set_ofdm_weak_signal_detection(ah,
326 true);
327 return;
328 }
329 if (as->firstep_level > 0) {
330 ath5k_ani_set_firstep_level(ah,
331 as->firstep_level - 1);
332 return;
333 }
334 } else {
335 /* beacon signal is low: only reduce firstep level */
336 if (as->firstep_level > 0) {
337 ath5k_ani_set_firstep_level(ah,
338 as->firstep_level - 1);
339 return;
340 }
341 }
342 }
343
344 /* all modes */
345 if (as->spur_level > 0) {
346 ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1);
347 return;
348 }
349
350 /* finally, reduce noise immunity */
351 if (as->noise_imm_level > 0) {
352 ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1);
353 return;
354 }
355}
356
357
358/**
359 * ath5k_hw_ani_get_listen_time() - Calculate time spent listening
360 *
361 * Return an approximation of the time spent "listening" in milliseconds (ms)
362 * since the last call of this function by deducting the cycles spent
363 * transmitting and receiving from the total cycle count.
364 * Save profile count values for debugging/statistics and because we might want
365 * to use them later.
366 *
367 * We assume no one else clears these registers!
368 */
369static int
370ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
371{
372 int listen;
373
374 /* freeze */
375 ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
376 /* read */
377 as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
378 as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
379 as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
380 as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
381 /* clear */
382 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
383 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
384 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
385 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
386 /* un-freeze */
387 ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
388
389 /* TODO: where does 44000 come from? (11g clock rate?) */
390 listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
391
392 if (as->pfc_cycles == 0 || listen < 0)
393 return 0;
394 return listen;
395}
396
397
398/**
399 * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters
400 *
401 * Clear the PHY error counters as soon as possible, since this might be called
402 * from a MIB interrupt and we want to make sure we don't get interrupted again.
403 * Add the count of CCK and OFDM errors to our internal state, so it can be used
404 * by the algorithm later.
405 *
406 * Will be called from interrupt and tasklet context.
407 * Returns 0 if both counters are zero.
408 */
409static int
410ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah,
411 struct ath5k_ani_state *as)
412{
413 unsigned int ofdm_err, cck_err;
414
415 if (!ah->ah_capabilities.cap_has_phyerr_counters)
416 return 0;
417
418 ofdm_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1);
419 cck_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2);
420
421 /* reset counters first, we might be in a hurry (interrupt) */
422 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
423 AR5K_PHYERR_CNT1);
424 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
425 AR5K_PHYERR_CNT2);
426
427 ofdm_err = ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ofdm_err);
428 cck_err = ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - cck_err);
429
430 /* sometimes both can be zero, especially when there is a superfluous
431 * second interrupt. detect that here and return an error. */
432 if (ofdm_err <= 0 && cck_err <= 0)
433 return 0;
434
435 /* avoid negative values should one of the registers overflow */
436 if (ofdm_err > 0) {
437 as->ofdm_errors += ofdm_err;
438 as->sum_ofdm_errors += ofdm_err;
439 }
440 if (cck_err > 0) {
441 as->cck_errors += cck_err;
442 as->sum_cck_errors += cck_err;
443 }
444 return 1;
445}
446
447
448/**
449 * ath5k_ani_period_restart() - Restart ANI period
450 *
451 * Just reset counters, so they are clear for the next "ani period".
452 */
453static void
454ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as)
455{
456 /* keep last values for debugging */
457 as->last_ofdm_errors = as->ofdm_errors;
458 as->last_cck_errors = as->cck_errors;
459 as->last_listen = as->listen_time;
460
461 as->ofdm_errors = 0;
462 as->cck_errors = 0;
463 as->listen_time = 0;
464}
465
466
467/**
468 * ath5k_ani_calibration() - The main ANI calibration function
469 *
470 * We count OFDM and CCK errors relative to the time where we did not send or
471 * receive ("listen" time) and raise or lower immunity accordingly.
472 * This is called regularly (every second) from the calibration timer, but also
473 * when an error threshold has been reached.
474 *
475 * In order to synchronize access from different contexts, this should be
476 * called only indirectly by scheduling the ANI tasklet!
477 */
478void
479ath5k_ani_calibration(struct ath5k_hw *ah)
480{
481 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
482 int listen, ofdm_high, ofdm_low, cck_high, cck_low;
483
484 if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
485 return;
486
487 /* get listen time since last call and add it to the counter because we
488 * might not have restarted the "ani period" last time */
489 listen = ath5k_hw_ani_get_listen_time(ah, as);
490 as->listen_time += listen;
491
492 ath5k_ani_save_and_clear_phy_errors(ah, as);
493
494 ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000;
495 cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000;
496 ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000;
497 cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000;
498
499 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
500 "listen %d (now %d)", as->listen_time, listen);
501 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
502 "check high ofdm %d/%d cck %d/%d",
503 as->ofdm_errors, ofdm_high, as->cck_errors, cck_high);
504
505 if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) {
506 /* too many PHY errors - we have to raise immunity */
507 bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false;
508 ath5k_ani_raise_immunity(ah, as, ofdm_flag);
509 ath5k_ani_period_restart(ah, as);
510
511 } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) {
512 /* If more than 5 (TODO: why 5?) periods have passed and we got
513 * relatively little errors we can try to lower immunity */
514 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
515 "check low ofdm %d/%d cck %d/%d",
516 as->ofdm_errors, ofdm_low, as->cck_errors, cck_low);
517
518 if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low)
519 ath5k_ani_lower_immunity(ah, as);
520
521 ath5k_ani_period_restart(ah, as);
522 }
523}
524
525
526/*** INTERRUPT HANDLER ***/
527
528/**
529 * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters
530 *
531 * Just read & reset the registers quickly, so they don't generate more
532 * interrupts, save the counters and schedule the tasklet to decide whether
533 * to raise immunity or not.
534 *
535 * We just need to handle PHY error counters, ath5k_hw_update_mib_counters()
536 * should take care of all "normal" MIB interrupts.
537 */
538void
539ath5k_ani_mib_intr(struct ath5k_hw *ah)
540{
541 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
542
543 /* nothing to do here if HW does not have PHY error counters - they
544 * can't be the reason for the MIB interrupt then */
545 if (!ah->ah_capabilities.cap_has_phyerr_counters)
546 return;
547
548 /* not in use but clear anyways */
549 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
550 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
551
552 if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
553 return;
554
555 /* if one of the errors triggered, we can get a superfluous second
556 * interrupt, even though we have already reset the register. the
557 * function detects that so we can return early */
558 if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0)
559 return;
560
561 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH ||
562 as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
563 tasklet_schedule(&ah->ah_sc->ani_tasklet);
564}
565
566
567/**
568 * ath5k_ani_phy_error_report() - Used by older HW to report PHY errors
569 *
570 * This is used by hardware without PHY error counters to report PHY errors
571 * on a frame-by-frame basis, instead of the interrupt.
572 */
573void
574ath5k_ani_phy_error_report(struct ath5k_hw *ah,
575 enum ath5k_phy_error_code phyerr)
576{
577 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
578
579 if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) {
580 as->ofdm_errors++;
581 if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH)
582 tasklet_schedule(&ah->ah_sc->ani_tasklet);
583 } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) {
584 as->cck_errors++;
585 if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
586 tasklet_schedule(&ah->ah_sc->ani_tasklet);
587 }
588}
589
590
591/*** INIT ***/
592
593/**
594 * ath5k_enable_phy_err_counters() - Enable PHY error counters
595 *
596 * Enable PHY error counters for OFDM and CCK timing errors.
597 */
598static void
599ath5k_enable_phy_err_counters(struct ath5k_hw *ah)
600{
601 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH,
602 AR5K_PHYERR_CNT1);
603 ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH,
604 AR5K_PHYERR_CNT2);
605 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHYERR_CNT1_MASK);
606 ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_CCK, AR5K_PHYERR_CNT2_MASK);
607
608 /* not in use */
609 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
610 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
611}
612
613
614/**
615 * ath5k_disable_phy_err_counters() - Disable PHY error counters
616 *
617 * Disable PHY error counters for OFDM and CCK timing errors.
618 */
619static void
620ath5k_disable_phy_err_counters(struct ath5k_hw *ah)
621{
622 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1);
623 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2);
624 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1_MASK);
625 ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2_MASK);
626
627 /* not in use */
628 ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
629 ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
630}
631
632
633/**
634 * ath5k_ani_init() - Initialize ANI
635 * @mode: Which mode to use (auto, manual high, manual low, off)
636 *
637 * Initialize ANI according to mode.
638 */
639void
640ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
641{
642 /* ANI is only possible on 5212 and newer */
643 if (ah->ah_version < AR5K_AR5212)
644 return;
645
646 /* clear old state information */
647 memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
648
649 /* older hardware has more spur levels than newer */
650 if (ah->ah_mac_srev < AR5K_SREV_AR2414)
651 ah->ah_sc->ani_state.max_spur_level = 7;
652 else
653 ah->ah_sc->ani_state.max_spur_level = 2;
654
655 /* initial values for our ani parameters */
656 if (mode == ATH5K_ANI_MODE_OFF) {
657 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
658 } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
659 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
660 "ANI manual low -> high sensitivity\n");
661 ath5k_ani_set_noise_immunity_level(ah, 0);
662 ath5k_ani_set_spur_immunity_level(ah, 0);
663 ath5k_ani_set_firstep_level(ah, 0);
664 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
665 ath5k_ani_set_cck_weak_signal_detection(ah, true);
666 } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
667 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
668 "ANI manual high -> low sensitivity\n");
669 ath5k_ani_set_noise_immunity_level(ah,
670 ATH5K_ANI_MAX_NOISE_IMM_LVL);
671 ath5k_ani_set_spur_immunity_level(ah,
672 ah->ah_sc->ani_state.max_spur_level);
673 ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
674 ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
675 ath5k_ani_set_cck_weak_signal_detection(ah, false);
676 } else if (mode == ATH5K_ANI_MODE_AUTO) {
677 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n");
678 ath5k_ani_set_noise_immunity_level(ah, 0);
679 ath5k_ani_set_spur_immunity_level(ah, 0);
680 ath5k_ani_set_firstep_level(ah, 0);
681 ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
682 ath5k_ani_set_cck_weak_signal_detection(ah, false);
683 }
684
685 /* newer hardware has PHY error counter registers which we can use to
686 * get OFDM and CCK error counts. older hardware has to set rxfilter and
687 * report every single PHY error by calling ath5k_ani_phy_error_report()
688 */
689 if (mode == ATH5K_ANI_MODE_AUTO) {
690 if (ah->ah_capabilities.cap_has_phyerr_counters)
691 ath5k_enable_phy_err_counters(ah);
692 else
693 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) |
694 AR5K_RX_FILTER_PHYERR);
695 } else {
696 if (ah->ah_capabilities.cap_has_phyerr_counters)
697 ath5k_disable_phy_err_counters(ah);
698 else
699 ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) &
700 ~AR5K_RX_FILTER_PHYERR);
701 }
702
703 ah->ah_sc->ani_state.ani_mode = mode;
704}
705
706
707/*** DEBUG ***/
708
709#ifdef CONFIG_ATH5K_DEBUG
710
711void
712ath5k_ani_print_counters(struct ath5k_hw *ah)
713{
714 /* clears too */
715 printk(KERN_NOTICE "ACK fail\t%d\n",
716 ath5k_hw_reg_read(ah, AR5K_ACK_FAIL));
717 printk(KERN_NOTICE "RTS fail\t%d\n",
718 ath5k_hw_reg_read(ah, AR5K_RTS_FAIL));
719 printk(KERN_NOTICE "RTS success\t%d\n",
720 ath5k_hw_reg_read(ah, AR5K_RTS_OK));
721 printk(KERN_NOTICE "FCS error\t%d\n",
722 ath5k_hw_reg_read(ah, AR5K_FCS_FAIL));
723
724 /* no clear */
725 printk(KERN_NOTICE "tx\t%d\n",
726 ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX));
727 printk(KERN_NOTICE "rx\t%d\n",
728 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX));
729 printk(KERN_NOTICE "busy\t%d\n",
730 ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR));
731 printk(KERN_NOTICE "cycles\t%d\n",
732 ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE));
733
734 printk(KERN_NOTICE "AR5K_PHYERR_CNT1\t%d\n",
735 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1));
736 printk(KERN_NOTICE "AR5K_PHYERR_CNT2\t%d\n",
737 ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2));
738 printk(KERN_NOTICE "AR5K_OFDM_FIL_CNT\t%d\n",
739 ath5k_hw_reg_read(ah, AR5K_OFDM_FIL_CNT));
740 printk(KERN_NOTICE "AR5K_CCK_FIL_CNT\t%d\n",
741 ath5k_hw_reg_read(ah, AR5K_CCK_FIL_CNT));
742}
743
744#endif
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h
new file mode 100644
index 000000000000..55cf26d8522c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ani.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2010 Bruno Randolf <br1@einfach.org>
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#ifndef ANI_H
17#define ANI_H
18
19/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */
20#define ATH5K_ANI_LISTEN_PERIOD 100
21#define ATH5K_ANI_OFDM_TRIG_HIGH 500
22#define ATH5K_ANI_OFDM_TRIG_LOW 200
23#define ATH5K_ANI_CCK_TRIG_HIGH 200
24#define ATH5K_ANI_CCK_TRIG_LOW 100
25
26/* average beacon RSSI thresholds */
27#define ATH5K_ANI_RSSI_THR_HIGH 40
28#define ATH5K_ANI_RSSI_THR_LOW 7
29
30/* maximum availabe levels */
31#define ATH5K_ANI_MAX_FIRSTEP_LVL 2
32#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1
33
34
35/**
36 * enum ath5k_ani_mode - mode for ANI / noise sensitivity
37 *
38 * @ATH5K_ANI_MODE_OFF: Turn ANI off. This can be useful to just stop the ANI
39 * algorithm after it has been on auto mode.
40 * ATH5K_ANI_MODE_MANUAL_LOW: Manually set all immunity parameters to low,
41 * maximizing sensitivity. ANI will not run.
42 * ATH5K_ANI_MODE_MANUAL_HIGH: Manually set all immunity parameters to high,
43 * minimizing sensitivity. ANI will not run.
44 * ATH5K_ANI_MODE_AUTO: Automatically control immunity parameters based on the
45 * amount of OFDM and CCK frame errors (default).
46 */
47enum ath5k_ani_mode {
48 ATH5K_ANI_MODE_OFF = 0,
49 ATH5K_ANI_MODE_MANUAL_LOW = 1,
50 ATH5K_ANI_MODE_MANUAL_HIGH = 2,
51 ATH5K_ANI_MODE_AUTO = 3
52};
53
54
55/**
56 * struct ath5k_ani_state - ANI state and associated counters
57 *
58 * @max_spur_level: the maximum spur level is chip dependent
59 */
60struct ath5k_ani_state {
61 enum ath5k_ani_mode ani_mode;
62
63 /* state */
64 int noise_imm_level;
65 int spur_level;
66 int firstep_level;
67 bool ofdm_weak_sig;
68 bool cck_weak_sig;
69
70 int max_spur_level;
71
72 /* used by the algorithm */
73 unsigned int listen_time;
74 unsigned int ofdm_errors;
75 unsigned int cck_errors;
76
77 /* debug/statistics only: numbers from last ANI calibration */
78 unsigned int pfc_tx;
79 unsigned int pfc_rx;
80 unsigned int pfc_busy;
81 unsigned int pfc_cycles;
82 unsigned int last_listen;
83 unsigned int last_ofdm_errors;
84 unsigned int last_cck_errors;
85 unsigned int sum_ofdm_errors;
86 unsigned int sum_cck_errors;
87};
88
89void ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode);
90void ath5k_ani_mib_intr(struct ath5k_hw *ah);
91void ath5k_ani_calibration(struct ath5k_hw *ah);
92void ath5k_ani_phy_error_report(struct ath5k_hw *ah,
93 enum ath5k_phy_error_code phyerr);
94
95/* for manual control */
96void ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level);
97void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level);
98void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level);
99void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on);
100void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on);
101
102void ath5k_ani_print_counters(struct ath5k_hw *ah);
103
104#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index ac67f02e26d8..2785946f659a 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -202,7 +202,8 @@
202#define AR5K_TUNE_MAX_TXPOWER 63 202#define AR5K_TUNE_MAX_TXPOWER 63
203#define AR5K_TUNE_DEFAULT_TXPOWER 25 203#define AR5K_TUNE_DEFAULT_TXPOWER 25
204#define AR5K_TUNE_TPC_TXPOWER false 204#define AR5K_TUNE_TPC_TXPOWER false
205#define AR5K_TUNE_HWTXTRIES 4 205#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */
206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
206 207
207#define AR5K_INIT_CARR_SENSE_EN 1 208#define AR5K_INIT_CARR_SENSE_EN 1
208 209
@@ -614,28 +615,6 @@ struct ath5k_rx_status {
614#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ 615#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/
615#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ 616#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/
616 617
617#if 0
618/**
619 * struct ath5k_beacon_state - Per-station beacon timer state.
620 * @bs_interval: in TU's, can also include the above flags
621 * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
622 * Point Coordination Function capable AP
623 */
624struct ath5k_beacon_state {
625 u32 bs_next_beacon;
626 u32 bs_next_dtim;
627 u32 bs_interval;
628 u8 bs_dtim_period;
629 u8 bs_cfp_period;
630 u16 bs_cfp_max_duration;
631 u16 bs_cfp_du_remain;
632 u16 bs_tim_offset;
633 u16 bs_sleep_duration;
634 u16 bs_bmiss_threshold;
635 u32 bs_cfp_next;
636};
637#endif
638
639 618
640/* 619/*
641 * TSF to TU conversion: 620 * TSF to TU conversion:
@@ -822,9 +801,9 @@ struct ath5k_athchan_2ghz {
822 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold 801 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
823 * We currently do increments on interrupt by 802 * We currently do increments on interrupt by
824 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 803 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
825 * @AR5K_INT_MIB: Indicates the Management Information Base counters should be 804 * @AR5K_INT_MIB: Indicates the either Management Information Base counters or
826 * checked. We should do this with ath5k_hw_update_mib_counters() but 805 * one of the PHY error counters reached the maximum value and should be
827 * it seems we should also then do some noise immunity work. 806 * read and cleared.
828 * @AR5K_INT_RXPHY: RX PHY Error 807 * @AR5K_INT_RXPHY: RX PHY Error
829 * @AR5K_INT_RXKCM: RX Key cache miss 808 * @AR5K_INT_RXKCM: RX Key cache miss
830 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a 809 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
@@ -912,10 +891,11 @@ enum ath5k_int {
912 AR5K_INT_NOCARD = 0xffffffff 891 AR5K_INT_NOCARD = 0xffffffff
913}; 892};
914 893
915/* Software interrupts used for calibration */ 894/* mask which calibration is active at the moment */
916enum ath5k_software_interrupt { 895enum ath5k_calibration_mask {
917 AR5K_SWI_FULL_CALIBRATION = 0x01, 896 AR5K_CALIBRATION_FULL = 0x01,
918 AR5K_SWI_SHORT_CALIBRATION = 0x02, 897 AR5K_CALIBRATION_SHORT = 0x02,
898 AR5K_CALIBRATION_ANI = 0x04,
919}; 899};
920 900
921/* 901/*
@@ -1004,6 +984,8 @@ struct ath5k_capabilities {
1004 struct { 984 struct {
1005 u8 q_tx_num; 985 u8 q_tx_num;
1006 } cap_queues; 986 } cap_queues;
987
988 bool cap_has_phyerr_counters;
1007}; 989};
1008 990
1009/* size of noise floor history (keep it a power of two) */ 991/* size of noise floor history (keep it a power of two) */
@@ -1014,6 +996,15 @@ struct ath5k_nfcal_hist
1014 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ 996 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1015}; 997};
1016 998
999/**
1000 * struct avg_val - Helper structure for average calculation
1001 * @avg: contains the actual average value
1002 * @avg_weight: is used internally during calculation to prevent rounding errors
1003 */
1004struct ath5k_avg_val {
1005 int avg;
1006 int avg_weight;
1007};
1017 1008
1018/***************************************\ 1009/***************************************\
1019 HARDWARE ABSTRACTION LAYER STRUCTURE 1010 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1028,7 +1019,6 @@ struct ath5k_nfcal_hist
1028 1019
1029/* TODO: Clean up and merge with ath5k_softc */ 1020/* TODO: Clean up and merge with ath5k_softc */
1030struct ath5k_hw { 1021struct ath5k_hw {
1031 u32 ah_magic;
1032 struct ath_common common; 1022 struct ath_common common;
1033 1023
1034 struct ath5k_softc *ah_sc; 1024 struct ath5k_softc *ah_sc;
@@ -1036,7 +1026,6 @@ struct ath5k_hw {
1036 1026
1037 enum ath5k_int ah_imr; 1027 enum ath5k_int ah_imr;
1038 1028
1039 enum nl80211_iftype ah_op_mode;
1040 struct ieee80211_channel *ah_current_channel; 1029 struct ieee80211_channel *ah_current_channel;
1041 bool ah_turbo; 1030 bool ah_turbo;
1042 bool ah_calibration; 1031 bool ah_calibration;
@@ -1049,7 +1038,6 @@ struct ath5k_hw {
1049 u32 ah_phy; 1038 u32 ah_phy;
1050 u32 ah_mac_srev; 1039 u32 ah_mac_srev;
1051 u16 ah_mac_version; 1040 u16 ah_mac_version;
1052 u16 ah_mac_revision;
1053 u16 ah_phy_revision; 1041 u16 ah_phy_revision;
1054 u16 ah_radio_5ghz_revision; 1042 u16 ah_radio_5ghz_revision;
1055 u16 ah_radio_2ghz_revision; 1043 u16 ah_radio_2ghz_revision;
@@ -1071,8 +1059,6 @@ struct ath5k_hw {
1071 u8 ah_def_ant; 1059 u8 ah_def_ant;
1072 bool ah_software_retry; 1060 bool ah_software_retry;
1073 1061
1074 int ah_gpio_npins;
1075
1076 struct ath5k_capabilities ah_capabilities; 1062 struct ath5k_capabilities ah_capabilities;
1077 1063
1078 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; 1064 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1123,17 +1109,18 @@ struct ath5k_hw {
1123 1109
1124 struct ath5k_nfcal_hist ah_nfcal_hist; 1110 struct ath5k_nfcal_hist ah_nfcal_hist;
1125 1111
1112 /* average beacon RSSI in our BSS (used by ANI) */
1113 struct ath5k_avg_val ah_beacon_rssi_avg;
1114
1126 /* noise floor from last periodic calibration */ 1115 /* noise floor from last periodic calibration */
1127 s32 ah_noise_floor; 1116 s32 ah_noise_floor;
1128 1117
1129 /* Calibration timestamp */ 1118 /* Calibration timestamp */
1130 unsigned long ah_cal_tstamp; 1119 unsigned long ah_cal_next_full;
1131 1120 unsigned long ah_cal_next_ani;
1132 /* Calibration interval (secs) */
1133 u8 ah_cal_intval;
1134 1121
1135 /* Software interrupt mask */ 1122 /* Calibration mask */
1136 u8 ah_swi_mask; 1123 u8 ah_cal_mask;
1137 1124
1138 /* 1125 /*
1139 * Function pointers 1126 * Function pointers
@@ -1141,9 +1128,9 @@ struct ath5k_hw {
1141 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, 1128 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
1142 u32 size, unsigned int flags); 1129 u32 size, unsigned int flags);
1143 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1130 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1144 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, 1131 unsigned int, unsigned int, int, enum ath5k_pkt_type,
1145 unsigned int, unsigned int, unsigned int, unsigned int, 1132 unsigned int, unsigned int, unsigned int, unsigned int,
1146 unsigned int, unsigned int, unsigned int); 1133 unsigned int, unsigned int, unsigned int, unsigned int);
1147 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1134 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1148 unsigned int, unsigned int, unsigned int, unsigned int, 1135 unsigned int, unsigned int, unsigned int, unsigned int,
1149 unsigned int, unsigned int); 1136 unsigned int, unsigned int);
@@ -1158,158 +1145,145 @@ struct ath5k_hw {
1158 */ 1145 */
1159 1146
1160/* Attach/Detach Functions */ 1147/* Attach/Detach Functions */
1161extern int ath5k_hw_attach(struct ath5k_softc *sc); 1148int ath5k_hw_attach(struct ath5k_softc *sc);
1162extern void ath5k_hw_detach(struct ath5k_hw *ah); 1149void ath5k_hw_detach(struct ath5k_hw *ah);
1163 1150
1164/* LED functions */ 1151/* LED functions */
1165extern int ath5k_init_leds(struct ath5k_softc *sc); 1152int ath5k_init_leds(struct ath5k_softc *sc);
1166extern void ath5k_led_enable(struct ath5k_softc *sc); 1153void ath5k_led_enable(struct ath5k_softc *sc);
1167extern void ath5k_led_off(struct ath5k_softc *sc); 1154void ath5k_led_off(struct ath5k_softc *sc);
1168extern void ath5k_unregister_leds(struct ath5k_softc *sc); 1155void ath5k_unregister_leds(struct ath5k_softc *sc);
1169 1156
1170/* Reset Functions */ 1157/* Reset Functions */
1171extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1158int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1172extern int ath5k_hw_on_hold(struct ath5k_hw *ah); 1159int ath5k_hw_on_hold(struct ath5k_hw *ah);
1173extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); 1160int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1161 struct ieee80211_channel *channel, bool change_channel);
1162int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
1163 bool is_set);
1174/* Power management functions */ 1164/* Power management functions */
1175extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
1176 1165
1177/* DMA Related Functions */ 1166/* DMA Related Functions */
1178extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); 1167void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
1179extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); 1168int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1180extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); 1169u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
1181extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); 1170void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
1182extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1171int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1183extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); 1172int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1184extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); 1173u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
1185extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, 1174int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
1186 u32 phys_addr); 1175 u32 phys_addr);
1187extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); 1176int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
1188/* Interrupt handling */ 1177/* Interrupt handling */
1189extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); 1178bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1190extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); 1179int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1191extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum 1180enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1192ath5k_int new_mask); 1181void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
1193extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
1194 1182
1195/* EEPROM access functions */ 1183/* EEPROM access functions */
1196extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1184int ath5k_eeprom_init(struct ath5k_hw *ah);
1197extern void ath5k_eeprom_detach(struct ath5k_hw *ah); 1185void ath5k_eeprom_detach(struct ath5k_hw *ah);
1198extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1186int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1199extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1187
1201/* Protocol Control Unit Functions */ 1188/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1189extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); 1190void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1204/* BSSID Functions */ 1191/* BSSID Functions */
1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1192int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1193void ath5k_hw_set_associd(struct ath5k_hw *ah);
1207extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1194void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1208/* Receive start/stop functions */ 1195/* Receive start/stop functions */
1209extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1196void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1210extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1197void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
1211/* RX Filter functions */ 1198/* RX Filter functions */
1212extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); 1199void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1213extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1200u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1214extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); 1201void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1215extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1216extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1217/* Beacon control functions */ 1202/* Beacon control functions */
1218extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); 1203u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1219extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); 1204void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
1220extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); 1205void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1221extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); 1206void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1222extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1223#if 0
1224extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
1225extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
1226extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
1227#endif
1228/* ACK bit rate */ 1207/* ACK bit rate */
1229void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); 1208void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1230/* ACK/CTS Timeouts */
1231extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */ 1209/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); 1210unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); 1211unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); 1212unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1239/* Key table (WEP) functions */ 1213/* Key table (WEP) functions */
1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1214int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1215int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
1242extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); 1216 const struct ieee80211_key_conf *key, const u8 *mac);
1243extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); 1217int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1244 1218
1245/* Queue Control Unit, DFS Control Unit Functions */ 1219/* Queue Control Unit, DFS Control Unit Functions */
1246extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); 1220int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
1247extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 1221 struct ath5k_txq_info *queue_info);
1248 const struct ath5k_txq_info *queue_info); 1222int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
1249extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, 1223 const struct ath5k_txq_info *queue_info);
1250 enum ath5k_tx_queue queue_type, 1224int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
1251 struct ath5k_txq_info *queue_info); 1225 enum ath5k_tx_queue queue_type,
1252extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); 1226 struct ath5k_txq_info *queue_info);
1253extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1227u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1254extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); 1228void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1255extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); 1229int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1256extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); 1230int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1257 1231
1258/* Hardware Descriptor Functions */ 1232/* Hardware Descriptor Functions */
1259extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1260 1234
1261/* GPIO Functions */ 1235/* GPIO Functions */
1262extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1236void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1263extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); 1237int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1264extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); 1238int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1265extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); 1239u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1266extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); 1240int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1267extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); 1241void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
1242 u32 interrupt_level);
1268 1243
1269/* rfkill Functions */ 1244/* rfkill Functions */
1270extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); 1245void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
1271extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); 1246void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
1272 1247
1273/* Misc functions */ 1248/* Misc functions */
1274int ath5k_hw_set_capabilities(struct ath5k_hw *ah); 1249int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
1275extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); 1250int ath5k_hw_get_capability(struct ath5k_hw *ah,
1276extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); 1251 enum ath5k_capability_type cap_type, u32 capability,
1277extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); 1252 u32 *result);
1253int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
1254int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
1278 1255
1279/* Initial register settings functions */ 1256/* Initial register settings functions */
1280extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); 1257int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1281 1258
1282/* Initialize RF */ 1259/* Initialize RF */
1283extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, 1260int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
1284 struct ieee80211_channel *channel, 1261 struct ieee80211_channel *channel,
1285 unsigned int mode); 1262 unsigned int mode);
1286extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); 1263int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
1287extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); 1264enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
1288extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); 1265int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1289/* PHY/RF channel functions */ 1266/* PHY/RF channel functions */
1290extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1267bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1291extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1268int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1292/* PHY calibration */ 1269/* PHY calibration */
1293void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1270void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1294extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1271int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1295extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1272 struct ieee80211_channel *channel);
1296extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
1297extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1298/* Spur mitigation */ 1273/* Spur mitigation */
1299bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1274bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1300 struct ieee80211_channel *channel); 1275 struct ieee80211_channel *channel);
1301void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, 1276void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1302 struct ieee80211_channel *channel); 1277 struct ieee80211_channel *channel);
1303/* Misc PHY functions */ 1278/* Misc PHY functions */
1304extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); 1279u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1305extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1280int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1306/* Antenna control */ 1281/* Antenna control */
1307extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1282void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1308extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
1309extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1310/* TX power setup */ 1283/* TX power setup */
1311extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); 1284int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1312extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1285 u8 ee_mode, u8 txpower);
1286int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1313 1287
1314/* 1288/*
1315 * Functions used internaly 1289 * Functions used internaly
@@ -1335,29 +1309,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1335 iowrite32(val, ah->ah_iobase + reg); 1309 iowrite32(val, ah->ah_iobase + reg);
1336} 1310}
1337 1311
1338#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
1339/*
1340 * Check if a register write has been completed
1341 */
1342static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
1343 u32 val, bool is_set)
1344{
1345 int i;
1346 u32 data;
1347
1348 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
1349 data = ath5k_hw_reg_read(ah, reg);
1350 if (is_set && (data & flag))
1351 break;
1352 else if ((data & flag) == val)
1353 break;
1354 udelay(15);
1355 }
1356
1357 return (i <= 0) ? -EAGAIN : 0;
1358}
1359#endif
1360
1361static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) 1312static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1362{ 1313{
1363 u32 retval = 0, bit, i; 1314 u32 retval = 0, bit, i;
@@ -1370,9 +1321,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
1370 return retval; 1321 return retval;
1371} 1322}
1372 1323
1373static inline int ath5k_pad_size(int hdrlen) 1324#define AVG_SAMPLES 8
1325#define AVG_FACTOR 1000
1326
1327/**
1328 * ath5k_moving_average - Exponentially weighted moving average
1329 * @avg: average structure
1330 * @val: current value
1331 *
1332 * This implementation make use of a struct ath5k_avg_val to prevent rounding
1333 * errors.
1334 */
1335static inline struct ath5k_avg_val
1336ath5k_moving_average(const struct ath5k_avg_val avg, const int val)
1374{ 1337{
1375 return (hdrlen < 24) ? 0 : hdrlen & 3; 1338 struct ath5k_avg_val new;
1339 new.avg_weight = avg.avg_weight ?
1340 (((avg.avg_weight * ((AVG_SAMPLES) - 1)) +
1341 (val * (AVG_FACTOR))) / (AVG_SAMPLES)) :
1342 (val * (AVG_FACTOR));
1343 new.avg = new.avg_weight / (AVG_FACTOR);
1344 return new;
1376} 1345}
1377 1346
1378#endif 1347#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index dc0786cc2639..e0c244b02f05 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -114,7 +114,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
114 /* 114 /*
115 * HW information 115 * HW information
116 */ 116 */
117 ah->ah_op_mode = NL80211_IFTYPE_STATION;
118 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; 117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
119 ah->ah_turbo = false; 118 ah->ah_turbo = false;
120 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; 119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
@@ -124,6 +123,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
124 ah->ah_cw_min = AR5K_TUNE_CWMIN; 123 ah->ah_cw_min = AR5K_TUNE_CWMIN;
125 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; 124 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
126 ah->ah_software_retry = false; 125 ah->ah_software_retry = false;
126 ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
127 ah->ah_noise_floor = -95; /* until first NF calibration is run */
128 sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
127 129
128 /* 130 /*
129 * Find the mac version 131 * Find the mac version
@@ -149,7 +151,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
149 /* Get MAC, PHY and RADIO revisions */ 151 /* Get MAC, PHY and RADIO revisions */
150 ah->ah_mac_srev = srev; 152 ah->ah_mac_srev = srev;
151 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); 153 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
152 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
153 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & 154 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
154 0xffffffff; 155 0xffffffff;
155 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, 156 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
@@ -328,7 +329,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
328 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 329 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
329 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); 330 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
330 ath5k_hw_set_associd(ah); 331 ath5k_hw_set_associd(ah);
331 ath5k_hw_set_opmode(ah); 332 ath5k_hw_set_opmode(ah, sc->opmode);
332 333
333 ath5k_hw_rfgain_opt_init(ah); 334 ath5k_hw_rfgain_opt_init(ah);
334 335
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3abbe7513ab5..5f04cf38a5bc 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -59,8 +59,8 @@
59#include "base.h" 59#include "base.h"
60#include "reg.h" 60#include "reg.h"
61#include "debug.h" 61#include "debug.h"
62#include "ani.h"
62 63
63static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
64static int modparam_nohwcrypt; 64static int modparam_nohwcrypt;
65module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 65module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
66MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 66MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -199,7 +199,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
199static int ath5k_pci_suspend(struct device *dev); 199static int ath5k_pci_suspend(struct device *dev);
200static int ath5k_pci_resume(struct device *dev); 200static int ath5k_pci_resume(struct device *dev);
201 201
202SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); 202static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
203#define ATH5K_PM_OPS (&ath5k_pm_ops) 203#define ATH5K_PM_OPS (&ath5k_pm_ops)
204#else 204#else
205#define ATH5K_PM_OPS NULL 205#define ATH5K_PM_OPS NULL
@@ -231,7 +231,7 @@ static void ath5k_remove_interface(struct ieee80211_hw *hw,
231 struct ieee80211_vif *vif); 231 struct ieee80211_vif *vif);
232static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 232static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
234 int mc_count, struct dev_addr_list *mc_list); 234 struct netdev_hw_addr_list *mc_list);
235static void ath5k_configure_filter(struct ieee80211_hw *hw, 235static void ath5k_configure_filter(struct ieee80211_hw *hw,
236 unsigned int changed_flags, 236 unsigned int changed_flags,
237 unsigned int *new_flags, 237 unsigned int *new_flags,
@@ -242,6 +242,8 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
242 struct ieee80211_key_conf *key); 242 struct ieee80211_key_conf *key);
243static int ath5k_get_stats(struct ieee80211_hw *hw, 243static int ath5k_get_stats(struct ieee80211_hw *hw,
244 struct ieee80211_low_level_stats *stats); 244 struct ieee80211_low_level_stats *stats);
245static int ath5k_get_survey(struct ieee80211_hw *hw,
246 int idx, struct survey_info *survey);
245static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 247static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
246static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); 248static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
247static void ath5k_reset_tsf(struct ieee80211_hw *hw); 249static void ath5k_reset_tsf(struct ieee80211_hw *hw);
@@ -267,6 +269,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
267 .configure_filter = ath5k_configure_filter, 269 .configure_filter = ath5k_configure_filter,
268 .set_key = ath5k_set_key, 270 .set_key = ath5k_set_key,
269 .get_stats = ath5k_get_stats, 271 .get_stats = ath5k_get_stats,
272 .get_survey = ath5k_get_survey,
270 .conf_tx = NULL, 273 .conf_tx = NULL,
271 .get_tsf = ath5k_get_tsf, 274 .get_tsf = ath5k_get_tsf,
272 .set_tsf = ath5k_set_tsf, 275 .set_tsf = ath5k_set_tsf,
@@ -308,7 +311,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
308 struct ath5k_buf *bf); 311 struct ath5k_buf *bf);
309static int ath5k_txbuf_setup(struct ath5k_softc *sc, 312static int ath5k_txbuf_setup(struct ath5k_softc *sc,
310 struct ath5k_buf *bf, 313 struct ath5k_buf *bf,
311 struct ath5k_txq *txq); 314 struct ath5k_txq *txq, int padsize);
312static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 315static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
313 struct ath5k_buf *bf) 316 struct ath5k_buf *bf)
314{ 317{
@@ -365,6 +368,7 @@ static void ath5k_beacon_send(struct ath5k_softc *sc);
365static void ath5k_beacon_config(struct ath5k_softc *sc); 368static void ath5k_beacon_config(struct ath5k_softc *sc);
366static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); 369static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
367static void ath5k_tasklet_beacon(unsigned long data); 370static void ath5k_tasklet_beacon(unsigned long data);
371static void ath5k_tasklet_ani(unsigned long data);
368 372
369static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) 373static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
370{ 374{
@@ -544,8 +548,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
544 SET_IEEE80211_DEV(hw, &pdev->dev); 548 SET_IEEE80211_DEV(hw, &pdev->dev);
545 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 549 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
546 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 550 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
547 IEEE80211_HW_SIGNAL_DBM | 551 IEEE80211_HW_SIGNAL_DBM;
548 IEEE80211_HW_NOISE_DBM;
549 552
550 hw->wiphy->interface_modes = 553 hw->wiphy->interface_modes =
551 BIT(NL80211_IFTYPE_AP) | 554 BIT(NL80211_IFTYPE_AP) |
@@ -830,6 +833,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
830 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); 833 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
831 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); 834 tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
832 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); 835 tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
836 tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
833 837
834 ret = ath5k_eeprom_read_mac(ah, mac); 838 ret = ath5k_eeprom_read_mac(ah, mac);
835 if (ret) { 839 if (ret) {
@@ -1138,8 +1142,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1138 struct ath5k_hw *ah = sc->ah; 1142 struct ath5k_hw *ah = sc->ah;
1139 u32 rfilt; 1143 u32 rfilt;
1140 1144
1141 ah->ah_op_mode = sc->opmode;
1142
1143 /* configure rx filter */ 1145 /* configure rx filter */
1144 rfilt = sc->filter_flags; 1146 rfilt = sc->filter_flags;
1145 ath5k_hw_set_rx_filter(ah, rfilt); 1147 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1148,8 +1150,9 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1148 ath5k_hw_set_bssid_mask(ah, sc->bssidmask); 1150 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1149 1151
1150 /* configure operational mode */ 1152 /* configure operational mode */
1151 ath5k_hw_set_opmode(ah); 1153 ath5k_hw_set_opmode(ah, sc->opmode);
1152 1154
1155 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
1153 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); 1156 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1154} 1157}
1155 1158
@@ -1272,7 +1275,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1272 1275
1273static int 1276static int
1274ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1277ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1275 struct ath5k_txq *txq) 1278 struct ath5k_txq *txq, int padsize)
1276{ 1279{
1277 struct ath5k_hw *ah = sc->ah; 1280 struct ath5k_hw *ah = sc->ah;
1278 struct ath5k_desc *ds = bf->desc; 1281 struct ath5k_desc *ds = bf->desc;
@@ -1324,7 +1327,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1324 sc->vif, pktlen, info)); 1327 sc->vif, pktlen, info));
1325 } 1328 }
1326 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1329 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1327 ieee80211_get_hdrlen_from_skb(skb), 1330 ieee80211_get_hdrlen_from_skb(skb), padsize,
1328 get_hw_packet_type(skb), 1331 get_hw_packet_type(skb),
1329 (sc->power_level * 2), 1332 (sc->power_level * 2),
1330 hw_rate, 1333 hw_rate,
@@ -1636,7 +1639,6 @@ ath5k_txq_cleanup(struct ath5k_softc *sc)
1636 sc->txqs[i].link); 1639 sc->txqs[i].link);
1637 } 1640 }
1638 } 1641 }
1639 ieee80211_wake_queues(sc->hw); /* XXX move to callers */
1640 1642
1641 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) 1643 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1642 if (sc->txqs[i].setup) 1644 if (sc->txqs[i].setup)
@@ -1807,6 +1809,86 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1807} 1809}
1808 1810
1809static void 1811static void
1812ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
1813{
1814 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1815 struct ath5k_hw *ah = sc->ah;
1816 struct ath_common *common = ath5k_hw_common(ah);
1817
1818 /* only beacons from our BSSID */
1819 if (!ieee80211_is_beacon(mgmt->frame_control) ||
1820 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0)
1821 return;
1822
1823 ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg,
1824 rssi);
1825
1826 /* in IBSS mode we should keep RSSI statistics per neighbour */
1827 /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */
1828}
1829
1830/*
1831 * Compute padding position. skb must contains an IEEE 802.11 frame
1832 */
1833static int ath5k_common_padpos(struct sk_buff *skb)
1834{
1835 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1836 __le16 frame_control = hdr->frame_control;
1837 int padpos = 24;
1838
1839 if (ieee80211_has_a4(frame_control)) {
1840 padpos += ETH_ALEN;
1841 }
1842 if (ieee80211_is_data_qos(frame_control)) {
1843 padpos += IEEE80211_QOS_CTL_LEN;
1844 }
1845
1846 return padpos;
1847}
1848
1849/*
1850 * This function expects a 802.11 frame and returns the number of
1851 * bytes added, or -1 if we don't have enought header room.
1852 */
1853
1854static int ath5k_add_padding(struct sk_buff *skb)
1855{
1856 int padpos = ath5k_common_padpos(skb);
1857 int padsize = padpos & 3;
1858
1859 if (padsize && skb->len>padpos) {
1860
1861 if (skb_headroom(skb) < padsize)
1862 return -1;
1863
1864 skb_push(skb, padsize);
1865 memmove(skb->data, skb->data+padsize, padpos);
1866 return padsize;
1867 }
1868
1869 return 0;
1870}
1871
1872/*
1873 * This function expects a 802.11 frame and returns the number of
1874 * bytes removed
1875 */
1876
1877static int ath5k_remove_padding(struct sk_buff *skb)
1878{
1879 int padpos = ath5k_common_padpos(skb);
1880 int padsize = padpos & 3;
1881
1882 if (padsize && skb->len>=padpos+padsize) {
1883 memmove(skb->data + padsize, skb->data, padpos);
1884 skb_pull(skb, padsize);
1885 return padsize;
1886 }
1887
1888 return 0;
1889}
1890
1891static void
1810ath5k_tasklet_rx(unsigned long data) 1892ath5k_tasklet_rx(unsigned long data)
1811{ 1893{
1812 struct ieee80211_rx_status *rxs; 1894 struct ieee80211_rx_status *rxs;
@@ -1819,8 +1901,6 @@ ath5k_tasklet_rx(unsigned long data)
1819 struct ath5k_buf *bf; 1901 struct ath5k_buf *bf;
1820 struct ath5k_desc *ds; 1902 struct ath5k_desc *ds;
1821 int ret; 1903 int ret;
1822 int hdrlen;
1823 int padsize;
1824 int rx_flag; 1904 int rx_flag;
1825 1905
1826 spin_lock(&sc->rxbuflock); 1906 spin_lock(&sc->rxbuflock);
@@ -1845,18 +1925,24 @@ ath5k_tasklet_rx(unsigned long data)
1845 break; 1925 break;
1846 else if (unlikely(ret)) { 1926 else if (unlikely(ret)) {
1847 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 1927 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1928 sc->stats.rxerr_proc++;
1848 spin_unlock(&sc->rxbuflock); 1929 spin_unlock(&sc->rxbuflock);
1849 return; 1930 return;
1850 } 1931 }
1851 1932
1852 if (unlikely(rs.rs_more)) { 1933 sc->stats.rx_all_count++;
1853 ATH5K_WARN(sc, "unsupported jumbo\n");
1854 goto next;
1855 }
1856 1934
1857 if (unlikely(rs.rs_status)) { 1935 if (unlikely(rs.rs_status)) {
1858 if (rs.rs_status & AR5K_RXERR_PHY) 1936 if (rs.rs_status & AR5K_RXERR_CRC)
1937 sc->stats.rxerr_crc++;
1938 if (rs.rs_status & AR5K_RXERR_FIFO)
1939 sc->stats.rxerr_fifo++;
1940 if (rs.rs_status & AR5K_RXERR_PHY) {
1941 sc->stats.rxerr_phy++;
1942 if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32)
1943 sc->stats.rxerr_phy_code[rs.rs_phyerr]++;
1859 goto next; 1944 goto next;
1945 }
1860 if (rs.rs_status & AR5K_RXERR_DECRYPT) { 1946 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1861 /* 1947 /*
1862 * Decrypt error. If the error occurred 1948 * Decrypt error. If the error occurred
@@ -1868,12 +1954,14 @@ ath5k_tasklet_rx(unsigned long data)
1868 * 1954 *
1869 * XXX do key cache faulting 1955 * XXX do key cache faulting
1870 */ 1956 */
1957 sc->stats.rxerr_decrypt++;
1871 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && 1958 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1872 !(rs.rs_status & AR5K_RXERR_CRC)) 1959 !(rs.rs_status & AR5K_RXERR_CRC))
1873 goto accept; 1960 goto accept;
1874 } 1961 }
1875 if (rs.rs_status & AR5K_RXERR_MIC) { 1962 if (rs.rs_status & AR5K_RXERR_MIC) {
1876 rx_flag |= RX_FLAG_MMIC_ERROR; 1963 rx_flag |= RX_FLAG_MMIC_ERROR;
1964 sc->stats.rxerr_mic++;
1877 goto accept; 1965 goto accept;
1878 } 1966 }
1879 1967
@@ -1883,6 +1971,12 @@ ath5k_tasklet_rx(unsigned long data)
1883 sc->opmode != NL80211_IFTYPE_MONITOR) 1971 sc->opmode != NL80211_IFTYPE_MONITOR)
1884 goto next; 1972 goto next;
1885 } 1973 }
1974
1975 if (unlikely(rs.rs_more)) {
1976 sc->stats.rxerr_jumbo++;
1977 goto next;
1978
1979 }
1886accept: 1980accept:
1887 next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); 1981 next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
1888 1982
@@ -1905,12 +1999,8 @@ accept:
1905 * bytes and we can optimize this a bit. In addition, we must 1999 * bytes and we can optimize this a bit. In addition, we must
1906 * not try to remove padding from short control frames that do 2000 * not try to remove padding from short control frames that do
1907 * not have payload. */ 2001 * not have payload. */
1908 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2002 ath5k_remove_padding(skb);
1909 padsize = ath5k_pad_size(hdrlen); 2003
1910 if (padsize) {
1911 memmove(skb->data + padsize, skb->data, hdrlen);
1912 skb_pull(skb, padsize);
1913 }
1914 rxs = IEEE80211_SKB_RXCB(skb); 2004 rxs = IEEE80211_SKB_RXCB(skb);
1915 2005
1916 /* 2006 /*
@@ -1939,10 +2029,15 @@ accept:
1939 rxs->freq = sc->curchan->center_freq; 2029 rxs->freq = sc->curchan->center_freq;
1940 rxs->band = sc->curband->band; 2030 rxs->band = sc->curband->band;
1941 2031
1942 rxs->noise = sc->ah->ah_noise_floor; 2032 rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi;
1943 rxs->signal = rxs->noise + rs.rs_rssi;
1944 2033
1945 rxs->antenna = rs.rs_antenna; 2034 rxs->antenna = rs.rs_antenna;
2035
2036 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2037 sc->stats.antenna_rx[rs.rs_antenna]++;
2038 else
2039 sc->stats.antenna_rx[0]++; /* invalid */
2040
1946 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 2041 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1947 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 2042 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1948 2043
@@ -1952,6 +2047,8 @@ accept:
1952 2047
1953 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 2048 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1954 2049
2050 ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi);
2051
1955 /* check beacons in IBSS mode */ 2052 /* check beacons in IBSS mode */
1956 if (sc->opmode == NL80211_IFTYPE_ADHOC) 2053 if (sc->opmode == NL80211_IFTYPE_ADHOC)
1957 ath5k_check_ibss_tsf(sc, skb, rxs); 2054 ath5k_check_ibss_tsf(sc, skb, rxs);
@@ -1988,6 +2085,17 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1988 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 2085 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1989 ds = bf->desc; 2086 ds = bf->desc;
1990 2087
2088 /*
2089 * It's possible that the hardware can say the buffer is
2090 * completed when it hasn't yet loaded the ds_link from
2091 * host memory and moved on. If there are more TX
2092 * descriptors in the queue, wait for TXDP to change
2093 * before processing this one.
2094 */
2095 if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr &&
2096 !list_is_last(&bf->list, &txq->q))
2097 break;
2098
1991 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); 2099 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
1992 if (unlikely(ret == -EINPROGRESS)) 2100 if (unlikely(ret == -EINPROGRESS))
1993 break; 2101 break;
@@ -1997,6 +2105,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1997 break; 2105 break;
1998 } 2106 }
1999 2107
2108 sc->stats.tx_all_count++;
2000 skb = bf->skb; 2109 skb = bf->skb;
2001 info = IEEE80211_SKB_CB(skb); 2110 info = IEEE80211_SKB_CB(skb);
2002 bf->skb = NULL; 2111 bf->skb = NULL;
@@ -2022,14 +2131,31 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
2022 info->status.rates[ts.ts_final_idx].count++; 2131 info->status.rates[ts.ts_final_idx].count++;
2023 2132
2024 if (unlikely(ts.ts_status)) { 2133 if (unlikely(ts.ts_status)) {
2025 sc->ll_stats.dot11ACKFailureCount++; 2134 sc->stats.ack_fail++;
2026 if (ts.ts_status & AR5K_TXERR_FILT) 2135 if (ts.ts_status & AR5K_TXERR_FILT) {
2027 info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2136 info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2137 sc->stats.txerr_filt++;
2138 }
2139 if (ts.ts_status & AR5K_TXERR_XRETRY)
2140 sc->stats.txerr_retry++;
2141 if (ts.ts_status & AR5K_TXERR_FIFO)
2142 sc->stats.txerr_fifo++;
2028 } else { 2143 } else {
2029 info->flags |= IEEE80211_TX_STAT_ACK; 2144 info->flags |= IEEE80211_TX_STAT_ACK;
2030 info->status.ack_signal = ts.ts_rssi; 2145 info->status.ack_signal = ts.ts_rssi;
2031 } 2146 }
2032 2147
2148 /*
2149 * Remove MAC header padding before giving the frame
2150 * back to mac80211.
2151 */
2152 ath5k_remove_padding(skb);
2153
2154 if (ts.ts_antenna > 0 && ts.ts_antenna < 5)
2155 sc->stats.antenna_tx[ts.ts_antenna]++;
2156 else
2157 sc->stats.antenna_tx[0]++; /* invalid */
2158
2033 ieee80211_tx_status(sc->hw, skb); 2159 ieee80211_tx_status(sc->hw, skb);
2034 2160
2035 spin_lock(&sc->txbuflock); 2161 spin_lock(&sc->txbuflock);
@@ -2073,6 +2199,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2073 int ret = 0; 2199 int ret = 0;
2074 u8 antenna; 2200 u8 antenna;
2075 u32 flags; 2201 u32 flags;
2202 const int padsize = 0;
2076 2203
2077 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, 2204 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
2078 PCI_DMA_TODEVICE); 2205 PCI_DMA_TODEVICE);
@@ -2120,7 +2247,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
2120 * from tx power (value is in dB units already) */ 2247 * from tx power (value is in dB units already) */
2121 ds->ds_data = bf->skbaddr; 2248 ds->ds_data = bf->skbaddr;
2122 ret = ah->ah_setup_tx_desc(ah, ds, skb->len, 2249 ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
2123 ieee80211_get_hdrlen_from_skb(skb), 2250 ieee80211_get_hdrlen_from_skb(skb), padsize,
2124 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), 2251 AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
2125 ieee80211_get_tx_rate(sc->hw, info)->hw_value, 2252 ieee80211_get_tx_rate(sc->hw, info)->hw_value,
2126 1, AR5K_TXKEYIX_INVALID, 2253 1, AR5K_TXKEYIX_INVALID,
@@ -2407,9 +2534,6 @@ ath5k_init(struct ath5k_softc *sc)
2407 */ 2534 */
2408 ath5k_stop_locked(sc); 2535 ath5k_stop_locked(sc);
2409 2536
2410 /* Set PHY calibration interval */
2411 ah->ah_cal_intval = ath5k_calinterval;
2412
2413 /* 2537 /*
2414 * The basic interface to setting the hardware in a good 2538 * The basic interface to setting the hardware in a good
2415 * state is ``reset''. On return the hardware is known to 2539 * state is ``reset''. On return the hardware is known to
@@ -2421,7 +2545,8 @@ ath5k_init(struct ath5k_softc *sc)
2421 sc->curband = &sc->sbands[sc->curchan->band]; 2545 sc->curband = &sc->sbands[sc->curchan->band];
2422 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | 2546 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2423 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2547 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2424 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI; 2548 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2549
2425 ret = ath5k_reset(sc, NULL); 2550 ret = ath5k_reset(sc, NULL);
2426 if (ret) 2551 if (ret)
2427 goto done; 2552 goto done;
@@ -2435,8 +2560,7 @@ ath5k_init(struct ath5k_softc *sc)
2435 for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) 2560 for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
2436 ath5k_hw_reset_key(ah, i); 2561 ath5k_hw_reset_key(ah, i);
2437 2562
2438 /* Set ack to be sent at low bit-rates */ 2563 ath5k_hw_set_ack_bitrate_high(ah, true);
2439 ath5k_hw_set_ack_bitrate_high(ah, false);
2440 ret = 0; 2564 ret = 0;
2441done: 2565done:
2442 mmiowb(); 2566 mmiowb();
@@ -2533,12 +2657,33 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2533 tasklet_kill(&sc->restq); 2657 tasklet_kill(&sc->restq);
2534 tasklet_kill(&sc->calib); 2658 tasklet_kill(&sc->calib);
2535 tasklet_kill(&sc->beacontq); 2659 tasklet_kill(&sc->beacontq);
2660 tasklet_kill(&sc->ani_tasklet);
2536 2661
2537 ath5k_rfkill_hw_stop(sc->ah); 2662 ath5k_rfkill_hw_stop(sc->ah);
2538 2663
2539 return ret; 2664 return ret;
2540} 2665}
2541 2666
2667static void
2668ath5k_intr_calibration_poll(struct ath5k_hw *ah)
2669{
2670 if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) &&
2671 !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) {
2672 /* run ANI only when full calibration is not active */
2673 ah->ah_cal_next_ani = jiffies +
2674 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
2675 tasklet_schedule(&ah->ah_sc->ani_tasklet);
2676
2677 } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) {
2678 ah->ah_cal_next_full = jiffies +
2679 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
2680 tasklet_schedule(&ah->ah_sc->calib);
2681 }
2682 /* we could use SWI to generate enough interrupts to meet our
2683 * calibration interval requirements, if necessary:
2684 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
2685}
2686
2542static irqreturn_t 2687static irqreturn_t
2543ath5k_intr(int irq, void *dev_id) 2688ath5k_intr(int irq, void *dev_id)
2544{ 2689{
@@ -2562,7 +2707,20 @@ ath5k_intr(int irq, void *dev_id)
2562 */ 2707 */
2563 tasklet_schedule(&sc->restq); 2708 tasklet_schedule(&sc->restq);
2564 } else if (unlikely(status & AR5K_INT_RXORN)) { 2709 } else if (unlikely(status & AR5K_INT_RXORN)) {
2565 tasklet_schedule(&sc->restq); 2710 /*
2711 * Receive buffers are full. Either the bus is busy or
2712 * the CPU is not fast enough to process all received
2713 * frames.
2714 * Older chipsets need a reset to come out of this
2715 * condition, but we treat it as RX for newer chips.
2716 * We don't know exactly which versions need a reset -
2717 * this guess is copied from the HAL.
2718 */
2719 sc->stats.rxorn_intr++;
2720 if (ah->ah_mac_srev < AR5K_SREV_AR5212)
2721 tasklet_schedule(&sc->restq);
2722 else
2723 tasklet_schedule(&sc->rxtq);
2566 } else { 2724 } else {
2567 if (status & AR5K_INT_SWBA) { 2725 if (status & AR5K_INT_SWBA) {
2568 tasklet_hi_schedule(&sc->beacontq); 2726 tasklet_hi_schedule(&sc->beacontq);
@@ -2587,15 +2745,10 @@ ath5k_intr(int irq, void *dev_id)
2587 if (status & AR5K_INT_BMISS) { 2745 if (status & AR5K_INT_BMISS) {
2588 /* TODO */ 2746 /* TODO */
2589 } 2747 }
2590 if (status & AR5K_INT_SWI) {
2591 tasklet_schedule(&sc->calib);
2592 }
2593 if (status & AR5K_INT_MIB) { 2748 if (status & AR5K_INT_MIB) {
2594 /* 2749 sc->stats.mib_intr++;
2595 * These stats are also used for ANI i think 2750 ath5k_hw_update_mib_counters(ah);
2596 * so how about updating them more often ? 2751 ath5k_ani_mib_intr(ah);
2597 */
2598 ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
2599 } 2752 }
2600 if (status & AR5K_INT_GPIO) 2753 if (status & AR5K_INT_GPIO)
2601 tasklet_schedule(&sc->rf_kill.toggleq); 2754 tasklet_schedule(&sc->rf_kill.toggleq);
@@ -2606,7 +2759,7 @@ ath5k_intr(int irq, void *dev_id)
2606 if (unlikely(!counter)) 2759 if (unlikely(!counter))
2607 ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); 2760 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2608 2761
2609 ath5k_hw_calibration_poll(ah); 2762 ath5k_intr_calibration_poll(ah);
2610 2763
2611 return IRQ_HANDLED; 2764 return IRQ_HANDLED;
2612} 2765}
@@ -2630,8 +2783,7 @@ ath5k_tasklet_calibrate(unsigned long data)
2630 struct ath5k_hw *ah = sc->ah; 2783 struct ath5k_hw *ah = sc->ah;
2631 2784
2632 /* Only full calibration for now */ 2785 /* Only full calibration for now */
2633 if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION) 2786 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2634 return;
2635 2787
2636 /* Stop queues so that calibration 2788 /* Stop queues so that calibration
2637 * doesn't interfere with tx */ 2789 * doesn't interfere with tx */
@@ -2647,18 +2799,29 @@ ath5k_tasklet_calibrate(unsigned long data)
2647 * to load new gain values. 2799 * to load new gain values.
2648 */ 2800 */
2649 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); 2801 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
2650 ath5k_reset_wake(sc); 2802 ath5k_reset(sc, sc->curchan);
2651 } 2803 }
2652 if (ath5k_hw_phy_calibrate(ah, sc->curchan)) 2804 if (ath5k_hw_phy_calibrate(ah, sc->curchan))
2653 ATH5K_ERR(sc, "calibration of channel %u failed\n", 2805 ATH5K_ERR(sc, "calibration of channel %u failed\n",
2654 ieee80211_frequency_to_channel( 2806 ieee80211_frequency_to_channel(
2655 sc->curchan->center_freq)); 2807 sc->curchan->center_freq));
2656 2808
2657 ah->ah_swi_mask = 0;
2658
2659 /* Wake queues */ 2809 /* Wake queues */
2660 ieee80211_wake_queues(sc->hw); 2810 ieee80211_wake_queues(sc->hw);
2661 2811
2812 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2813}
2814
2815
2816static void
2817ath5k_tasklet_ani(unsigned long data)
2818{
2819 struct ath5k_softc *sc = (void *)data;
2820 struct ath5k_hw *ah = sc->ah;
2821
2822 ah->ah_cal_mask |= AR5K_CALIBRATION_ANI;
2823 ath5k_ani_calibration(ah);
2824 ah->ah_cal_mask &= ~AR5K_CALIBRATION_ANI;
2662} 2825}
2663 2826
2664 2827
@@ -2680,7 +2843,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2680 struct ath5k_softc *sc = hw->priv; 2843 struct ath5k_softc *sc = hw->priv;
2681 struct ath5k_buf *bf; 2844 struct ath5k_buf *bf;
2682 unsigned long flags; 2845 unsigned long flags;
2683 int hdrlen;
2684 int padsize; 2846 int padsize;
2685 2847
2686 ath5k_debug_dump_skb(sc, skb, "TX ", 1); 2848 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
@@ -2692,17 +2854,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2692 * the hardware expects the header padded to 4 byte boundaries 2854 * the hardware expects the header padded to 4 byte boundaries
2693 * if this is not the case we add the padding after the header 2855 * if this is not the case we add the padding after the header
2694 */ 2856 */
2695 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 2857 padsize = ath5k_add_padding(skb);
2696 padsize = ath5k_pad_size(hdrlen); 2858 if (padsize < 0) {
2697 if (padsize) { 2859 ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
2698 2860 " headroom to pad");
2699 if (skb_headroom(skb) < padsize) { 2861 goto drop_packet;
2700 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2701 " headroom to pad %d\n", hdrlen, padsize);
2702 goto drop_packet;
2703 }
2704 skb_push(skb, padsize);
2705 memmove(skb->data, skb->data+padsize, hdrlen);
2706 } 2862 }
2707 2863
2708 spin_lock_irqsave(&sc->txbuflock, flags); 2864 spin_lock_irqsave(&sc->txbuflock, flags);
@@ -2721,7 +2877,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
2721 2877
2722 bf->skb = skb; 2878 bf->skb = skb;
2723 2879
2724 if (ath5k_txbuf_setup(sc, bf, txq)) { 2880 if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
2725 bf->skb = NULL; 2881 bf->skb = NULL;
2726 spin_lock_irqsave(&sc->txbuflock, flags); 2882 spin_lock_irqsave(&sc->txbuflock, flags);
2727 list_add_tail(&bf->list, &sc->txbuf); 2883 list_add_tail(&bf->list, &sc->txbuf);
@@ -2768,6 +2924,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2768 goto err; 2924 goto err;
2769 } 2925 }
2770 2926
2927 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
2928
2771 /* 2929 /*
2772 * Change channels and update the h/w rate map if we're switching; 2930 * Change channels and update the h/w rate map if we're switching;
2773 * e.g. 11a to 11b/g. 2931 * e.g. 11a to 11b/g.
@@ -2836,6 +2994,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2836 goto end; 2994 goto end;
2837 } 2995 }
2838 2996
2997 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode);
2998
2839 ath5k_hw_set_lladdr(sc->ah, vif->addr); 2999 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2840 ath5k_mode_setup(sc); 3000 ath5k_mode_setup(sc);
2841 3001
@@ -2906,7 +3066,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2906 * then we must allow the user to set how many tx antennas we 3066 * then we must allow the user to set how many tx antennas we
2907 * have available 3067 * have available
2908 */ 3068 */
2909 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 3069 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
2910 3070
2911unlock: 3071unlock:
2912 mutex_unlock(&sc->lock); 3072 mutex_unlock(&sc->lock);
@@ -2914,22 +3074,20 @@ unlock:
2914} 3074}
2915 3075
2916static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 3076static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2917 int mc_count, struct dev_addr_list *mclist) 3077 struct netdev_hw_addr_list *mc_list)
2918{ 3078{
2919 u32 mfilt[2], val; 3079 u32 mfilt[2], val;
2920 int i;
2921 u8 pos; 3080 u8 pos;
3081 struct netdev_hw_addr *ha;
2922 3082
2923 mfilt[0] = 0; 3083 mfilt[0] = 0;
2924 mfilt[1] = 1; 3084 mfilt[1] = 1;
2925 3085
2926 for (i = 0; i < mc_count; i++) { 3086 netdev_hw_addr_list_for_each(ha, mc_list) {
2927 if (!mclist)
2928 break;
2929 /* calculate XOR of eight 6-bit values */ 3087 /* calculate XOR of eight 6-bit values */
2930 val = get_unaligned_le32(mclist->dmi_addr + 0); 3088 val = get_unaligned_le32(ha->addr + 0);
2931 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3089 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2932 val = get_unaligned_le32(mclist->dmi_addr + 3); 3090 val = get_unaligned_le32(ha->addr + 3);
2933 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; 3091 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2934 pos &= 0x3f; 3092 pos &= 0x3f;
2935 mfilt[pos / 32] |= (1 << (pos % 32)); 3093 mfilt[pos / 32] |= (1 << (pos % 32));
@@ -2937,8 +3095,7 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2937 * but not sure, needs testing, if we do use this we'd 3095 * but not sure, needs testing, if we do use this we'd
2938 * neet to inform below to not reset the mcast */ 3096 * neet to inform below to not reset the mcast */
2939 /* ath5k_hw_set_mcast_filterindex(ah, 3097 /* ath5k_hw_set_mcast_filterindex(ah,
2940 * mclist->dmi_addr[5]); */ 3098 * ha->addr[5]); */
2941 mclist = mclist->next;
2942 } 3099 }
2943 3100
2944 return ((u64)(mfilt[1]) << 32) | mfilt[0]; 3101 return ((u64)(mfilt[1]) << 32) | mfilt[0];
@@ -3124,12 +3281,30 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3124 struct ieee80211_low_level_stats *stats) 3281 struct ieee80211_low_level_stats *stats)
3125{ 3282{
3126 struct ath5k_softc *sc = hw->priv; 3283 struct ath5k_softc *sc = hw->priv;
3127 struct ath5k_hw *ah = sc->ah;
3128 3284
3129 /* Force update */ 3285 /* Force update */
3130 ath5k_hw_update_mib_counters(ah, &sc->ll_stats); 3286 ath5k_hw_update_mib_counters(sc->ah);
3287
3288 stats->dot11ACKFailureCount = sc->stats.ack_fail;
3289 stats->dot11RTSFailureCount = sc->stats.rts_fail;
3290 stats->dot11RTSSuccessCount = sc->stats.rts_ok;
3291 stats->dot11FCSErrorCount = sc->stats.fcs_error;
3292
3293 return 0;
3294}
3295
3296static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
3297 struct survey_info *survey)
3298{
3299 struct ath5k_softc *sc = hw->priv;
3300 struct ieee80211_conf *conf = &hw->conf;
3301
3302 if (idx != 0)
3303 return -ENOENT;
3131 3304
3132 memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); 3305 survey->channel = conf->channel;
3306 survey->filled = SURVEY_INFO_NOISE_DBM;
3307 survey->noise = sc->ah->ah_noise_floor;
3133 3308
3134 return 0; 3309 return 0;
3135} 3310}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 7e1a88a5abdb..56221bc7c8cd 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -50,6 +50,7 @@
50 50
51#include "ath5k.h" 51#include "ath5k.h"
52#include "debug.h" 52#include "debug.h"
53#include "ani.h"
53 54
54#include "../regd.h" 55#include "../regd.h"
55#include "../ath.h" 56#include "../ath.h"
@@ -105,6 +106,38 @@ struct ath5k_rfkill {
105 struct tasklet_struct toggleq; 106 struct tasklet_struct toggleq;
106}; 107};
107 108
109/* statistics */
110struct ath5k_statistics {
111 /* antenna use */
112 unsigned int antenna_rx[5]; /* frames count per antenna RX */
113 unsigned int antenna_tx[5]; /* frames count per antenna TX */
114
115 /* frame errors */
116 unsigned int rx_all_count; /* all RX frames, including errors */
117 unsigned int tx_all_count; /* all TX frames, including errors */
118 unsigned int rxerr_crc;
119 unsigned int rxerr_phy;
120 unsigned int rxerr_phy_code[32];
121 unsigned int rxerr_fifo;
122 unsigned int rxerr_decrypt;
123 unsigned int rxerr_mic;
124 unsigned int rxerr_proc;
125 unsigned int rxerr_jumbo;
126 unsigned int txerr_retry;
127 unsigned int txerr_fifo;
128 unsigned int txerr_filt;
129
130 /* MIB counters */
131 unsigned int ack_fail;
132 unsigned int rts_fail;
133 unsigned int rts_ok;
134 unsigned int fcs_error;
135 unsigned int beacons;
136
137 unsigned int mib_intr;
138 unsigned int rxorn_intr;
139};
140
108#if CHAN_DEBUG 141#if CHAN_DEBUG
109#define ATH_CHAN_MAX (26+26+26+200+200) 142#define ATH_CHAN_MAX (26+26+26+200+200)
110#else 143#else
@@ -117,7 +150,6 @@ struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 150 struct pci_dev *pdev; /* for dma mapping */
118 void __iomem *iobase; /* address of the device */ 151 void __iomem *iobase; /* address of the device */
119 struct mutex lock; /* dev-level lock */ 152 struct mutex lock; /* dev-level lock */
120 struct ieee80211_low_level_stats ll_stats;
121 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 153 struct ieee80211_hw *hw; /* IEEE 802.11 common */
122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 154 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
123 struct ieee80211_channel channels[ATH_CHAN_MAX]; 155 struct ieee80211_channel channels[ATH_CHAN_MAX];
@@ -191,6 +223,11 @@ struct ath5k_softc {
191 int power_level; /* Requested tx power in dbm */ 223 int power_level; /* Requested tx power in dbm */
192 bool assoc; /* associate state */ 224 bool assoc; /* associate state */
193 bool enable_beacon; /* true if beacons are on */ 225 bool enable_beacon; /* true if beacons are on */
226
227 struct ath5k_statistics stats;
228
229 struct ath5k_ani_state ani_state;
230 struct tasklet_struct ani_tasklet; /* ANI calibration */
194}; 231};
195 232
196#define ath5k_hw_hasbssidmask(_ah) \ 233#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 367a6c7d3cc7..74f007126f41 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -102,9 +102,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
102 } 102 }
103 } 103 }
104 104
105 /* GPIO */
106 ah->ah_gpio_npins = AR5K_NUM_GPIO;
107
108 /* Set number of supported TX queues */ 105 /* Set number of supported TX queues */
109 if (ah->ah_version == AR5K_AR5210) 106 if (ah->ah_version == AR5K_AR5210)
110 ah->ah_capabilities.cap_queues.q_tx_num = 107 ah->ah_capabilities.cap_queues.q_tx_num =
@@ -112,6 +109,12 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
112 else 109 else
113 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; 110 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
114 111
112 /* newer hardware has PHY error counters */
113 if (ah->ah_mac_srev >= AR5K_SREV_AR5213A)
114 ah->ah_capabilities.cap_has_phyerr_counters = true;
115 else
116 ah->ah_capabilities.cap_has_phyerr_counters = false;
117
115 return 0; 118 return 0;
116} 119}
117 120
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 747508c15d34..6fb5c5ffa5b1 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -69,6 +69,7 @@ module_param_named(debug, ath5k_debug, uint, 0);
69 69
70#include <linux/seq_file.h> 70#include <linux/seq_file.h>
71#include "reg.h" 71#include "reg.h"
72#include "ani.h"
72 73
73static struct dentry *ath5k_global_debugfs; 74static struct dentry *ath5k_global_debugfs;
74 75
@@ -307,6 +308,7 @@ static const struct {
307 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, 308 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
308 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, 309 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
309 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, 310 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
311 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
310 { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, 312 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
311}; 313};
312 314
@@ -364,6 +366,369 @@ static const struct file_operations fops_debug = {
364}; 366};
365 367
366 368
369/* debugfs: antenna */
370
371static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
372 size_t count, loff_t *ppos)
373{
374 struct ath5k_softc *sc = file->private_data;
375 char buf[700];
376 unsigned int len = 0;
377 unsigned int i;
378 unsigned int v;
379
380 len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n",
381 sc->ah->ah_ant_mode);
382 len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n",
383 sc->ah->ah_def_ant);
384 len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n",
385 sc->ah->ah_tx_ant);
386
387 len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n");
388 for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
389 len += snprintf(buf+len, sizeof(buf)-len,
390 "[antenna %d]\t%d\t%d\n",
391 i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]);
392 }
393 len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n",
394 sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]);
395
396 v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA);
397 len += snprintf(buf+len, sizeof(buf)-len,
398 "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
399
400 v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1);
401 len += snprintf(buf+len, sizeof(buf)-len,
402 "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
403 (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
404 len += snprintf(buf+len, sizeof(buf)-len,
405 "AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
406 (v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
407 len += snprintf(buf+len, sizeof(buf)-len,
408 "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
409 (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
410 len += snprintf(buf+len, sizeof(buf)-len,
411 "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
412 (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
413
414 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL);
415 len += snprintf(buf+len, sizeof(buf)-len,
416 "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
417 (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
418
419 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART);
420 len += snprintf(buf+len, sizeof(buf)-len,
421 "AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
422 (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
423
424 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV);
425 len += snprintf(buf+len, sizeof(buf)-len,
426 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
427 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
428
429 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
430}
431
432static ssize_t write_file_antenna(struct file *file,
433 const char __user *userbuf,
434 size_t count, loff_t *ppos)
435{
436 struct ath5k_softc *sc = file->private_data;
437 unsigned int i;
438 char buf[20];
439
440 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
441 return -EFAULT;
442
443 if (strncmp(buf, "diversity", 9) == 0) {
444 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
445 printk(KERN_INFO "ath5k debug: enable diversity\n");
446 } else if (strncmp(buf, "fixed-a", 7) == 0) {
447 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
448 printk(KERN_INFO "ath5k debugfs: fixed antenna A\n");
449 } else if (strncmp(buf, "fixed-b", 7) == 0) {
450 ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
451 printk(KERN_INFO "ath5k debug: fixed antenna B\n");
452 } else if (strncmp(buf, "clear", 5) == 0) {
453 for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
454 sc->stats.antenna_rx[i] = 0;
455 sc->stats.antenna_tx[i] = 0;
456 }
457 printk(KERN_INFO "ath5k debug: cleared antenna stats\n");
458 }
459 return count;
460}
461
462static const struct file_operations fops_antenna = {
463 .read = read_file_antenna,
464 .write = write_file_antenna,
465 .open = ath5k_debugfs_open,
466 .owner = THIS_MODULE,
467};
468
469
470/* debugfs: frameerrors */
471
472static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
473 size_t count, loff_t *ppos)
474{
475 struct ath5k_softc *sc = file->private_data;
476 struct ath5k_statistics *st = &sc->stats;
477 char buf[700];
478 unsigned int len = 0;
479 int i;
480
481 len += snprintf(buf+len, sizeof(buf)-len,
482 "RX\n---------------------\n");
483 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n",
484 st->rxerr_crc,
485 st->rx_all_count > 0 ?
486 st->rxerr_crc*100/st->rx_all_count : 0);
487 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n",
488 st->rxerr_phy,
489 st->rx_all_count > 0 ?
490 st->rxerr_phy*100/st->rx_all_count : 0);
491 for (i = 0; i < 32; i++) {
492 if (st->rxerr_phy_code[i])
493 len += snprintf(buf+len, sizeof(buf)-len,
494 " phy_err[%d]\t%d\n",
495 i, st->rxerr_phy_code[i]);
496 }
497
498 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
499 st->rxerr_fifo,
500 st->rx_all_count > 0 ?
501 st->rxerr_fifo*100/st->rx_all_count : 0);
502 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n",
503 st->rxerr_decrypt,
504 st->rx_all_count > 0 ?
505 st->rxerr_decrypt*100/st->rx_all_count : 0);
506 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n",
507 st->rxerr_mic,
508 st->rx_all_count > 0 ?
509 st->rxerr_mic*100/st->rx_all_count : 0);
510 len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n",
511 st->rxerr_proc,
512 st->rx_all_count > 0 ?
513 st->rxerr_proc*100/st->rx_all_count : 0);
514 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n",
515 st->rxerr_jumbo,
516 st->rx_all_count > 0 ?
517 st->rxerr_jumbo*100/st->rx_all_count : 0);
518 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n",
519 st->rx_all_count);
520
521 len += snprintf(buf+len, sizeof(buf)-len,
522 "\nTX\n---------------------\n");
523 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n",
524 st->txerr_retry,
525 st->tx_all_count > 0 ?
526 st->txerr_retry*100/st->tx_all_count : 0);
527 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n",
528 st->txerr_fifo,
529 st->tx_all_count > 0 ?
530 st->txerr_fifo*100/st->tx_all_count : 0);
531 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n",
532 st->txerr_filt,
533 st->tx_all_count > 0 ?
534 st->txerr_filt*100/st->tx_all_count : 0);
535 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
536 st->tx_all_count);
537
538 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
539}
540
541static ssize_t write_file_frameerrors(struct file *file,
542 const char __user *userbuf,
543 size_t count, loff_t *ppos)
544{
545 struct ath5k_softc *sc = file->private_data;
546 struct ath5k_statistics *st = &sc->stats;
547 char buf[20];
548
549 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
550 return -EFAULT;
551
552 if (strncmp(buf, "clear", 5) == 0) {
553 st->rxerr_crc = 0;
554 st->rxerr_phy = 0;
555 st->rxerr_fifo = 0;
556 st->rxerr_decrypt = 0;
557 st->rxerr_mic = 0;
558 st->rxerr_proc = 0;
559 st->rxerr_jumbo = 0;
560 st->rx_all_count = 0;
561 st->txerr_retry = 0;
562 st->txerr_fifo = 0;
563 st->txerr_filt = 0;
564 st->tx_all_count = 0;
565 printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n");
566 }
567 return count;
568}
569
570static const struct file_operations fops_frameerrors = {
571 .read = read_file_frameerrors,
572 .write = write_file_frameerrors,
573 .open = ath5k_debugfs_open,
574 .owner = THIS_MODULE,
575};
576
577
578/* debugfs: ani */
579
580static ssize_t read_file_ani(struct file *file, char __user *user_buf,
581 size_t count, loff_t *ppos)
582{
583 struct ath5k_softc *sc = file->private_data;
584 struct ath5k_statistics *st = &sc->stats;
585 struct ath5k_ani_state *as = &sc->ani_state;
586
587 char buf[700];
588 unsigned int len = 0;
589
590 len += snprintf(buf+len, sizeof(buf)-len,
591 "HW has PHY error counters:\t%s\n",
592 sc->ah->ah_capabilities.cap_has_phyerr_counters ?
593 "yes" : "no");
594 len += snprintf(buf+len, sizeof(buf)-len,
595 "HW max spur immunity level:\t%d\n",
596 as->max_spur_level);
597 len += snprintf(buf+len, sizeof(buf)-len,
598 "\nANI state\n--------------------------------------------\n");
599 len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t");
600 switch (as->ani_mode) {
601 case ATH5K_ANI_MODE_OFF:
602 len += snprintf(buf+len, sizeof(buf)-len, "OFF\n");
603 break;
604 case ATH5K_ANI_MODE_MANUAL_LOW:
605 len += snprintf(buf+len, sizeof(buf)-len,
606 "MANUAL LOW\n");
607 break;
608 case ATH5K_ANI_MODE_MANUAL_HIGH:
609 len += snprintf(buf+len, sizeof(buf)-len,
610 "MANUAL HIGH\n");
611 break;
612 case ATH5K_ANI_MODE_AUTO:
613 len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n");
614 break;
615 default:
616 len += snprintf(buf+len, sizeof(buf)-len,
617 "??? (not good)\n");
618 break;
619 }
620 len += snprintf(buf+len, sizeof(buf)-len,
621 "noise immunity level:\t\t%d\n",
622 as->noise_imm_level);
623 len += snprintf(buf+len, sizeof(buf)-len,
624 "spur immunity level:\t\t%d\n",
625 as->spur_level);
626 len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n",
627 as->firstep_level);
628 len += snprintf(buf+len, sizeof(buf)-len,
629 "OFDM weak signal detection:\t%s\n",
630 as->ofdm_weak_sig ? "on" : "off");
631 len += snprintf(buf+len, sizeof(buf)-len,
632 "CCK weak signal detection:\t%s\n",
633 as->cck_weak_sig ? "on" : "off");
634
635 len += snprintf(buf+len, sizeof(buf)-len,
636 "\nMIB INTERRUPTS:\t\t%u\n",
637 st->mib_intr);
638 len += snprintf(buf+len, sizeof(buf)-len,
639 "beacon RSSI average:\t%d\n",
640 sc->ah->ah_beacon_rssi_avg.avg);
641 len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
642 as->pfc_tx,
643 as->pfc_cycles > 0 ?
644 as->pfc_tx*100/as->pfc_cycles : 0);
645 len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
646 as->pfc_rx,
647 as->pfc_cycles > 0 ?
648 as->pfc_rx*100/as->pfc_cycles : 0);
649 len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
650 as->pfc_busy,
651 as->pfc_cycles > 0 ?
652 as->pfc_busy*100/as->pfc_cycles : 0);
653 len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
654 as->pfc_cycles);
655 len += snprintf(buf+len, sizeof(buf)-len,
656 "listen time\t\t%d\tlast: %d\n",
657 as->listen_time, as->last_listen);
658 len += snprintf(buf+len, sizeof(buf)-len,
659 "OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
660 as->ofdm_errors, as->last_ofdm_errors,
661 as->sum_ofdm_errors);
662 len += snprintf(buf+len, sizeof(buf)-len,
663 "CCK errors\t\t%u\tlast: %u\tsum: %u\n",
664 as->cck_errors, as->last_cck_errors,
665 as->sum_cck_errors);
666 len += snprintf(buf+len, sizeof(buf)-len,
667 "AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
668 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1),
669 ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
670 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1)));
671 len += snprintf(buf+len, sizeof(buf)-len,
672 "AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
673 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2),
674 ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
675 ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
676
677 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
678}
679
680static ssize_t write_file_ani(struct file *file,
681 const char __user *userbuf,
682 size_t count, loff_t *ppos)
683{
684 struct ath5k_softc *sc = file->private_data;
685 char buf[20];
686
687 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
688 return -EFAULT;
689
690 if (strncmp(buf, "sens-low", 8) == 0) {
691 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_HIGH);
692 } else if (strncmp(buf, "sens-high", 9) == 0) {
693 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_LOW);
694 } else if (strncmp(buf, "ani-off", 7) == 0) {
695 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_OFF);
696 } else if (strncmp(buf, "ani-on", 6) == 0) {
697 ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_AUTO);
698 } else if (strncmp(buf, "noise-low", 9) == 0) {
699 ath5k_ani_set_noise_immunity_level(sc->ah, 0);
700 } else if (strncmp(buf, "noise-high", 10) == 0) {
701 ath5k_ani_set_noise_immunity_level(sc->ah,
702 ATH5K_ANI_MAX_NOISE_IMM_LVL);
703 } else if (strncmp(buf, "spur-low", 8) == 0) {
704 ath5k_ani_set_spur_immunity_level(sc->ah, 0);
705 } else if (strncmp(buf, "spur-high", 9) == 0) {
706 ath5k_ani_set_spur_immunity_level(sc->ah,
707 sc->ani_state.max_spur_level);
708 } else if (strncmp(buf, "fir-low", 7) == 0) {
709 ath5k_ani_set_firstep_level(sc->ah, 0);
710 } else if (strncmp(buf, "fir-high", 8) == 0) {
711 ath5k_ani_set_firstep_level(sc->ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
712 } else if (strncmp(buf, "ofdm-off", 8) == 0) {
713 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, false);
714 } else if (strncmp(buf, "ofdm-on", 7) == 0) {
715 ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, true);
716 } else if (strncmp(buf, "cck-off", 7) == 0) {
717 ath5k_ani_set_cck_weak_signal_detection(sc->ah, false);
718 } else if (strncmp(buf, "cck-on", 6) == 0) {
719 ath5k_ani_set_cck_weak_signal_detection(sc->ah, true);
720 }
721 return count;
722}
723
724static const struct file_operations fops_ani = {
725 .read = read_file_ani,
726 .write = write_file_ani,
727 .open = ath5k_debugfs_open,
728 .owner = THIS_MODULE,
729};
730
731
367/* init */ 732/* init */
368 733
369void 734void
@@ -393,6 +758,20 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
393 758
394 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, 759 sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
395 sc->debug.debugfs_phydir, sc, &fops_reset); 760 sc->debug.debugfs_phydir, sc, &fops_reset);
761
762 sc->debug.debugfs_antenna = debugfs_create_file("antenna",
763 S_IWUSR | S_IRUSR,
764 sc->debug.debugfs_phydir, sc, &fops_antenna);
765
766 sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
767 S_IWUSR | S_IRUSR,
768 sc->debug.debugfs_phydir, sc,
769 &fops_frameerrors);
770
771 sc->debug.debugfs_ani = debugfs_create_file("ani",
772 S_IWUSR | S_IRUSR,
773 sc->debug.debugfs_phydir, sc,
774 &fops_ani);
396} 775}
397 776
398void 777void
@@ -408,6 +787,9 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
408 debugfs_remove(sc->debug.debugfs_registers); 787 debugfs_remove(sc->debug.debugfs_registers);
409 debugfs_remove(sc->debug.debugfs_beacon); 788 debugfs_remove(sc->debug.debugfs_beacon);
410 debugfs_remove(sc->debug.debugfs_reset); 789 debugfs_remove(sc->debug.debugfs_reset);
790 debugfs_remove(sc->debug.debugfs_antenna);
791 debugfs_remove(sc->debug.debugfs_frameerrors);
792 debugfs_remove(sc->debug.debugfs_ani);
411 debugfs_remove(sc->debug.debugfs_phydir); 793 debugfs_remove(sc->debug.debugfs_phydir);
412} 794}
413 795
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index 66f69f04e55e..ddd5b3a99e8d 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -74,6 +74,9 @@ struct ath5k_dbg_info {
74 struct dentry *debugfs_registers; 74 struct dentry *debugfs_registers;
75 struct dentry *debugfs_beacon; 75 struct dentry *debugfs_beacon;
76 struct dentry *debugfs_reset; 76 struct dentry *debugfs_reset;
77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_frameerrors;
79 struct dentry *debugfs_ani;
77}; 80};
78 81
79/** 82/**
@@ -113,6 +116,7 @@ enum ath5k_debug_level {
113 ATH5K_DEBUG_DUMP_TX = 0x00000200, 116 ATH5K_DEBUG_DUMP_TX = 0x00000200,
114 ATH5K_DEBUG_DUMPBANDS = 0x00000400, 117 ATH5K_DEBUG_DUMPBANDS = 0x00000400,
115 ATH5K_DEBUG_TRACE = 0x00001000, 118 ATH5K_DEBUG_TRACE = 0x00001000,
119 ATH5K_DEBUG_ANI = 0x00002000,
116 ATH5K_DEBUG_ANY = 0xffffffff 120 ATH5K_DEBUG_ANY = 0xffffffff
117}; 121};
118 122
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index dc30a2b70a6b..7d7b646ab65a 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -35,7 +35,8 @@
35 */ 35 */
36static int 36static int
37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 37ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
38 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, 38 unsigned int pkt_len, unsigned int hdr_len, int padsize,
39 enum ath5k_pkt_type type,
39 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, 40 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
40 unsigned int key_index, unsigned int antenna_mode, unsigned int flags, 41 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
41 unsigned int rtscts_rate, unsigned int rtscts_duration) 42 unsigned int rtscts_rate, unsigned int rtscts_duration)
@@ -71,7 +72,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
71 /* Verify and set frame length */ 72 /* Verify and set frame length */
72 73
73 /* remove padding we might have added before */ 74 /* remove padding we might have added before */
74 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 75 frame_len = pkt_len - padsize + FCS_LEN;
75 76
76 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) 77 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
77 return -EINVAL; 78 return -EINVAL;
@@ -100,7 +101,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); 101 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
101 } 102 }
102 103
103 /*Diferences between 5210-5211*/ 104 /*Differences between 5210-5211*/
104 if (ah->ah_version == AR5K_AR5210) { 105 if (ah->ah_version == AR5K_AR5210) {
105 switch (type) { 106 switch (type) {
106 case AR5K_PKT_TYPE_BEACON: 107 case AR5K_PKT_TYPE_BEACON:
@@ -165,6 +166,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
165 */ 166 */
166static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 167static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
167 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, 168 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
169 int padsize,
168 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, 170 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
169 unsigned int tx_tries0, unsigned int key_index, 171 unsigned int tx_tries0, unsigned int key_index,
170 unsigned int antenna_mode, unsigned int flags, 172 unsigned int antenna_mode, unsigned int flags,
@@ -206,7 +208,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
206 /* Verify and set frame length */ 208 /* Verify and set frame length */
207 209
208 /* remove padding we might have added before */ 210 /* remove padding we might have added before */
209 frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; 211 frame_len = pkt_len - padsize + FCS_LEN;
210 212
211 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 213 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
212 return -EINVAL; 214 return -EINVAL;
@@ -229,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
229 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 231 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
230 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 232 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
231 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 233 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
232 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, 234 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
233 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); 235 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
234 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 236 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
235 237
@@ -643,6 +645,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
643 rs->rs_status |= AR5K_RXERR_PHY; 645 rs->rs_status |= AR5K_RXERR_PHY;
644 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, 646 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
645 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); 647 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
648 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
646 } 649 }
647 650
648 if (rx_status->rx_status_1 & 651 if (rx_status->rx_status_1 &
@@ -668,12 +671,6 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
668 ah->ah_version != AR5K_AR5212) 671 ah->ah_version != AR5K_AR5212)
669 return -ENOTSUPP; 672 return -ENOTSUPP;
670 673
671 /* XXX: What is this magic value and where is it used ? */
672 if (ah->ah_version == AR5K_AR5212)
673 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
674 else if (ah->ah_version == AR5K_AR5211)
675 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
676
677 if (ah->ah_version == AR5K_AR5212) { 674 if (ah->ah_version == AR5K_AR5212) {
678 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; 675 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
679 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 676 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 56158c804e3e..64538fbe4167 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -112,15 +112,32 @@ struct ath5k_hw_rx_error {
112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
114 114
115/* PHY Error codes */ 115/**
116#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 116 * enum ath5k_phy_error_code - PHY Error codes
117#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 117 */
118#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 118enum ath5k_phy_error_code {
119#define AR5K_DESC_RX_PHY_ERROR_RATE 0x60 119 AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */
120#define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80 120 AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */
121#define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0 121 AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */
122#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 122 AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */
123#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 123 AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */
124 AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */
125 AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */
126 AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */
127 /* these are specific to the 5212 */
128 AR5K_RX_PHY_ERROR_OFDM_TIMING = 17,
129 AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY = 18,
130 AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL = 19,
131 AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL = 20,
132 AR5K_RX_PHY_ERROR_OFDM_POWER_DROP = 21,
133 AR5K_RX_PHY_ERROR_OFDM_SERVICE = 22,
134 AR5K_RX_PHY_ERROR_OFDM_RESTART = 23,
135 AR5K_RX_PHY_ERROR_CCK_TIMING = 25,
136 AR5K_RX_PHY_ERROR_CCK_HEADER_CRC = 26,
137 AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL = 27,
138 AR5K_RX_PHY_ERROR_CCK_SERVICE = 30,
139 AR5K_RX_PHY_ERROR_CCK_RESTART = 31,
140};
124 141
125/* 142/*
126 * 5210/5211 hardware 2-word TX control descriptor 143 * 5210/5211 hardware 2-word TX control descriptor
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 67665cdc7afe..ed0263672d6d 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -331,7 +331,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
331 ee->ee_x_gain[mode] = (val >> 1) & 0xf; 331 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
332 ee->ee_xpd[mode] = val & 0x1; 332 ee->ee_xpd[mode] = val & 0x1;
333 333
334 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) 334 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
335 mode != AR5K_EEPROM_MODE_11B)
335 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; 336 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
336 337
337 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { 338 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
@@ -341,6 +342,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
341 if (mode == AR5K_EEPROM_MODE_11A) 342 if (mode == AR5K_EEPROM_MODE_11A)
342 ee->ee_xr_power[mode] = val & 0x3f; 343 ee->ee_xr_power[mode] = val & 0x3f;
343 else { 344 else {
345 /* b_DB_11[bg] and b_OB_11[bg] */
344 ee->ee_ob[mode][0] = val & 0x7; 346 ee->ee_ob[mode][0] = val & 0x7;
345 ee->ee_db[mode][0] = (val >> 3) & 0x7; 347 ee->ee_db[mode][0] = (val >> 3) & 0x7;
346 } 348 }
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 473a483bb9c3..c4a6d5f26af4 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -24,9 +24,6 @@
24 * SERDES infos are present */ 24 * SERDES infos are present */
25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ 25#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ 26#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
27#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
28#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
29#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
30 27
31#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ 28#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
32 29
@@ -78,9 +75,9 @@
78#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) 75#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
79#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) 76#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
80#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) 77#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
81#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ 78#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */
82#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ 79#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */
83#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) 80#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */
84#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ 81#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
85#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ 82#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */
86 83
@@ -101,7 +98,7 @@
101 98
102#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) 99#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5)
103#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) 100#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
104#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) 101#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */
105#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) 102#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1)
106 103
107#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) 104#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6)
@@ -114,26 +111,27 @@
114 111
115#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) 112#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8)
116#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) 113#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
117#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) 114#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */
118#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) 115#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */
119 116
120#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) 117#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9)
121#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) 118#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */
122#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) 119#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */
123#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) 120#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */
124#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) 121#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */
125#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) 122#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */
126#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) 123#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */
127#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) 124#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */
128 125
129#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) 126#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10)
130#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) 127#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */
131#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) 128#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */
132#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) 129#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */
133#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) 130#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */
134#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) 131#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */
135#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) 132#define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */
136#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) 133#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */
134#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */
137 135
138/* calibration settings */ 136/* calibration settings */
139#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) 137#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
@@ -389,7 +387,49 @@ struct ath5k_edge_power {
389 bool flag; 387 bool flag;
390}; 388};
391 389
392/* EEPROM calibration data */ 390/**
391 * struct ath5k_eeprom_info - EEPROM calibration data
392 *
393 * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING
394 * flags
395 * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?]
396 * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for
397 * OFDM and CCK packets
398 * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK
399 * (11Mbps) rate in G mode. 0.1dB steps
400 * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution
401 *
402 * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path
403 * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path
404 * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control
405 * @ee_switch_settling: RX/TX Switch settling time
406 * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps
407 * @ee_ant_control: Antenna Control Settings
408 * @ee_ob: Bias current for Output stage of PA
409 * B/G mode: Index [0] is used for AR2112/5112, otherwise [1]
410 * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz
411 * @ee_db: Bias current for Output stage of PA. see @ee_ob
412 * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame
413 * to when the external LNA is activated
414 * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame
415 * to when the external PA switch is deactivated
416 * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when
417 * external PA switch is activated
418 * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity
419 * (IEEE802.11a section 17.3.10.5 )
420 * @ee_xlna_gain: Total gain of the LNA (information only)
421 * @ee_xpd: Use external (1) or internal power detector
422 * @ee_x_gain: Gain for external power detector output (differences in EEMAP
423 * versions!)
424 * @ee_i_gain: Initial gain value after reset
425 * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used
426 *
427 * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals
428 * @ee_noise_floor_thr: Noise floor threshold in 1dB steps
429 * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps
430 * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps
431 * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2)
432 */
393struct ath5k_eeprom_info { 433struct ath5k_eeprom_info {
394 434
395 /* Header information */ 435 /* Header information */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index aefe84f9c04b..5212e275f1c7 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -39,16 +39,16 @@
39 * ath5k_hw_set_opmode - Set PCU operating mode 39 * ath5k_hw_set_opmode - Set PCU operating mode
40 * 40 *
41 * @ah: The &struct ath5k_hw 41 * @ah: The &struct ath5k_hw
42 * @op_mode: &enum nl80211_iftype operating mode
42 * 43 *
43 * Initialize PCU for the various operating modes (AP/STA etc) 44 * Initialize PCU for the various operating modes (AP/STA etc)
44 *
45 * NOTE: ah->ah_op_mode must be set before calling this.
46 */ 45 */
47int ath5k_hw_set_opmode(struct ath5k_hw *ah) 46int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
48{ 47{
49 struct ath_common *common = ath5k_hw_common(ah); 48 struct ath_common *common = ath5k_hw_common(ah);
50 u32 pcu_reg, beacon_reg, low_id, high_id; 49 u32 pcu_reg, beacon_reg, low_id, high_id;
51 50
51 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
52 52
53 /* Preserve rest settings */ 53 /* Preserve rest settings */
54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 54 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
@@ -61,7 +61,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
61 61
62 ATH5K_TRACE(ah->ah_sc); 62 ATH5K_TRACE(ah->ah_sc);
63 63
64 switch (ah->ah_op_mode) { 64 switch (op_mode) {
65 case NL80211_IFTYPE_ADHOC: 65 case NL80211_IFTYPE_ADHOC:
66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; 66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
67 beacon_reg |= AR5K_BCR_ADHOC; 67 beacon_reg |= AR5K_BCR_ADHOC;
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
113} 113}
114 114
115/** 115/**
116 * ath5k_hw_update - Update mib counters (mac layer statistics) 116 * ath5k_hw_update - Update MIB counters (mac layer statistics)
117 * 117 *
118 * @ah: The &struct ath5k_hw 118 * @ah: The &struct ath5k_hw
119 * @stats: The &struct ieee80211_low_level_stats we use to track
120 * statistics on the driver
121 * 119 *
122 * Reads MIB counters from PCU and updates sw statistics. Must be 120 * Reads MIB counters from PCU and updates sw statistics. Is called after a
123 * called after a MIB interrupt. 121 * MIB interrupt, because one of these counters might have reached their maximum
122 * and triggered the MIB interrupt, to let us read and clear the counter.
123 *
124 * Is called in interrupt context!
124 */ 125 */
125void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, 126void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
126 struct ieee80211_low_level_stats *stats)
127{ 127{
128 ATH5K_TRACE(ah->ah_sc); 128 struct ath5k_statistics *stats = &ah->ah_sc->stats;
129 129
130 /* Read-And-Clear */ 130 /* Read-And-Clear */
131 stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); 131 stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
132 stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); 132 stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
133 stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); 133 stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
134 stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); 134 stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
135 135 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
136 /* XXX: Should we use this to track beacon count ?
137 * -we read it anyway to clear the register */
138 ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
139
140 /* Reset profile count registers on 5212*/
141 if (ah->ah_version == AR5K_AR5212) {
142 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
143 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
144 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
145 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
146 }
147
148 /* TODO: Handle ANI stats */
149} 136}
150 137
151/** 138/**
@@ -167,9 +154,9 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
167 else { 154 else {
168 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; 155 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
169 if (high) 156 if (high)
170 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
171 else
172 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); 157 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
158 else
159 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
173 } 160 }
174} 161}
175 162
@@ -179,25 +166,12 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
179\******************/ 166\******************/
180 167
181/** 168/**
182 * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
183 *
184 * @ah: The &struct ath5k_hw
185 */
186unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
187{
188 ATH5K_TRACE(ah->ah_sc);
189
190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
192}
193
194/**
195 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU 169 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
196 * 170 *
197 * @ah: The &struct ath5k_hw 171 * @ah: The &struct ath5k_hw
198 * @timeout: Timeout in usec 172 * @timeout: Timeout in usec
199 */ 173 */
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 174static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
201{ 175{
202 ATH5K_TRACE(ah->ah_sc); 176 ATH5K_TRACE(ah->ah_sc);
203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) 177 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
@@ -211,24 +185,12 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
211} 185}
212 186
213/** 187/**
214 * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
215 *
216 * @ah: The &struct ath5k_hw
217 */
218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
219{
220 ATH5K_TRACE(ah->ah_sc);
221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
223}
224
225/**
226 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU 188 * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
227 * 189 *
228 * @ah: The &struct ath5k_hw 190 * @ah: The &struct ath5k_hw
229 * @timeout: Timeout in usec 191 * @timeout: Timeout in usec
230 */ 192 */
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 193static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
232{ 194{
233 ATH5K_TRACE(ah->ah_sc); 195 ATH5K_TRACE(ah->ah_sc);
234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) 196 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
@@ -290,7 +252,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
290 * 252 *
291 * @ah: The &struct ath5k_hw 253 * @ah: The &struct ath5k_hw
292 */ 254 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) 255static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{ 256{
295 struct ieee80211_channel *channel = ah->ah_current_channel; 257 struct ieee80211_channel *channel = ah->ah_current_channel;
296 258
@@ -308,7 +270,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
308 * 270 *
309 * @ah: The &struct ath5k_hw 271 * @ah: The &struct ath5k_hw
310 */ 272 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) 273static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
312{ 274{
313 struct ieee80211_channel *channel = ah->ah_current_channel; 275 struct ieee80211_channel *channel = ah->ah_current_channel;
314 276
@@ -417,7 +379,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
417 * (ACK etc). 379 * (ACK etc).
418 * 380 *
419 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma 381 * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
420 * TODO: Init ANI here
421 */ 382 */
422void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) 383void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
423{ 384{
@@ -451,42 +412,6 @@ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
451 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); 412 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
452} 413}
453 414
454/*
455 * Set multicast filter by index
456 */
457int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
458{
459
460 ATH5K_TRACE(ah->ah_sc);
461 if (index >= 64)
462 return -EINVAL;
463 else if (index >= 32)
464 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
465 (1 << (index - 32)));
466 else
467 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
468
469 return 0;
470}
471
472/*
473 * Clear Multicast filter by index
474 */
475int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
476{
477
478 ATH5K_TRACE(ah->ah_sc);
479 if (index >= 64)
480 return -EINVAL;
481 else if (index >= 32)
482 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
483 (1 << (index - 32)));
484 else
485 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
486
487 return 0;
488}
489
490/** 415/**
491 * ath5k_hw_get_rx_filter - Get current rx filter 416 * ath5k_hw_get_rx_filter - Get current rx filter
492 * 417 *
@@ -571,18 +496,7 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
571* Beacon control * 496* Beacon control *
572\****************/ 497\****************/
573 498
574/** 499#define ATH5K_MAX_TSF_READ 10
575 * ath5k_hw_get_tsf32 - Get a 32bit TSF
576 *
577 * @ah: The &struct ath5k_hw
578 *
579 * Returns lower 32 bits of current TSF
580 */
581u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
582{
583 ATH5K_TRACE(ah->ah_sc);
584 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
585}
586 500
587/** 501/**
588 * ath5k_hw_get_tsf64 - Get the full 64bit TSF 502 * ath5k_hw_get_tsf64 - Get the full 64bit TSF
@@ -593,10 +507,35 @@ u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
593 */ 507 */
594u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) 508u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
595{ 509{
596 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32); 510 u32 tsf_lower, tsf_upper1, tsf_upper2;
511 int i;
512
513 /*
514 * While reading TSF upper and then lower part, the clock is still
515 * counting (or jumping in case of IBSS merge) so we might get
516 * inconsistent values. To avoid this, we read the upper part again
517 * and check it has not been changed. We make the hypothesis that a
518 * maximum of 3 changes can happens in a row (we use 10 as a safe
519 * value).
520 *
521 * Impact on performance is pretty small, since in most cases, only
522 * 3 register reads are needed.
523 */
524
525 tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
526 for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
527 tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
528 tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
529 if (tsf_upper2 == tsf_upper1)
530 break;
531 tsf_upper1 = tsf_upper2;
532 }
533
534 WARN_ON( i == ATH5K_MAX_TSF_READ );
535
597 ATH5K_TRACE(ah->ah_sc); 536 ATH5K_TRACE(ah->ah_sc);
598 537
599 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32); 538 return (((u64)tsf_upper1 << 32) | tsf_lower);
600} 539}
601 540
602/** 541/**
@@ -651,7 +590,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
651 /* 590 /*
652 * Set the additional timers by mode 591 * Set the additional timers by mode
653 */ 592 */
654 switch (ah->ah_op_mode) { 593 switch (ah->ah_sc->opmode) {
655 case NL80211_IFTYPE_MONITOR: 594 case NL80211_IFTYPE_MONITOR:
656 case NL80211_IFTYPE_STATION: 595 case NL80211_IFTYPE_STATION:
657 /* In STA mode timer1 is used as next wakeup 596 /* In STA mode timer1 is used as next wakeup
@@ -688,8 +627,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
688 * Set the beacon register and enable all timers. 627 * Set the beacon register and enable all timers.
689 */ 628 */
690 /* When in AP or Mesh Point mode zero timer0 to start TSF */ 629 /* When in AP or Mesh Point mode zero timer0 to start TSF */
691 if (ah->ah_op_mode == NL80211_IFTYPE_AP || 630 if (ah->ah_sc->opmode == NL80211_IFTYPE_AP ||
692 ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) 631 ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT)
693 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); 632 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
694 633
695 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); 634 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
@@ -722,203 +661,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
722 661
723} 662}
724 663
725#if 0
726/*
727 * Set beacon timers
728 */
729int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
730 const struct ath5k_beacon_state *state)
731{
732 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
733
734 /*
735 * TODO: should be changed through *state
736 * review struct ath5k_beacon_state struct
737 *
738 * XXX: These are used for cfp period bellow, are they
739 * ok ? Is it O.K. for tsf here to be 0 or should we use
740 * get_tsf ?
741 */
742 u32 dtim_count = 0; /* XXX */
743 u32 cfp_count = 0; /* XXX */
744 u32 tsf = 0; /* XXX */
745
746 ATH5K_TRACE(ah->ah_sc);
747 /* Return on an invalid beacon state */
748 if (state->bs_interval < 1)
749 return -EINVAL;
750
751 interval = state->bs_interval;
752 dtim = state->bs_dtim_period;
753
754 /*
755 * PCF support?
756 */
757 if (state->bs_cfp_period > 0) {
758 /*
759 * Enable PCF mode and set the CFP
760 * (Contention Free Period) and timer registers
761 */
762 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
763 state->bs_interval;
764 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
765 state->bs_interval;
766
767 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
768 AR5K_STA_ID1_DEFAULT_ANTENNA |
769 AR5K_STA_ID1_PCF);
770 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
771 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
772 AR5K_CFP_DUR);
773 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
774 next_cfp)) << 3, AR5K_TIMER2);
775 } else {
776 /* Disable PCF mode */
777 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
778 AR5K_STA_ID1_DEFAULT_ANTENNA |
779 AR5K_STA_ID1_PCF);
780 }
781
782 /*
783 * Enable the beacon timer register
784 */
785 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
786
787 /*
788 * Start the beacon timers
789 */
790 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
791 ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
792 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
793 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
794 AR5K_BEACON_PERIOD), AR5K_BEACON);
795
796 /*
797 * Write new beacon miss threshold, if it appears to be valid
798 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
799 * and return if its not in range. We can test this by reading value and
800 * setting value to a largest value and seeing which values register.
801 */
802
803 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
804 state->bs_bmiss_threshold);
805
806 /*
807 * Set sleep control register
808 * XXX: Didn't find this in 5210 code but since this register
809 * exists also in ar5k's 5210 headers i leave it as common code.
810 */
811 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
812 (state->bs_sleep_duration - 3) << 3);
813
814 /*
815 * Set enhanced sleep registers on 5212
816 */
817 if (ah->ah_version == AR5K_AR5212) {
818 if (state->bs_sleep_duration > state->bs_interval &&
819 roundup(state->bs_sleep_duration, interval) ==
820 state->bs_sleep_duration)
821 interval = state->bs_sleep_duration;
822
823 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
824 roundup(state->bs_sleep_duration, dtim) ==
825 state->bs_sleep_duration))
826 dtim = state->bs_sleep_duration;
827
828 if (interval > dtim)
829 return -EINVAL;
830
831 next_beacon = interval == dtim ? state->bs_next_dtim :
832 state->bs_next_beacon;
833
834 ath5k_hw_reg_write(ah,
835 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
836 AR5K_SLEEP0_NEXT_DTIM) |
837 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
838 AR5K_SLEEP0_ENH_SLEEP_EN |
839 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
840
841 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
842 AR5K_SLEEP1_NEXT_TIM) |
843 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
844
845 ath5k_hw_reg_write(ah,
846 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
847 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
848 }
849
850 return 0;
851}
852
853/*
854 * Reset beacon timers
855 */
856void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
857{
858 ATH5K_TRACE(ah->ah_sc);
859 /*
860 * Disable beacon timer
861 */
862 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
863
864 /*
865 * Disable some beacon register values
866 */
867 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
868 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
869 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
870}
871
872/*
873 * Wait for beacon queue to finish
874 */
875int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
876{
877 unsigned int i;
878 int ret;
879
880 ATH5K_TRACE(ah->ah_sc);
881
882 /* 5210 doesn't have QCU*/
883 if (ah->ah_version == AR5K_AR5210) {
884 /*
885 * Wait for beaconn queue to finish by checking
886 * Control Register and Beacon Status Register.
887 */
888 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
889 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
890 ||
891 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
892 break;
893 udelay(10);
894 }
895
896 /* Timeout... */
897 if (i <= 0) {
898 /*
899 * Re-schedule the beacon queue
900 */
901 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
902 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
903 AR5K_BCR);
904
905 return -EIO;
906 }
907 ret = 0;
908 } else {
909 /*5211/5212*/
910 ret = ath5k_hw_register_timeout(ah,
911 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
912 AR5K_QCU_STS_FRMPENDCNT, 0, false);
913
914 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
915 return -EIO;
916 }
917
918 return ret;
919}
920#endif
921
922 664
923/*********************\ 665/*********************\
924* Key table functions * 666* Key table functions *
@@ -971,19 +713,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
971 return 0; 713 return 0;
972} 714}
973 715
974/*
975 * Check if a table entry is valid
976 */
977int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
978{
979 ATH5K_TRACE(ah->ah_sc);
980 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
981
982 /* Check the validation flag at the end of the entry */
983 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
984 AR5K_KEYTABLE_VALID;
985}
986
987static 716static
988int ath5k_keycache_type(const struct ieee80211_key_conf *key) 717int ath5k_keycache_type(const struct ieee80211_key_conf *key)
989{ 718{
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 68e2bccd90d3..1b81c4778800 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -20,8 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#define _ATH5K_PHY
24
25#include <linux/delay.h> 23#include <linux/delay.h>
26#include <linux/slab.h> 24#include <linux/slab.h>
27 25
@@ -982,7 +980,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
982 return -EINVAL; 980 return -EINVAL;
983 981
984 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); 982 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
985 } else if ((c - (c % 5)) != 2 || c > 5435) { 983 } else if ((c % 5) != 2 || c > 5435) {
986 if (!(c % 20) && c >= 5120) { 984 if (!(c % 20) && c >= 5120) {
987 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); 985 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
988 data2 = ath5k_hw_bitswap(3, 2); 986 data2 = ath5k_hw_bitswap(3, 2);
@@ -995,7 +993,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
995 } else 993 } else
996 return -EINVAL; 994 return -EINVAL;
997 } else { 995 } else {
998 data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); 996 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
999 data2 = ath5k_hw_bitswap(0, 2); 997 data2 = ath5k_hw_bitswap(0, 2);
1000 } 998 }
1001 999
@@ -1023,7 +1021,7 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1023 data0 = ath5k_hw_bitswap((c - 2272), 8); 1021 data0 = ath5k_hw_bitswap((c - 2272), 8);
1024 data2 = 0; 1022 data2 = 0;
1025 /* ? 5GHz ? */ 1023 /* ? 5GHz ? */
1026 } else if ((c - (c % 5)) != 2 || c > 5435) { 1024 } else if ((c % 5) != 2 || c > 5435) {
1027 if (!(c % 20) && c < 5120) 1025 if (!(c % 20) && c < 5120)
1028 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); 1026 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1029 else if (!(c % 10)) 1027 else if (!(c % 10))
@@ -1034,7 +1032,7 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1034 return -EINVAL; 1032 return -EINVAL;
1035 data2 = ath5k_hw_bitswap(1, 2); 1033 data2 = ath5k_hw_bitswap(1, 2);
1036 } else { 1034 } else {
1037 data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); 1035 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1038 data2 = ath5k_hw_bitswap(0, 2); 1036 data2 = ath5k_hw_bitswap(0, 2);
1039 } 1037 }
1040 1038
@@ -1105,28 +1103,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1105 PHY calibration 1103 PHY calibration
1106\*****************/ 1104\*****************/
1107 1105
1108void
1109ath5k_hw_calibration_poll(struct ath5k_hw *ah)
1110{
1111 /* Calibration interval in jiffies */
1112 unsigned long cal_intval;
1113
1114 cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
1115
1116 /* Initialize timestamp if needed */
1117 if (!ah->ah_cal_tstamp)
1118 ah->ah_cal_tstamp = jiffies;
1119
1120 /* For now we always do full calibration
1121 * Mark software interrupt mask and fire software
1122 * interrupt (bit gets auto-cleared) */
1123 if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
1124 ah->ah_cal_tstamp = jiffies;
1125 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
1126 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
1127 }
1128}
1129
1130static int sign_extend(int val, const int nbits) 1106static int sign_extend(int val, const int nbits)
1131{ 1107{
1132 int order = BIT(nbits-1); 1108 int order = BIT(nbits-1);
@@ -1191,7 +1167,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1191 * The median of the values in the history is then loaded into the 1167 * The median of the values in the history is then loaded into the
1192 * hardware for its own use for RSSI and CCA measurements. 1168 * hardware for its own use for RSSI and CCA measurements.
1193 */ 1169 */
1194void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) 1170static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1195{ 1171{
1196 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1172 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1197 u32 val; 1173 u32 val;
@@ -1400,7 +1376,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1400 } 1376 }
1401 1377
1402 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1378 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1403 q_coffd = q_pwr >> 7; 1379
1380 if (ah->ah_version == AR5K_AR5211)
1381 q_coffd = q_pwr >> 6;
1382 else
1383 q_coffd = q_pwr >> 7;
1404 1384
1405 /* protect against divide by 0 and loss of sign bits */ 1385 /* protect against divide by 0 and loss of sign bits */
1406 if (i_coffd == 0 || q_coffd < 2) 1386 if (i_coffd == 0 || q_coffd < 2)
@@ -1409,7 +1389,10 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1409 i_coff = (-iq_corr) / i_coffd; 1389 i_coff = (-iq_corr) / i_coffd;
1410 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ 1390 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
1411 1391
1412 q_coff = (i_pwr / q_coffd) - 128; 1392 if (ah->ah_version == AR5K_AR5211)
1393 q_coff = (i_pwr / q_coffd) - 64;
1394 else
1395 q_coff = (i_pwr / q_coffd) - 128;
1413 q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ 1396 q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
1414 1397
1415 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, 1398 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
@@ -1769,7 +1752,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1769* Antenna control * 1752* Antenna control *
1770\*****************/ 1753\*****************/
1771 1754
1772void /*TODO:Boundary check*/ 1755static void /*TODO:Boundary check*/
1773ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) 1756ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1774{ 1757{
1775 ATH5K_TRACE(ah->ah_sc); 1758 ATH5K_TRACE(ah->ah_sc);
@@ -1778,16 +1761,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1778 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); 1761 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1779} 1762}
1780 1763
1781unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1782{
1783 ATH5K_TRACE(ah->ah_sc);
1784
1785 if (ah->ah_version != AR5K_AR5210)
1786 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
1787
1788 return false; /*XXX: What do we return for 5210 ?*/
1789}
1790
1791/* 1764/*
1792 * Enable/disable fast rx antenna diversity 1765 * Enable/disable fast rx antenna diversity
1793 */ 1766 */
@@ -1931,6 +1904,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1931 1904
1932 ah->ah_tx_ant = tx_ant; 1905 ah->ah_tx_ant = tx_ant;
1933 ah->ah_ant_mode = ant_mode; 1906 ah->ah_ant_mode = ant_mode;
1907 ah->ah_def_ant = def_ant;
1934 1908
1935 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; 1909 sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
1936 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; 1910 sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
@@ -2171,8 +2145,6 @@ ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2171done: 2145done:
2172 *pcinfo_l = &pcinfo[idx_l]; 2146 *pcinfo_l = &pcinfo[idx_l];
2173 *pcinfo_r = &pcinfo[idx_r]; 2147 *pcinfo_r = &pcinfo[idx_r];
2174
2175 return;
2176} 2148}
2177 2149
2178/* 2150/*
@@ -2441,19 +2413,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
2441 pcdac_tmp = pcdac_high_pwr; 2413 pcdac_tmp = pcdac_high_pwr;
2442 2414
2443 edge_flag = 0x40; 2415 edge_flag = 0x40;
2444#if 0
2445 /* If both min and max power limits are in lower
2446 * power curve's range, only use the low power curve.
2447 * TODO: min/max levels are related to target
2448 * power values requested from driver/user
2449 * XXX: Is this really needed ? */
2450 if (min_pwr < table_max[1] &&
2451 max_pwr < table_max[1]) {
2452 edge_flag = 0;
2453 pcdac_tmp = pcdac_low_pwr;
2454 max_pwr_idx = (table_max[1] - table_min[1])/2;
2455 }
2456#endif
2457 } else { 2416 } else {
2458 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ 2417 pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
2459 pcdac_high_pwr = ah->ah_txpower.tmpL[0]; 2418 pcdac_high_pwr = ah->ah_txpower.tmpL[0];
@@ -2600,7 +2559,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
2600 max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; 2559 max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
2601 2560
2602 /* Fill pdadc_out table */ 2561 /* Fill pdadc_out table */
2603 while (pdadc_0 < max_idx) 2562 while (pdadc_0 < max_idx && pdadc_i < 128)
2604 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++]; 2563 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
2605 2564
2606 /* Need to extrapolate above this pdgain? */ 2565 /* Need to extrapolate above this pdgain? */
@@ -3144,5 +3103,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3144 3103
3145 return ath5k_hw_txpower(ah, channel, ee_mode, txpower); 3104 return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
3146} 3105}
3147
3148#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 9122a8556f45..f5831da33f7b 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -517,23 +517,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
517} 517}
518 518
519/* 519/*
520 * Get slot time from DCU
521 */
522unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
523{
524 unsigned int slot_time_clock;
525
526 ATH5K_TRACE(ah->ah_sc);
527
528 if (ah->ah_version == AR5K_AR5210)
529 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
530 else
531 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
532
533 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
534}
535
536/*
537 * Set slot time on DCU 520 * Set slot time on DCU
538 */ 521 */
539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 522int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 1464f89b249c..55b4ac6d236f 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -212,10 +212,10 @@
212 * MIB control register 212 * MIB control register
213 */ 213 */
214#define AR5K_MIBC 0x0040 /* Register Address */ 214#define AR5K_MIBC 0x0040 /* Register Address */
215#define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ 215#define AR5K_MIBC_COW 0x00000001 /* Counter Overflow Warning */
216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ 216#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */
217#define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ 217#define AR5K_MIBC_CMC 0x00000004 /* Clear MIB Counters */
218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ 218#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe, increment all */
219 219
220/* 220/*
221 * Timeout prescale register 221 * Timeout prescale register
@@ -1139,8 +1139,8 @@
1139#define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ 1139#define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */
1140#define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ 1140#define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */
1141#define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ 1141#define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */
1142#define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ 1142#define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Rate to use for ACK/CTS. 0: highest mandatory rate <= RX rate; 1: 1Mbps in B mode */
1143#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ 1143#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* 802.11b base rate. 0: 1, 2, 5.5 and 11Mbps; 1: 1 and 2Mbps. [5211+] */
1144#define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ 1144#define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */
1145#define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ 1145#define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */
1146#define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ 1146#define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */
@@ -1516,7 +1516,14 @@
1516 AR5K_NAV_5210 : AR5K_NAV_5211) 1516 AR5K_NAV_5210 : AR5K_NAV_5211)
1517 1517
1518/* 1518/*
1519 * RTS success register 1519 * MIB counters:
1520 *
1521 * max value is 0xc000, if this is reached we get a MIB interrupt.
1522 * they can be controlled via AR5K_MIBC and are cleared on read.
1523 */
1524
1525/*
1526 * RTS success (MIB counter)
1520 */ 1527 */
1521#define AR5K_RTS_OK_5210 0x8090 1528#define AR5K_RTS_OK_5210 0x8090
1522#define AR5K_RTS_OK_5211 0x8088 1529#define AR5K_RTS_OK_5211 0x8088
@@ -1524,7 +1531,7 @@
1524 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) 1531 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
1525 1532
1526/* 1533/*
1527 * RTS failure register 1534 * RTS failure (MIB counter)
1528 */ 1535 */
1529#define AR5K_RTS_FAIL_5210 0x8094 1536#define AR5K_RTS_FAIL_5210 0x8094
1530#define AR5K_RTS_FAIL_5211 0x808c 1537#define AR5K_RTS_FAIL_5211 0x808c
@@ -1532,7 +1539,7 @@
1532 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) 1539 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
1533 1540
1534/* 1541/*
1535 * ACK failure register 1542 * ACK failure (MIB counter)
1536 */ 1543 */
1537#define AR5K_ACK_FAIL_5210 0x8098 1544#define AR5K_ACK_FAIL_5210 0x8098
1538#define AR5K_ACK_FAIL_5211 0x8090 1545#define AR5K_ACK_FAIL_5211 0x8090
@@ -1540,7 +1547,7 @@
1540 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) 1547 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
1541 1548
1542/* 1549/*
1543 * FCS failure register 1550 * FCS failure (MIB counter)
1544 */ 1551 */
1545#define AR5K_FCS_FAIL_5210 0x809c 1552#define AR5K_FCS_FAIL_5210 0x809c
1546#define AR5K_FCS_FAIL_5211 0x8094 1553#define AR5K_FCS_FAIL_5211 0x8094
@@ -1667,11 +1674,17 @@
1667 1674
1668/* 1675/*
1669 * Profile count registers 1676 * Profile count registers
1677 *
1678 * These registers can be cleared and freezed with ATH5K_MIBC, but they do not
1679 * generate a MIB interrupt.
1680 * Instead of overflowing, they shift by one bit to the right. All registers
1681 * shift together, i.e. when one reaches the max, all shift at the same time by
1682 * one bit to the right. This way we should always get consistent values.
1670 */ 1683 */
1671#define AR5K_PROFCNT_TX 0x80ec /* Tx count */ 1684#define AR5K_PROFCNT_TX 0x80ec /* Tx count */
1672#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ 1685#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */
1673#define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ 1686#define AR5K_PROFCNT_RXCLR 0x80f4 /* Busy count */
1674#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ 1687#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle counter */
1675 1688
1676/* 1689/*
1677 * Quiet period control registers 1690 * Quiet period control registers
@@ -1758,7 +1771,7 @@
1758#define AR5K_CCK_FIL_CNT 0x8128 1771#define AR5K_CCK_FIL_CNT 0x8128
1759 1772
1760/* 1773/*
1761 * PHY Error Counters (?) 1774 * PHY Error Counters (same masks as AR5K_PHY_ERR_FIL)
1762 */ 1775 */
1763#define AR5K_PHYERR_CNT1 0x812c 1776#define AR5K_PHYERR_CNT1 0x812c
1764#define AR5K_PHYERR_CNT1_MASK 0x8130 1777#define AR5K_PHYERR_CNT1_MASK 0x8130
@@ -1766,6 +1779,9 @@
1766#define AR5K_PHYERR_CNT2 0x8134 1779#define AR5K_PHYERR_CNT2 0x8134
1767#define AR5K_PHYERR_CNT2_MASK 0x8138 1780#define AR5K_PHYERR_CNT2_MASK 0x8138
1768 1781
1782/* if the PHY Error Counters reach this maximum, we get MIB interrupts */
1783#define ATH5K_PHYERR_CNT_MAX 0x00c00000
1784
1769/* 1785/*
1770 * TSF Threshold register (?) 1786 * TSF Threshold register (?)
1771 */ 1787 */
@@ -1974,7 +1990,7 @@
1974#define AR5K_PHY_SETTLING 0x9844 /* Register Address */ 1990#define AR5K_PHY_SETTLING 0x9844 /* Register Address */
1975#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ 1991#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
1976#define AR5K_PHY_SETTLING_AGC_S 0 1992#define AR5K_PHY_SETTLING_AGC_S 0
1977#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ 1993#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */
1978#define AR5K_PHY_SETTLING_SWITCH_S 7 1994#define AR5K_PHY_SETTLING_SWITCH_S 7
1979 1995
1980/* 1996/*
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index cbf28e379843..307f80e83f94 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -19,8 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#define _ATH5K_RESET
23
24/*****************************\ 22/*****************************\
25 Reset functions and helpers 23 Reset functions and helpers
26\*****************************/ 24\*****************************/
@@ -34,6 +32,27 @@
34#include "base.h" 32#include "base.h"
35#include "debug.h" 33#include "debug.h"
36 34
35/*
36 * Check if a register write has been completed
37 */
38int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
39 bool is_set)
40{
41 int i;
42 u32 data;
43
44 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
45 data = ath5k_hw_reg_read(ah, reg);
46 if (is_set && (data & flag))
47 break;
48 else if ((data & flag) == val)
49 break;
50 udelay(15);
51 }
52
53 return (i <= 0) ? -EAGAIN : 0;
54}
55
37/** 56/**
38 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 57 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
39 * 58 *
@@ -221,8 +240,8 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
221/* 240/*
222 * Sleep control 241 * Sleep control
223 */ 242 */
224int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, 243static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
225 bool set_chip, u16 sleep_duration) 244 bool set_chip, u16 sleep_duration)
226{ 245{
227 unsigned int i; 246 unsigned int i;
228 u32 staid, data; 247 u32 staid, data;
@@ -608,7 +627,6 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
608 627
609 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); 628 AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
610 } 629 }
611 return;
612} 630}
613 631
614/* TODO: Half/Quarter rate */ 632/* TODO: Half/Quarter rate */
@@ -864,8 +882,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
864 /* Heavy clipping -disable for now */ 882 /* Heavy clipping -disable for now */
865 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) 883 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
866 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); 884 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
867
868 return;
869} 885}
870 886
871/* 887/*
@@ -1017,11 +1033,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1017 if (ret) 1033 if (ret)
1018 return ret; 1034 return ret;
1019 1035
1020 /*
1021 * Initialize operating mode
1022 */
1023 ah->ah_op_mode = op_mode;
1024
1025 /* PHY access enable */ 1036 /* PHY access enable */
1026 if (ah->ah_mac_srev >= AR5K_SREV_AR5211) 1037 if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
1027 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); 1038 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
@@ -1192,7 +1203,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1192 ath5k_hw_set_associd(ah); 1203 ath5k_hw_set_associd(ah);
1193 1204
1194 /* Set PCU config */ 1205 /* Set PCU config */
1195 ath5k_hw_set_opmode(ah); 1206 ath5k_hw_set_opmode(ah, op_mode);
1196 1207
1197 /* Clear any pending interrupts 1208 /* Clear any pending interrupts
1198 * PISR/SISR Not available on 5210 */ 1209 * PISR/SISR Not available on 5210 */
@@ -1378,7 +1389,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1378 * external 32KHz crystal when sleeping if one 1389 * external 32KHz crystal when sleeping if one
1379 * exists */ 1390 * exists */
1380 if (ah->ah_version == AR5K_AR5212 && 1391 if (ah->ah_version == AR5K_AR5212 &&
1381 ah->ah_op_mode != NL80211_IFTYPE_AP) 1392 op_mode != NL80211_IFTYPE_AP)
1382 ath5k_hw_set_sleep_clock(ah, true); 1393 ath5k_hw_set_sleep_clock(ah, true);
1383 1394
1384 /* 1395 /*
@@ -1388,5 +1399,3 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1388 ath5k_hw_reset_tsf(ah); 1399 ath5k_hw_reset_tsf(ah);
1389 return 0; 1400 return 0;
1390} 1401}
1391
1392#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5774cea23a3b..35f23bdc442f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS
32 32
33 Also required for changing debug message flags at run time. 33 Also required for changing debug message flags at run time.
34 34
35config ATH9K_HTC
36 tristate "Atheros HTC based wireless cards support"
37 depends on USB && MAC80211
38 select ATH9K_HW
39 select MAC80211_LEDS
40 select LEDS_CLASS
41 select NEW_LEDS
42 select ATH9K_COMMON
43 ---help---
44 Support for Atheros HTC based cards.
45 Chipsets supported: AR9271
46
47 For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
48
49 The built module will be ath9k_htc.
50
51config ATH9K_HTC_DEBUGFS
52 bool "Atheros ath9k_htc debugging"
53 depends on ATH9K_HTC && DEBUG_FS
54 ---help---
55 Say Y, if you need access to ath9k_htc's statistics.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b50d5eb9ec3..dd112be218ab 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -13,18 +13,38 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
13 13
14obj-$(CONFIG_ATH9K) += ath9k.o 14obj-$(CONFIG_ATH9K) += ath9k.o
15 15
16ath9k_hw-y:= hw.o \ 16ath9k_hw-y:= \
17 ar9002_hw.o \
18 ar9003_hw.o \
19 hw.o \
20 ar9003_phy.o \
21 ar9002_phy.o \
22 ar5008_phy.o \
23 ar9002_calib.o \
24 ar9003_calib.o \
25 calib.o \
17 eeprom.o \ 26 eeprom.o \
18 eeprom_def.o \ 27 eeprom_def.o \
19 eeprom_4k.o \ 28 eeprom_4k.o \
20 eeprom_9287.o \ 29 eeprom_9287.o \
21 calib.o \
22 ani.o \ 30 ani.o \
23 phy.o \
24 btcoex.o \ 31 btcoex.o \
25 mac.o \ 32 mac.o \
33 ar9002_mac.o \
34 ar9003_mac.o \
35 ar9003_eeprom.o
26 36
27obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 37obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
28 38
29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 39obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
30ath9k_common-y:= common.o 40ath9k_common-y:= common.o
41
42ath9k_htc-y += htc_hst.o \
43 hif_usb.o \
44 wmi.o \
45 htc_drv_txrx.o \
46 htc_drv_main.o \
47 htc_drv_beacon.o \
48 htc_drv_init.o
49
50obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index ca4994f13151..85fdd26039c8 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -47,6 +47,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
47} 47}
48 48
49static struct ath_bus_ops ath_ahb_bus_ops = { 49static struct ath_bus_ops ath_ahb_bus_ops = {
50 .ath_bus_type = ATH_AHB,
50 .read_cachesize = ath_ahb_read_cachesize, 51 .read_cachesize = ath_ahb_read_cachesize,
51 .eeprom_read = ath_ahb_eeprom_read, 52 .eeprom_read = ath_ahb_eeprom_read,
52}; 53};
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 2a0cd64c2bfb..ba8b20f01594 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h"
18 19
19static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 20static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
20 struct ath9k_channel *chan) 21 struct ath9k_channel *chan)
@@ -37,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
37 return 0; 38 return 0;
38} 39}
39 40
40static bool ath9k_hw_ani_control(struct ath_hw *ah,
41 enum ath9k_ani_cmd cmd, int param)
42{
43 struct ar5416AniState *aniState = ah->curani;
44 struct ath_common *common = ath9k_hw_common(ah);
45
46 switch (cmd & ah->ani_function) {
47 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
48 u32 level = param;
49
50 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
51 ath_print(common, ATH_DBG_ANI,
52 "level out of range (%u > %u)\n",
53 level,
54 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
55 return false;
56 }
57
58 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
59 AR_PHY_DESIRED_SZ_TOT_DES,
60 ah->totalSizeDesired[level]);
61 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
62 AR_PHY_AGC_CTL1_COARSE_LOW,
63 ah->coarse_low[level]);
64 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
65 AR_PHY_AGC_CTL1_COARSE_HIGH,
66 ah->coarse_high[level]);
67 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
68 AR_PHY_FIND_SIG_FIRPWR,
69 ah->firpwr[level]);
70
71 if (level > aniState->noiseImmunityLevel)
72 ah->stats.ast_ani_niup++;
73 else if (level < aniState->noiseImmunityLevel)
74 ah->stats.ast_ani_nidown++;
75 aniState->noiseImmunityLevel = level;
76 break;
77 }
78 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
79 const int m1ThreshLow[] = { 127, 50 };
80 const int m2ThreshLow[] = { 127, 40 };
81 const int m1Thresh[] = { 127, 0x4d };
82 const int m2Thresh[] = { 127, 0x40 };
83 const int m2CountThr[] = { 31, 16 };
84 const int m2CountThrLow[] = { 63, 48 };
85 u32 on = param ? 1 : 0;
86
87 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
88 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
89 m1ThreshLow[on]);
90 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
91 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
92 m2ThreshLow[on]);
93 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
94 AR_PHY_SFCORR_M1_THRESH,
95 m1Thresh[on]);
96 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
97 AR_PHY_SFCORR_M2_THRESH,
98 m2Thresh[on]);
99 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
100 AR_PHY_SFCORR_M2COUNT_THR,
101 m2CountThr[on]);
102 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
103 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
104 m2CountThrLow[on]);
105
106 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
107 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
108 m1ThreshLow[on]);
109 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
110 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
111 m2ThreshLow[on]);
112 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
113 AR_PHY_SFCORR_EXT_M1_THRESH,
114 m1Thresh[on]);
115 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
116 AR_PHY_SFCORR_EXT_M2_THRESH,
117 m2Thresh[on]);
118
119 if (on)
120 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
121 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
122 else
123 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
124 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
125
126 if (!on != aniState->ofdmWeakSigDetectOff) {
127 if (on)
128 ah->stats.ast_ani_ofdmon++;
129 else
130 ah->stats.ast_ani_ofdmoff++;
131 aniState->ofdmWeakSigDetectOff = !on;
132 }
133 break;
134 }
135 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
136 const int weakSigThrCck[] = { 8, 6 };
137 u32 high = param ? 1 : 0;
138
139 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
140 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
141 weakSigThrCck[high]);
142 if (high != aniState->cckWeakSigThreshold) {
143 if (high)
144 ah->stats.ast_ani_cckhigh++;
145 else
146 ah->stats.ast_ani_ccklow++;
147 aniState->cckWeakSigThreshold = high;
148 }
149 break;
150 }
151 case ATH9K_ANI_FIRSTEP_LEVEL:{
152 const int firstep[] = { 0, 4, 8 };
153 u32 level = param;
154
155 if (level >= ARRAY_SIZE(firstep)) {
156 ath_print(common, ATH_DBG_ANI,
157 "level out of range (%u > %u)\n",
158 level,
159 (unsigned) ARRAY_SIZE(firstep));
160 return false;
161 }
162 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
163 AR_PHY_FIND_SIG_FIRSTEP,
164 firstep[level]);
165 if (level > aniState->firstepLevel)
166 ah->stats.ast_ani_stepup++;
167 else if (level < aniState->firstepLevel)
168 ah->stats.ast_ani_stepdown++;
169 aniState->firstepLevel = level;
170 break;
171 }
172 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
173 const int cycpwrThr1[] =
174 { 2, 4, 6, 8, 10, 12, 14, 16 };
175 u32 level = param;
176
177 if (level >= ARRAY_SIZE(cycpwrThr1)) {
178 ath_print(common, ATH_DBG_ANI,
179 "level out of range (%u > %u)\n",
180 level,
181 (unsigned) ARRAY_SIZE(cycpwrThr1));
182 return false;
183 }
184 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
185 AR_PHY_TIMING5_CYCPWR_THR1,
186 cycpwrThr1[level]);
187 if (level > aniState->spurImmunityLevel)
188 ah->stats.ast_ani_spurup++;
189 else if (level < aniState->spurImmunityLevel)
190 ah->stats.ast_ani_spurdown++;
191 aniState->spurImmunityLevel = level;
192 break;
193 }
194 case ATH9K_ANI_PRESENT:
195 break;
196 default:
197 ath_print(common, ATH_DBG_ANI,
198 "invalid cmd %u\n", cmd);
199 return false;
200 }
201
202 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
203 ath_print(common, ATH_DBG_ANI,
204 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
205 "ofdmWeakSigDetectOff=%d\n",
206 aniState->noiseImmunityLevel,
207 aniState->spurImmunityLevel,
208 !aniState->ofdmWeakSigDetectOff);
209 ath_print(common, ATH_DBG_ANI,
210 "cckWeakSigThreshold=%d, "
211 "firstepLevel=%d, listenTime=%d\n",
212 aniState->cckWeakSigThreshold,
213 aniState->firstepLevel,
214 aniState->listenTime);
215 ath_print(common, ATH_DBG_ANI,
216 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
217 aniState->cycleCount,
218 aniState->ofdmPhyErrCount,
219 aniState->cckPhyErrCount);
220
221 return true;
222}
223
224static void ath9k_hw_update_mibstats(struct ath_hw *ah, 41static void ath9k_hw_update_mibstats(struct ath_hw *ah,
225 struct ath9k_mib_stats *stats) 42 struct ath9k_mib_stats *stats)
226{ 43{
@@ -262,11 +79,17 @@ static void ath9k_ani_restart(struct ath_hw *ah)
262 "Writing ofdmbase=%u cckbase=%u\n", 79 "Writing ofdmbase=%u cckbase=%u\n",
263 aniState->ofdmPhyErrBase, 80 aniState->ofdmPhyErrBase,
264 aniState->cckPhyErrBase); 81 aniState->cckPhyErrBase);
82
83 ENABLE_REGWRITE_BUFFER(ah);
84
265 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); 85 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
266 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); 86 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
267 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 87 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
268 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 88 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
269 89
90 REGWRITE_BUFFER_FLUSH(ah);
91 DISABLE_REGWRITE_BUFFER(ah);
92
270 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 93 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
271 94
272 aniState->ofdmPhyErrCount = 0; 95 aniState->ofdmPhyErrCount = 0;
@@ -540,8 +363,14 @@ void ath9k_ani_reset(struct ath_hw *ah)
540 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 363 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
541 ~ATH9K_RX_FILTER_PHYERR); 364 ~ATH9K_RX_FILTER_PHYERR);
542 ath9k_ani_restart(ah); 365 ath9k_ani_restart(ah);
366
367 ENABLE_REGWRITE_BUFFER(ah);
368
543 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 369 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
544 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 370 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
371
372 REGWRITE_BUFFER_FLUSH(ah);
373 DISABLE_REGWRITE_BUFFER(ah);
545} 374}
546 375
547void ath9k_hw_ani_monitor(struct ath_hw *ah, 376void ath9k_hw_ani_monitor(struct ath_hw *ah,
@@ -639,6 +468,8 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
639 468
640 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 469 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
641 470
471 ENABLE_REGWRITE_BUFFER(ah);
472
642 REG_WRITE(ah, AR_FILT_OFDM, 0); 473 REG_WRITE(ah, AR_FILT_OFDM, 0);
643 REG_WRITE(ah, AR_FILT_CCK, 0); 474 REG_WRITE(ah, AR_FILT_CCK, 0);
644 REG_WRITE(ah, AR_MIBC, 475 REG_WRITE(ah, AR_MIBC,
@@ -646,6 +477,9 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
646 & 0x0f); 477 & 0x0f);
647 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); 478 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
648 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); 479 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
480
481 REGWRITE_BUFFER_FLUSH(ah);
482 DISABLE_REGWRITE_BUFFER(ah);
649} 483}
650 484
651/* Freeze the MIB counters, get the stats and then clear them */ 485/* Freeze the MIB counters, get the stats and then clear them */
@@ -809,20 +643,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
809 ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", 643 ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
810 ah->ani[0].cckPhyErrBase); 644 ah->ani[0].cckPhyErrBase);
811 645
646 ENABLE_REGWRITE_BUFFER(ah);
647
812 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); 648 REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
813 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); 649 REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
650
651 REGWRITE_BUFFER_FLUSH(ah);
652 DISABLE_REGWRITE_BUFFER(ah);
653
814 ath9k_enable_mib_counters(ah); 654 ath9k_enable_mib_counters(ah);
815 655
816 ah->aniperiod = ATH9K_ANI_PERIOD; 656 ah->aniperiod = ATH9K_ANI_PERIOD;
817 if (ah->config.enable_ani) 657 if (ah->config.enable_ani)
818 ah->proc_phyerr |= HAL_PROCESS_ANI; 658 ah->proc_phyerr |= HAL_PROCESS_ANI;
819} 659}
820
821void ath9k_hw_ani_disable(struct ath_hw *ah)
822{
823 ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n");
824
825 ath9k_hw_disable_mib_counters(ah);
826 REG_WRITE(ah, AR_PHY_ERR_1, 0);
827 REG_WRITE(ah, AR_PHY_ERR_2, 0);
828}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 4e1ab94a5153..3356762ea384 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -118,6 +118,5 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
118void ath9k_hw_procmibevent(struct ath_hw *ah); 118void ath9k_hw_procmibevent(struct ath_hw *ah);
119void ath9k_hw_ani_setup(struct ath_hw *ah); 119void ath9k_hw_ani_setup(struct ath_hw *ah);
120void ath9k_hw_ani_init(struct ath_hw *ah); 120void ath9k_hw_ani_init(struct ath_hw *ah);
121void ath9k_hw_ani_disable(struct ath_hw *ah);
122 121
123#endif /* ANI_H */ 122#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
new file mode 100644
index 000000000000..025c31ac6146
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
@@ -0,0 +1,742 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_AR5008_H
18#define INITVALS_AR5008_H
19
20static const u32 ar5416Modes[][6] = {
21 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
22 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
23 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
24 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
25 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
26 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
27 { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
28 { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
29 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
30 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
31 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
32 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
33 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
34 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
35 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
36 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
37 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
38 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
39 { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
40 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
41 { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
42 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
43 { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
44 { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
45 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
46 { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
47 { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
48 { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
49 { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
50 { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
51 { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
52 { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
53 { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
54 { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
55 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
56 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
57 { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
58 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
59 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
60 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
61 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
62 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
63 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
64 { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
65 { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
66 { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
67 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
68 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
69 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
70 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
71 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
72 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
73 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
74 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
75 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
76 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
77 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
78 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
79 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
80 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
81 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
82 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
83 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
84};
85
86static const u32 ar5416Common[][2] = {
87 { 0x0000000c, 0x00000000 },
88 { 0x00000030, 0x00020015 },
89 { 0x00000034, 0x00000005 },
90 { 0x00000040, 0x00000000 },
91 { 0x00000044, 0x00000008 },
92 { 0x00000048, 0x00000008 },
93 { 0x0000004c, 0x00000010 },
94 { 0x00000050, 0x00000000 },
95 { 0x00000054, 0x0000001f },
96 { 0x00000800, 0x00000000 },
97 { 0x00000804, 0x00000000 },
98 { 0x00000808, 0x00000000 },
99 { 0x0000080c, 0x00000000 },
100 { 0x00000810, 0x00000000 },
101 { 0x00000814, 0x00000000 },
102 { 0x00000818, 0x00000000 },
103 { 0x0000081c, 0x00000000 },
104 { 0x00000820, 0x00000000 },
105 { 0x00000824, 0x00000000 },
106 { 0x00001040, 0x002ffc0f },
107 { 0x00001044, 0x002ffc0f },
108 { 0x00001048, 0x002ffc0f },
109 { 0x0000104c, 0x002ffc0f },
110 { 0x00001050, 0x002ffc0f },
111 { 0x00001054, 0x002ffc0f },
112 { 0x00001058, 0x002ffc0f },
113 { 0x0000105c, 0x002ffc0f },
114 { 0x00001060, 0x002ffc0f },
115 { 0x00001064, 0x002ffc0f },
116 { 0x00001230, 0x00000000 },
117 { 0x00001270, 0x00000000 },
118 { 0x00001038, 0x00000000 },
119 { 0x00001078, 0x00000000 },
120 { 0x000010b8, 0x00000000 },
121 { 0x000010f8, 0x00000000 },
122 { 0x00001138, 0x00000000 },
123 { 0x00001178, 0x00000000 },
124 { 0x000011b8, 0x00000000 },
125 { 0x000011f8, 0x00000000 },
126 { 0x00001238, 0x00000000 },
127 { 0x00001278, 0x00000000 },
128 { 0x000012b8, 0x00000000 },
129 { 0x000012f8, 0x00000000 },
130 { 0x00001338, 0x00000000 },
131 { 0x00001378, 0x00000000 },
132 { 0x000013b8, 0x00000000 },
133 { 0x000013f8, 0x00000000 },
134 { 0x00001438, 0x00000000 },
135 { 0x00001478, 0x00000000 },
136 { 0x000014b8, 0x00000000 },
137 { 0x000014f8, 0x00000000 },
138 { 0x00001538, 0x00000000 },
139 { 0x00001578, 0x00000000 },
140 { 0x000015b8, 0x00000000 },
141 { 0x000015f8, 0x00000000 },
142 { 0x00001638, 0x00000000 },
143 { 0x00001678, 0x00000000 },
144 { 0x000016b8, 0x00000000 },
145 { 0x000016f8, 0x00000000 },
146 { 0x00001738, 0x00000000 },
147 { 0x00001778, 0x00000000 },
148 { 0x000017b8, 0x00000000 },
149 { 0x000017f8, 0x00000000 },
150 { 0x0000103c, 0x00000000 },
151 { 0x0000107c, 0x00000000 },
152 { 0x000010bc, 0x00000000 },
153 { 0x000010fc, 0x00000000 },
154 { 0x0000113c, 0x00000000 },
155 { 0x0000117c, 0x00000000 },
156 { 0x000011bc, 0x00000000 },
157 { 0x000011fc, 0x00000000 },
158 { 0x0000123c, 0x00000000 },
159 { 0x0000127c, 0x00000000 },
160 { 0x000012bc, 0x00000000 },
161 { 0x000012fc, 0x00000000 },
162 { 0x0000133c, 0x00000000 },
163 { 0x0000137c, 0x00000000 },
164 { 0x000013bc, 0x00000000 },
165 { 0x000013fc, 0x00000000 },
166 { 0x0000143c, 0x00000000 },
167 { 0x0000147c, 0x00000000 },
168 { 0x00004030, 0x00000002 },
169 { 0x0000403c, 0x00000002 },
170 { 0x00007010, 0x00000000 },
171 { 0x00007038, 0x000004c2 },
172 { 0x00008004, 0x00000000 },
173 { 0x00008008, 0x00000000 },
174 { 0x0000800c, 0x00000000 },
175 { 0x00008018, 0x00000700 },
176 { 0x00008020, 0x00000000 },
177 { 0x00008038, 0x00000000 },
178 { 0x0000803c, 0x00000000 },
179 { 0x00008048, 0x40000000 },
180 { 0x00008054, 0x00000000 },
181 { 0x00008058, 0x00000000 },
182 { 0x0000805c, 0x000fc78f },
183 { 0x00008060, 0x0000000f },
184 { 0x00008064, 0x00000000 },
185 { 0x000080c0, 0x2a82301a },
186 { 0x000080c4, 0x05dc01e0 },
187 { 0x000080c8, 0x1f402710 },
188 { 0x000080cc, 0x01f40000 },
189 { 0x000080d0, 0x00001e00 },
190 { 0x000080d4, 0x00000000 },
191 { 0x000080d8, 0x00400000 },
192 { 0x000080e0, 0xffffffff },
193 { 0x000080e4, 0x0000ffff },
194 { 0x000080e8, 0x003f3f3f },
195 { 0x000080ec, 0x00000000 },
196 { 0x000080f0, 0x00000000 },
197 { 0x000080f4, 0x00000000 },
198 { 0x000080f8, 0x00000000 },
199 { 0x000080fc, 0x00020000 },
200 { 0x00008100, 0x00020000 },
201 { 0x00008104, 0x00000001 },
202 { 0x00008108, 0x00000052 },
203 { 0x0000810c, 0x00000000 },
204 { 0x00008110, 0x00000168 },
205 { 0x00008118, 0x000100aa },
206 { 0x0000811c, 0x00003210 },
207 { 0x00008124, 0x00000000 },
208 { 0x00008128, 0x00000000 },
209 { 0x0000812c, 0x00000000 },
210 { 0x00008130, 0x00000000 },
211 { 0x00008134, 0x00000000 },
212 { 0x00008138, 0x00000000 },
213 { 0x0000813c, 0x00000000 },
214 { 0x00008144, 0xffffffff },
215 { 0x00008168, 0x00000000 },
216 { 0x0000816c, 0x00000000 },
217 { 0x00008170, 0x32143320 },
218 { 0x00008174, 0xfaa4fa50 },
219 { 0x00008178, 0x00000100 },
220 { 0x0000817c, 0x00000000 },
221 { 0x000081c4, 0x00000000 },
222 { 0x000081ec, 0x00000000 },
223 { 0x000081f0, 0x00000000 },
224 { 0x000081f4, 0x00000000 },
225 { 0x000081f8, 0x00000000 },
226 { 0x000081fc, 0x00000000 },
227 { 0x00008200, 0x00000000 },
228 { 0x00008204, 0x00000000 },
229 { 0x00008208, 0x00000000 },
230 { 0x0000820c, 0x00000000 },
231 { 0x00008210, 0x00000000 },
232 { 0x00008214, 0x00000000 },
233 { 0x00008218, 0x00000000 },
234 { 0x0000821c, 0x00000000 },
235 { 0x00008220, 0x00000000 },
236 { 0x00008224, 0x00000000 },
237 { 0x00008228, 0x00000000 },
238 { 0x0000822c, 0x00000000 },
239 { 0x00008230, 0x00000000 },
240 { 0x00008234, 0x00000000 },
241 { 0x00008238, 0x00000000 },
242 { 0x0000823c, 0x00000000 },
243 { 0x00008240, 0x00100000 },
244 { 0x00008244, 0x0010f400 },
245 { 0x00008248, 0x00000100 },
246 { 0x0000824c, 0x0001e800 },
247 { 0x00008250, 0x00000000 },
248 { 0x00008254, 0x00000000 },
249 { 0x00008258, 0x00000000 },
250 { 0x0000825c, 0x400000ff },
251 { 0x00008260, 0x00080922 },
252 { 0x00008264, 0x88000010 },
253 { 0x00008270, 0x00000000 },
254 { 0x00008274, 0x40000000 },
255 { 0x00008278, 0x003e4180 },
256 { 0x0000827c, 0x00000000 },
257 { 0x00008284, 0x0000002c },
258 { 0x00008288, 0x0000002c },
259 { 0x0000828c, 0x00000000 },
260 { 0x00008294, 0x00000000 },
261 { 0x00008298, 0x00000000 },
262 { 0x00008300, 0x00000000 },
263 { 0x00008304, 0x00000000 },
264 { 0x00008308, 0x00000000 },
265 { 0x0000830c, 0x00000000 },
266 { 0x00008310, 0x00000000 },
267 { 0x00008314, 0x00000000 },
268 { 0x00008318, 0x00000000 },
269 { 0x00008328, 0x00000000 },
270 { 0x0000832c, 0x00000007 },
271 { 0x00008330, 0x00000302 },
272 { 0x00008334, 0x00000e00 },
273 { 0x00008338, 0x00070000 },
274 { 0x0000833c, 0x00000000 },
275 { 0x00008340, 0x000107ff },
276 { 0x00009808, 0x00000000 },
277 { 0x0000980c, 0xad848e19 },
278 { 0x00009810, 0x7d14e000 },
279 { 0x00009814, 0x9c0a9f6b },
280 { 0x0000981c, 0x00000000 },
281 { 0x0000982c, 0x0000a000 },
282 { 0x00009830, 0x00000000 },
283 { 0x0000983c, 0x00200400 },
284 { 0x00009840, 0x206a002e },
285 { 0x0000984c, 0x1284233c },
286 { 0x00009854, 0x00000859 },
287 { 0x00009900, 0x00000000 },
288 { 0x00009904, 0x00000000 },
289 { 0x00009908, 0x00000000 },
290 { 0x0000990c, 0x00000000 },
291 { 0x0000991c, 0x10000fff },
292 { 0x00009920, 0x05100000 },
293 { 0x0000a920, 0x05100000 },
294 { 0x0000b920, 0x05100000 },
295 { 0x00009928, 0x00000001 },
296 { 0x0000992c, 0x00000004 },
297 { 0x00009934, 0x1e1f2022 },
298 { 0x00009938, 0x0a0b0c0d },
299 { 0x0000993c, 0x00000000 },
300 { 0x00009948, 0x9280b212 },
301 { 0x0000994c, 0x00020028 },
302 { 0x00009954, 0x5d50e188 },
303 { 0x00009958, 0x00081fff },
304 { 0x0000c95c, 0x004b6a8e },
305 { 0x0000c968, 0x000003ce },
306 { 0x00009970, 0x190fb515 },
307 { 0x00009974, 0x00000000 },
308 { 0x00009978, 0x00000001 },
309 { 0x0000997c, 0x00000000 },
310 { 0x00009980, 0x00000000 },
311 { 0x00009984, 0x00000000 },
312 { 0x00009988, 0x00000000 },
313 { 0x0000998c, 0x00000000 },
314 { 0x00009990, 0x00000000 },
315 { 0x00009994, 0x00000000 },
316 { 0x00009998, 0x00000000 },
317 { 0x0000999c, 0x00000000 },
318 { 0x000099a0, 0x00000000 },
319 { 0x000099a4, 0x00000001 },
320 { 0x000099a8, 0x001fff00 },
321 { 0x000099ac, 0x00000000 },
322 { 0x000099b0, 0x03051000 },
323 { 0x000099dc, 0x00000000 },
324 { 0x000099e0, 0x00000200 },
325 { 0x000099e4, 0xaaaaaaaa },
326 { 0x000099e8, 0x3c466478 },
327 { 0x000099ec, 0x000000aa },
328 { 0x000099fc, 0x00001042 },
329 { 0x00009b00, 0x00000000 },
330 { 0x00009b04, 0x00000001 },
331 { 0x00009b08, 0x00000002 },
332 { 0x00009b0c, 0x00000003 },
333 { 0x00009b10, 0x00000004 },
334 { 0x00009b14, 0x00000005 },
335 { 0x00009b18, 0x00000008 },
336 { 0x00009b1c, 0x00000009 },
337 { 0x00009b20, 0x0000000a },
338 { 0x00009b24, 0x0000000b },
339 { 0x00009b28, 0x0000000c },
340 { 0x00009b2c, 0x0000000d },
341 { 0x00009b30, 0x00000010 },
342 { 0x00009b34, 0x00000011 },
343 { 0x00009b38, 0x00000012 },
344 { 0x00009b3c, 0x00000013 },
345 { 0x00009b40, 0x00000014 },
346 { 0x00009b44, 0x00000015 },
347 { 0x00009b48, 0x00000018 },
348 { 0x00009b4c, 0x00000019 },
349 { 0x00009b50, 0x0000001a },
350 { 0x00009b54, 0x0000001b },
351 { 0x00009b58, 0x0000001c },
352 { 0x00009b5c, 0x0000001d },
353 { 0x00009b60, 0x00000020 },
354 { 0x00009b64, 0x00000021 },
355 { 0x00009b68, 0x00000022 },
356 { 0x00009b6c, 0x00000023 },
357 { 0x00009b70, 0x00000024 },
358 { 0x00009b74, 0x00000025 },
359 { 0x00009b78, 0x00000028 },
360 { 0x00009b7c, 0x00000029 },
361 { 0x00009b80, 0x0000002a },
362 { 0x00009b84, 0x0000002b },
363 { 0x00009b88, 0x0000002c },
364 { 0x00009b8c, 0x0000002d },
365 { 0x00009b90, 0x00000030 },
366 { 0x00009b94, 0x00000031 },
367 { 0x00009b98, 0x00000032 },
368 { 0x00009b9c, 0x00000033 },
369 { 0x00009ba0, 0x00000034 },
370 { 0x00009ba4, 0x00000035 },
371 { 0x00009ba8, 0x00000035 },
372 { 0x00009bac, 0x00000035 },
373 { 0x00009bb0, 0x00000035 },
374 { 0x00009bb4, 0x00000035 },
375 { 0x00009bb8, 0x00000035 },
376 { 0x00009bbc, 0x00000035 },
377 { 0x00009bc0, 0x00000035 },
378 { 0x00009bc4, 0x00000035 },
379 { 0x00009bc8, 0x00000035 },
380 { 0x00009bcc, 0x00000035 },
381 { 0x00009bd0, 0x00000035 },
382 { 0x00009bd4, 0x00000035 },
383 { 0x00009bd8, 0x00000035 },
384 { 0x00009bdc, 0x00000035 },
385 { 0x00009be0, 0x00000035 },
386 { 0x00009be4, 0x00000035 },
387 { 0x00009be8, 0x00000035 },
388 { 0x00009bec, 0x00000035 },
389 { 0x00009bf0, 0x00000035 },
390 { 0x00009bf4, 0x00000035 },
391 { 0x00009bf8, 0x00000010 },
392 { 0x00009bfc, 0x0000001a },
393 { 0x0000a210, 0x40806333 },
394 { 0x0000a214, 0x00106c10 },
395 { 0x0000a218, 0x009c4060 },
396 { 0x0000a220, 0x018830c6 },
397 { 0x0000a224, 0x00000400 },
398 { 0x0000a228, 0x00000bb5 },
399 { 0x0000a22c, 0x00000011 },
400 { 0x0000a234, 0x20202020 },
401 { 0x0000a238, 0x20202020 },
402 { 0x0000a23c, 0x13c889af },
403 { 0x0000a240, 0x38490a20 },
404 { 0x0000a244, 0x00007bb6 },
405 { 0x0000a248, 0x0fff3ffc },
406 { 0x0000a24c, 0x00000001 },
407 { 0x0000a250, 0x0000a000 },
408 { 0x0000a254, 0x00000000 },
409 { 0x0000a258, 0x0cc75380 },
410 { 0x0000a25c, 0x0f0f0f01 },
411 { 0x0000a260, 0xdfa91f01 },
412 { 0x0000a268, 0x00000000 },
413 { 0x0000a26c, 0x0e79e5c6 },
414 { 0x0000b26c, 0x0e79e5c6 },
415 { 0x0000c26c, 0x0e79e5c6 },
416 { 0x0000d270, 0x00820820 },
417 { 0x0000a278, 0x1ce739ce },
418 { 0x0000a27c, 0x051701ce },
419 { 0x0000a338, 0x00000000 },
420 { 0x0000a33c, 0x00000000 },
421 { 0x0000a340, 0x00000000 },
422 { 0x0000a344, 0x00000000 },
423 { 0x0000a348, 0x3fffffff },
424 { 0x0000a34c, 0x3fffffff },
425 { 0x0000a350, 0x3fffffff },
426 { 0x0000a354, 0x0003ffff },
427 { 0x0000a358, 0x79a8aa1f },
428 { 0x0000d35c, 0x07ffffef },
429 { 0x0000d360, 0x0fffffe7 },
430 { 0x0000d364, 0x17ffffe5 },
431 { 0x0000d368, 0x1fffffe4 },
432 { 0x0000d36c, 0x37ffffe3 },
433 { 0x0000d370, 0x3fffffe3 },
434 { 0x0000d374, 0x57ffffe3 },
435 { 0x0000d378, 0x5fffffe2 },
436 { 0x0000d37c, 0x7fffffe2 },
437 { 0x0000d380, 0x7f3c7bba },
438 { 0x0000d384, 0xf3307ff0 },
439 { 0x0000a388, 0x08000000 },
440 { 0x0000a38c, 0x20202020 },
441 { 0x0000a390, 0x20202020 },
442 { 0x0000a394, 0x1ce739ce },
443 { 0x0000a398, 0x000001ce },
444 { 0x0000a39c, 0x00000001 },
445 { 0x0000a3a0, 0x00000000 },
446 { 0x0000a3a4, 0x00000000 },
447 { 0x0000a3a8, 0x00000000 },
448 { 0x0000a3ac, 0x00000000 },
449 { 0x0000a3b0, 0x00000000 },
450 { 0x0000a3b4, 0x00000000 },
451 { 0x0000a3b8, 0x00000000 },
452 { 0x0000a3bc, 0x00000000 },
453 { 0x0000a3c0, 0x00000000 },
454 { 0x0000a3c4, 0x00000000 },
455 { 0x0000a3c8, 0x00000246 },
456 { 0x0000a3cc, 0x20202020 },
457 { 0x0000a3d0, 0x20202020 },
458 { 0x0000a3d4, 0x20202020 },
459 { 0x0000a3dc, 0x1ce739ce },
460 { 0x0000a3e0, 0x000001ce },
461};
462
463static const u32 ar5416Bank0[][2] = {
464 { 0x000098b0, 0x1e5795e5 },
465 { 0x000098e0, 0x02008020 },
466};
467
468static const u32 ar5416BB_RfGain[][3] = {
469 { 0x00009a00, 0x00000000, 0x00000000 },
470 { 0x00009a04, 0x00000040, 0x00000040 },
471 { 0x00009a08, 0x00000080, 0x00000080 },
472 { 0x00009a0c, 0x000001a1, 0x00000141 },
473 { 0x00009a10, 0x000001e1, 0x00000181 },
474 { 0x00009a14, 0x00000021, 0x000001c1 },
475 { 0x00009a18, 0x00000061, 0x00000001 },
476 { 0x00009a1c, 0x00000168, 0x00000041 },
477 { 0x00009a20, 0x000001a8, 0x000001a8 },
478 { 0x00009a24, 0x000001e8, 0x000001e8 },
479 { 0x00009a28, 0x00000028, 0x00000028 },
480 { 0x00009a2c, 0x00000068, 0x00000068 },
481 { 0x00009a30, 0x00000189, 0x000000a8 },
482 { 0x00009a34, 0x000001c9, 0x00000169 },
483 { 0x00009a38, 0x00000009, 0x000001a9 },
484 { 0x00009a3c, 0x00000049, 0x000001e9 },
485 { 0x00009a40, 0x00000089, 0x00000029 },
486 { 0x00009a44, 0x00000170, 0x00000069 },
487 { 0x00009a48, 0x000001b0, 0x00000190 },
488 { 0x00009a4c, 0x000001f0, 0x000001d0 },
489 { 0x00009a50, 0x00000030, 0x00000010 },
490 { 0x00009a54, 0x00000070, 0x00000050 },
491 { 0x00009a58, 0x00000191, 0x00000090 },
492 { 0x00009a5c, 0x000001d1, 0x00000151 },
493 { 0x00009a60, 0x00000011, 0x00000191 },
494 { 0x00009a64, 0x00000051, 0x000001d1 },
495 { 0x00009a68, 0x00000091, 0x00000011 },
496 { 0x00009a6c, 0x000001b8, 0x00000051 },
497 { 0x00009a70, 0x000001f8, 0x00000198 },
498 { 0x00009a74, 0x00000038, 0x000001d8 },
499 { 0x00009a78, 0x00000078, 0x00000018 },
500 { 0x00009a7c, 0x00000199, 0x00000058 },
501 { 0x00009a80, 0x000001d9, 0x00000098 },
502 { 0x00009a84, 0x00000019, 0x00000159 },
503 { 0x00009a88, 0x00000059, 0x00000199 },
504 { 0x00009a8c, 0x00000099, 0x000001d9 },
505 { 0x00009a90, 0x000000d9, 0x00000019 },
506 { 0x00009a94, 0x000000f9, 0x00000059 },
507 { 0x00009a98, 0x000000f9, 0x00000099 },
508 { 0x00009a9c, 0x000000f9, 0x000000d9 },
509 { 0x00009aa0, 0x000000f9, 0x000000f9 },
510 { 0x00009aa4, 0x000000f9, 0x000000f9 },
511 { 0x00009aa8, 0x000000f9, 0x000000f9 },
512 { 0x00009aac, 0x000000f9, 0x000000f9 },
513 { 0x00009ab0, 0x000000f9, 0x000000f9 },
514 { 0x00009ab4, 0x000000f9, 0x000000f9 },
515 { 0x00009ab8, 0x000000f9, 0x000000f9 },
516 { 0x00009abc, 0x000000f9, 0x000000f9 },
517 { 0x00009ac0, 0x000000f9, 0x000000f9 },
518 { 0x00009ac4, 0x000000f9, 0x000000f9 },
519 { 0x00009ac8, 0x000000f9, 0x000000f9 },
520 { 0x00009acc, 0x000000f9, 0x000000f9 },
521 { 0x00009ad0, 0x000000f9, 0x000000f9 },
522 { 0x00009ad4, 0x000000f9, 0x000000f9 },
523 { 0x00009ad8, 0x000000f9, 0x000000f9 },
524 { 0x00009adc, 0x000000f9, 0x000000f9 },
525 { 0x00009ae0, 0x000000f9, 0x000000f9 },
526 { 0x00009ae4, 0x000000f9, 0x000000f9 },
527 { 0x00009ae8, 0x000000f9, 0x000000f9 },
528 { 0x00009aec, 0x000000f9, 0x000000f9 },
529 { 0x00009af0, 0x000000f9, 0x000000f9 },
530 { 0x00009af4, 0x000000f9, 0x000000f9 },
531 { 0x00009af8, 0x000000f9, 0x000000f9 },
532 { 0x00009afc, 0x000000f9, 0x000000f9 },
533};
534
535static const u32 ar5416Bank1[][2] = {
536 { 0x000098b0, 0x02108421 },
537 { 0x000098ec, 0x00000008 },
538};
539
540static const u32 ar5416Bank2[][2] = {
541 { 0x000098b0, 0x0e73ff17 },
542 { 0x000098e0, 0x00000420 },
543};
544
545static const u32 ar5416Bank3[][3] = {
546 { 0x000098f0, 0x01400018, 0x01c00018 },
547};
548
549static const u32 ar5416Bank6[][3] = {
550
551 { 0x0000989c, 0x00000000, 0x00000000 },
552 { 0x0000989c, 0x00000000, 0x00000000 },
553 { 0x0000989c, 0x00000000, 0x00000000 },
554 { 0x0000989c, 0x00e00000, 0x00e00000 },
555 { 0x0000989c, 0x005e0000, 0x005e0000 },
556 { 0x0000989c, 0x00120000, 0x00120000 },
557 { 0x0000989c, 0x00620000, 0x00620000 },
558 { 0x0000989c, 0x00020000, 0x00020000 },
559 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
560 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
561 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
562 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
563 { 0x0000989c, 0x005f0000, 0x005f0000 },
564 { 0x0000989c, 0x00870000, 0x00870000 },
565 { 0x0000989c, 0x00f90000, 0x00f90000 },
566 { 0x0000989c, 0x007b0000, 0x007b0000 },
567 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
568 { 0x0000989c, 0x00f50000, 0x00f50000 },
569 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
570 { 0x0000989c, 0x00110000, 0x00110000 },
571 { 0x0000989c, 0x006100a8, 0x006100a8 },
572 { 0x0000989c, 0x004210a2, 0x004210a2 },
573 { 0x0000989c, 0x0014008f, 0x0014008f },
574 { 0x0000989c, 0x00c40003, 0x00c40003 },
575 { 0x0000989c, 0x003000f2, 0x003000f2 },
576 { 0x0000989c, 0x00440016, 0x00440016 },
577 { 0x0000989c, 0x00410040, 0x00410040 },
578 { 0x0000989c, 0x0001805e, 0x0001805e },
579 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
580 { 0x0000989c, 0x000000f1, 0x000000f1 },
581 { 0x0000989c, 0x00002081, 0x00002081 },
582 { 0x0000989c, 0x000000d4, 0x000000d4 },
583 { 0x000098d0, 0x0000000f, 0x0010000f },
584};
585
586static const u32 ar5416Bank6TPC[][3] = {
587 { 0x0000989c, 0x00000000, 0x00000000 },
588 { 0x0000989c, 0x00000000, 0x00000000 },
589 { 0x0000989c, 0x00000000, 0x00000000 },
590 { 0x0000989c, 0x00e00000, 0x00e00000 },
591 { 0x0000989c, 0x005e0000, 0x005e0000 },
592 { 0x0000989c, 0x00120000, 0x00120000 },
593 { 0x0000989c, 0x00620000, 0x00620000 },
594 { 0x0000989c, 0x00020000, 0x00020000 },
595 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
596 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
597 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
598 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
599 { 0x0000989c, 0x005f0000, 0x005f0000 },
600 { 0x0000989c, 0x00870000, 0x00870000 },
601 { 0x0000989c, 0x00f90000, 0x00f90000 },
602 { 0x0000989c, 0x007b0000, 0x007b0000 },
603 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
604 { 0x0000989c, 0x00f50000, 0x00f50000 },
605 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
606 { 0x0000989c, 0x00110000, 0x00110000 },
607 { 0x0000989c, 0x006100a8, 0x006100a8 },
608 { 0x0000989c, 0x00423022, 0x00423022 },
609 { 0x0000989c, 0x201400df, 0x201400df },
610 { 0x0000989c, 0x00c40002, 0x00c40002 },
611 { 0x0000989c, 0x003000f2, 0x003000f2 },
612 { 0x0000989c, 0x00440016, 0x00440016 },
613 { 0x0000989c, 0x00410040, 0x00410040 },
614 { 0x0000989c, 0x0001805e, 0x0001805e },
615 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
616 { 0x0000989c, 0x000000e1, 0x000000e1 },
617 { 0x0000989c, 0x00007081, 0x00007081 },
618 { 0x0000989c, 0x000000d4, 0x000000d4 },
619 { 0x000098d0, 0x0000000f, 0x0010000f },
620};
621
622static const u32 ar5416Bank7[][2] = {
623 { 0x0000989c, 0x00000500 },
624 { 0x0000989c, 0x00000800 },
625 { 0x000098cc, 0x0000000e },
626};
627
628static const u32 ar5416Addac[][2] = {
629 {0x0000989c, 0x00000000 },
630 {0x0000989c, 0x00000003 },
631 {0x0000989c, 0x00000000 },
632 {0x0000989c, 0x0000000c },
633 {0x0000989c, 0x00000000 },
634 {0x0000989c, 0x00000030 },
635 {0x0000989c, 0x00000000 },
636 {0x0000989c, 0x00000000 },
637 {0x0000989c, 0x00000000 },
638 {0x0000989c, 0x00000000 },
639 {0x0000989c, 0x00000000 },
640 {0x0000989c, 0x00000000 },
641 {0x0000989c, 0x00000000 },
642 {0x0000989c, 0x00000000 },
643 {0x0000989c, 0x00000000 },
644 {0x0000989c, 0x00000000 },
645 {0x0000989c, 0x00000000 },
646 {0x0000989c, 0x00000000 },
647 {0x0000989c, 0x00000060 },
648 {0x0000989c, 0x00000000 },
649 {0x0000989c, 0x00000000 },
650 {0x0000989c, 0x00000000 },
651 {0x0000989c, 0x00000000 },
652 {0x0000989c, 0x00000000 },
653 {0x0000989c, 0x00000000 },
654 {0x0000989c, 0x00000000 },
655 {0x0000989c, 0x00000000 },
656 {0x0000989c, 0x00000000 },
657 {0x0000989c, 0x00000000 },
658 {0x0000989c, 0x00000000 },
659 {0x0000989c, 0x00000000 },
660 {0x0000989c, 0x00000058 },
661 {0x0000989c, 0x00000000 },
662 {0x0000989c, 0x00000000 },
663 {0x0000989c, 0x00000000 },
664 {0x0000989c, 0x00000000 },
665 {0x000098cc, 0x00000000 },
666};
667
668static const u32 ar5416Modes_9100[][6] = {
669 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
670 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
671 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
672 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
673 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
674 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
675 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
676 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
677 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
678 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
679 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
680 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
681 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
682 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
683 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
684 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
685 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
686 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
687 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
688 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
689 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
690 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
691 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
692 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
693 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
694 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
695 { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
696 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
697 { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
698 { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
699#ifdef TB243
700 { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
701 { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
702 { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
703 { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
704#else
705 { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
706 { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
707 { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
708 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
709#endif
710 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
711 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
712 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
713 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
714 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
715 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
716 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
717 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
718 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
719 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
720 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
721 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
722 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
723 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
724 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
725 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
726 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
727 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
728 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
729 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
730 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
731 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
732 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
733 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
734 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
735 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
736 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
737 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
738 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
739 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
740};
741
742#endif /* INITVALS_AR5008_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
new file mode 100644
index 000000000000..b2c17c98bb38
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -0,0 +1,1374 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "hw-ops.h"
19#include "../regd.h"
20#include "ar9002_phy.h"
21
22/* All code below is for non single-chip solutions */
23
24/**
25 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
26 * @rfbuf:
27 * @reg32:
28 * @numBits:
29 * @firstBit:
30 * @column:
31 *
32 * Performs analog "swizzling" of parameters into their location.
33 * Used on external AR2133/AR5133 radios.
34 */
35static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
36 u32 numBits, u32 firstBit,
37 u32 column)
38{
39 u32 tmp32, mask, arrayEntry, lastBit;
40 int32_t bitPosition, bitsLeft;
41
42 tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
43 arrayEntry = (firstBit - 1) / 8;
44 bitPosition = (firstBit - 1) % 8;
45 bitsLeft = numBits;
46 while (bitsLeft > 0) {
47 lastBit = (bitPosition + bitsLeft > 8) ?
48 8 : bitPosition + bitsLeft;
49 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
50 (column * 8);
51 rfBuf[arrayEntry] &= ~mask;
52 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
53 (column * 8)) & mask;
54 bitsLeft -= 8 - bitPosition;
55 tmp32 = tmp32 >> (8 - bitPosition);
56 bitPosition = 0;
57 arrayEntry++;
58 }
59}
60
61/*
62 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
63 * rf_pwd_icsyndiv.
64 *
65 * Theoretical Rules:
66 * if 2 GHz band
67 * if forceBiasAuto
68 * if synth_freq < 2412
69 * bias = 0
70 * else if 2412 <= synth_freq <= 2422
71 * bias = 1
72 * else // synth_freq > 2422
73 * bias = 2
74 * else if forceBias > 0
75 * bias = forceBias & 7
76 * else
77 * no change, use value from ini file
78 * else
79 * no change, invalid band
80 *
81 * 1st Mod:
82 * 2422 also uses value of 2
83 * <approved>
84 *
85 * 2nd Mod:
86 * Less than 2412 uses value of 0, 2412 and above uses value of 2
87 */
88static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
89{
90 struct ath_common *common = ath9k_hw_common(ah);
91 u32 tmp_reg;
92 int reg_writes = 0;
93 u32 new_bias = 0;
94
95 if (!AR_SREV_5416(ah) || synth_freq >= 3000)
96 return;
97
98 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
99
100 if (synth_freq < 2412)
101 new_bias = 0;
102 else if (synth_freq < 2422)
103 new_bias = 1;
104 else
105 new_bias = 2;
106
107 /* pre-reverse this field */
108 tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
109
110 ath_print(common, ATH_DBG_CONFIG,
111 "Force rf_pwd_icsyndiv to %1d on %4d\n",
112 new_bias, synth_freq);
113
114 /* swizzle rf_pwd_icsyndiv */
115 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
116
117 /* write Bank 6 with new params */
118 REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
119}
120
121/**
122 * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
123 * @ah: atheros hardware stucture
124 * @chan:
125 *
126 * For the external AR2133/AR5133 radios, takes the MHz channel value and set
127 * the channel value. Assumes writes enabled to analog bus and bank6 register
128 * cache in ah->analogBank6Data.
129 */
130static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
131{
132 struct ath_common *common = ath9k_hw_common(ah);
133 u32 channelSel = 0;
134 u32 bModeSynth = 0;
135 u32 aModeRefSel = 0;
136 u32 reg32 = 0;
137 u16 freq;
138 struct chan_centers centers;
139
140 ath9k_hw_get_channel_centers(ah, chan, &centers);
141 freq = centers.synth_center;
142
143 if (freq < 4800) {
144 u32 txctl;
145
146 if (((freq - 2192) % 5) == 0) {
147 channelSel = ((freq - 672) * 2 - 3040) / 10;
148 bModeSynth = 0;
149 } else if (((freq - 2224) % 5) == 0) {
150 channelSel = ((freq - 704) * 2 - 3040) / 10;
151 bModeSynth = 1;
152 } else {
153 ath_print(common, ATH_DBG_FATAL,
154 "Invalid channel %u MHz\n", freq);
155 return -EINVAL;
156 }
157
158 channelSel = (channelSel << 2) & 0xff;
159 channelSel = ath9k_hw_reverse_bits(channelSel, 8);
160
161 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
162 if (freq == 2484) {
163
164 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
165 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
166 } else {
167 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
168 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
169 }
170
171 } else if ((freq % 20) == 0 && freq >= 5120) {
172 channelSel =
173 ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
174 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
175 } else if ((freq % 10) == 0) {
176 channelSel =
177 ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
178 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
179 aModeRefSel = ath9k_hw_reverse_bits(2, 2);
180 else
181 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
182 } else if ((freq % 5) == 0) {
183 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
184 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
185 } else {
186 ath_print(common, ATH_DBG_FATAL,
187 "Invalid channel %u MHz\n", freq);
188 return -EINVAL;
189 }
190
191 ar5008_hw_force_bias(ah, freq);
192
193 reg32 =
194 (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
195 (1 << 5) | 0x1;
196
197 REG_WRITE(ah, AR_PHY(0x37), reg32);
198
199 ah->curchan = chan;
200 ah->curchan_rad_index = -1;
201
202 return 0;
203}
204
205/**
206 * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios
207 * @ah: atheros hardware structure
208 * @chan:
209 *
210 * For non single-chip solutions. Converts to baseband spur frequency given the
211 * input channel frequency and compute register settings below.
212 */
213static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
214 struct ath9k_channel *chan)
215{
216 int bb_spur = AR_NO_SPUR;
217 int bin, cur_bin;
218 int spur_freq_sd;
219 int spur_delta_phase;
220 int denominator;
221 int upper, lower, cur_vit_mask;
222 int tmp, new;
223 int i;
224 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
225 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
226 };
227 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
228 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
229 };
230 int inc[4] = { 0, 100, 0, 0 };
231
232 int8_t mask_m[123];
233 int8_t mask_p[123];
234 int8_t mask_amt;
235 int tmp_mask;
236 int cur_bb_spur;
237 bool is2GHz = IS_CHAN_2GHZ(chan);
238
239 memset(&mask_m, 0, sizeof(int8_t) * 123);
240 memset(&mask_p, 0, sizeof(int8_t) * 123);
241
242 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
243 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
244 if (AR_NO_SPUR == cur_bb_spur)
245 break;
246 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
247 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
248 bb_spur = cur_bb_spur;
249 break;
250 }
251 }
252
253 if (AR_NO_SPUR == bb_spur)
254 return;
255
256 bin = bb_spur * 32;
257
258 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
259 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
260 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
261 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
262 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
263
264 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
265
266 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
267 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
268 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
269 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
270 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
271 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
272
273 spur_delta_phase = ((bb_spur * 524288) / 100) &
274 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
275
276 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
277 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
278
279 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
280 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
281 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
282 REG_WRITE(ah, AR_PHY_TIMING11, new);
283
284 cur_bin = -6000;
285 upper = bin + 100;
286 lower = bin - 100;
287
288 for (i = 0; i < 4; i++) {
289 int pilot_mask = 0;
290 int chan_mask = 0;
291 int bp = 0;
292 for (bp = 0; bp < 30; bp++) {
293 if ((cur_bin > lower) && (cur_bin < upper)) {
294 pilot_mask = pilot_mask | 0x1 << bp;
295 chan_mask = chan_mask | 0x1 << bp;
296 }
297 cur_bin += 100;
298 }
299 cur_bin += inc[i];
300 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
301 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
302 }
303
304 cur_vit_mask = 6100;
305 upper = bin + 120;
306 lower = bin - 120;
307
308 for (i = 0; i < 123; i++) {
309 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
310
311 /* workaround for gcc bug #37014 */
312 volatile int tmp_v = abs(cur_vit_mask - bin);
313
314 if (tmp_v < 75)
315 mask_amt = 1;
316 else
317 mask_amt = 0;
318 if (cur_vit_mask < 0)
319 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
320 else
321 mask_p[cur_vit_mask / 100] = mask_amt;
322 }
323 cur_vit_mask -= 100;
324 }
325
326 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
327 | (mask_m[48] << 26) | (mask_m[49] << 24)
328 | (mask_m[50] << 22) | (mask_m[51] << 20)
329 | (mask_m[52] << 18) | (mask_m[53] << 16)
330 | (mask_m[54] << 14) | (mask_m[55] << 12)
331 | (mask_m[56] << 10) | (mask_m[57] << 8)
332 | (mask_m[58] << 6) | (mask_m[59] << 4)
333 | (mask_m[60] << 2) | (mask_m[61] << 0);
334 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
335 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
336
337 tmp_mask = (mask_m[31] << 28)
338 | (mask_m[32] << 26) | (mask_m[33] << 24)
339 | (mask_m[34] << 22) | (mask_m[35] << 20)
340 | (mask_m[36] << 18) | (mask_m[37] << 16)
341 | (mask_m[48] << 14) | (mask_m[39] << 12)
342 | (mask_m[40] << 10) | (mask_m[41] << 8)
343 | (mask_m[42] << 6) | (mask_m[43] << 4)
344 | (mask_m[44] << 2) | (mask_m[45] << 0);
345 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
346 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
347
348 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
349 | (mask_m[18] << 26) | (mask_m[18] << 24)
350 | (mask_m[20] << 22) | (mask_m[20] << 20)
351 | (mask_m[22] << 18) | (mask_m[22] << 16)
352 | (mask_m[24] << 14) | (mask_m[24] << 12)
353 | (mask_m[25] << 10) | (mask_m[26] << 8)
354 | (mask_m[27] << 6) | (mask_m[28] << 4)
355 | (mask_m[29] << 2) | (mask_m[30] << 0);
356 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
357 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
358
359 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
360 | (mask_m[2] << 26) | (mask_m[3] << 24)
361 | (mask_m[4] << 22) | (mask_m[5] << 20)
362 | (mask_m[6] << 18) | (mask_m[7] << 16)
363 | (mask_m[8] << 14) | (mask_m[9] << 12)
364 | (mask_m[10] << 10) | (mask_m[11] << 8)
365 | (mask_m[12] << 6) | (mask_m[13] << 4)
366 | (mask_m[14] << 2) | (mask_m[15] << 0);
367 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
368 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
369
370 tmp_mask = (mask_p[15] << 28)
371 | (mask_p[14] << 26) | (mask_p[13] << 24)
372 | (mask_p[12] << 22) | (mask_p[11] << 20)
373 | (mask_p[10] << 18) | (mask_p[9] << 16)
374 | (mask_p[8] << 14) | (mask_p[7] << 12)
375 | (mask_p[6] << 10) | (mask_p[5] << 8)
376 | (mask_p[4] << 6) | (mask_p[3] << 4)
377 | (mask_p[2] << 2) | (mask_p[1] << 0);
378 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
379 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
380
381 tmp_mask = (mask_p[30] << 28)
382 | (mask_p[29] << 26) | (mask_p[28] << 24)
383 | (mask_p[27] << 22) | (mask_p[26] << 20)
384 | (mask_p[25] << 18) | (mask_p[24] << 16)
385 | (mask_p[23] << 14) | (mask_p[22] << 12)
386 | (mask_p[21] << 10) | (mask_p[20] << 8)
387 | (mask_p[19] << 6) | (mask_p[18] << 4)
388 | (mask_p[17] << 2) | (mask_p[16] << 0);
389 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
390 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
391
392 tmp_mask = (mask_p[45] << 28)
393 | (mask_p[44] << 26) | (mask_p[43] << 24)
394 | (mask_p[42] << 22) | (mask_p[41] << 20)
395 | (mask_p[40] << 18) | (mask_p[39] << 16)
396 | (mask_p[38] << 14) | (mask_p[37] << 12)
397 | (mask_p[36] << 10) | (mask_p[35] << 8)
398 | (mask_p[34] << 6) | (mask_p[33] << 4)
399 | (mask_p[32] << 2) | (mask_p[31] << 0);
400 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
401 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
402
403 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
404 | (mask_p[59] << 26) | (mask_p[58] << 24)
405 | (mask_p[57] << 22) | (mask_p[56] << 20)
406 | (mask_p[55] << 18) | (mask_p[54] << 16)
407 | (mask_p[53] << 14) | (mask_p[52] << 12)
408 | (mask_p[51] << 10) | (mask_p[50] << 8)
409 | (mask_p[49] << 6) | (mask_p[48] << 4)
410 | (mask_p[47] << 2) | (mask_p[46] << 0);
411 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
412 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
413}
414
415/**
416 * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming
417 * @ah: atheros hardware structure
418 *
419 * Only required for older devices with external AR2133/AR5133 radios.
420 */
421static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
422{
423#define ATH_ALLOC_BANK(bank, size) do { \
424 bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
425 if (!bank) { \
426 ath_print(common, ATH_DBG_FATAL, \
427 "Cannot allocate RF banks\n"); \
428 return -ENOMEM; \
429 } \
430 } while (0);
431
432 struct ath_common *common = ath9k_hw_common(ah);
433
434 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
435
436 ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
437 ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
438 ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
439 ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
440 ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
441 ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
442 ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
443 ATH_ALLOC_BANK(ah->addac5416_21,
444 ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
445 ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
446
447 return 0;
448#undef ATH_ALLOC_BANK
449}
450
451
452/**
453 * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
454 * @ah: atheros hardware struture
455 * For the external AR2133/AR5133 radios banks.
456 */
457static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
458{
459#define ATH_FREE_BANK(bank) do { \
460 kfree(bank); \
461 bank = NULL; \
462 } while (0);
463
464 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
465
466 ATH_FREE_BANK(ah->analogBank0Data);
467 ATH_FREE_BANK(ah->analogBank1Data);
468 ATH_FREE_BANK(ah->analogBank2Data);
469 ATH_FREE_BANK(ah->analogBank3Data);
470 ATH_FREE_BANK(ah->analogBank6Data);
471 ATH_FREE_BANK(ah->analogBank6TPCData);
472 ATH_FREE_BANK(ah->analogBank7Data);
473 ATH_FREE_BANK(ah->addac5416_21);
474 ATH_FREE_BANK(ah->bank6Temp);
475
476#undef ATH_FREE_BANK
477}
478
479/* *
480 * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM
481 * @ah: atheros hardware structure
482 * @chan:
483 * @modesIndex:
484 *
485 * Used for the external AR2133/AR5133 radios.
486 *
487 * Reads the EEPROM header info from the device structure and programs
488 * all rf registers. This routine requires access to the analog
489 * rf device. This is not required for single-chip devices.
490 */
491static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
492 struct ath9k_channel *chan,
493 u16 modesIndex)
494{
495 u32 eepMinorRev;
496 u32 ob5GHz = 0, db5GHz = 0;
497 u32 ob2GHz = 0, db2GHz = 0;
498 int regWrites = 0;
499
500 /*
501 * Software does not need to program bank data
502 * for single chip devices, that is AR9280 or anything
503 * after that.
504 */
505 if (AR_SREV_9280_10_OR_LATER(ah))
506 return true;
507
508 /* Setup rf parameters */
509 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
510
511 /* Setup Bank 0 Write */
512 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
513
514 /* Setup Bank 1 Write */
515 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
516
517 /* Setup Bank 2 Write */
518 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
519
520 /* Setup Bank 6 Write */
521 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
522 modesIndex);
523 {
524 int i;
525 for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
526 ah->analogBank6Data[i] =
527 INI_RA(&ah->iniBank6TPC, i, modesIndex);
528 }
529 }
530
531 /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
532 if (eepMinorRev >= 2) {
533 if (IS_CHAN_2GHZ(chan)) {
534 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
535 db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
536 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
537 ob2GHz, 3, 197, 0);
538 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
539 db2GHz, 3, 194, 0);
540 } else {
541 ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
542 db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
543 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
544 ob5GHz, 3, 203, 0);
545 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
546 db5GHz, 3, 200, 0);
547 }
548 }
549
550 /* Setup Bank 7 Setup */
551 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
552
553 /* Write Analog registers */
554 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
555 regWrites);
556 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
557 regWrites);
558 REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
559 regWrites);
560 REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
561 regWrites);
562 REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
563 regWrites);
564 REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
565 regWrites);
566
567 return true;
568}
569
570static void ar5008_hw_init_bb(struct ath_hw *ah,
571 struct ath9k_channel *chan)
572{
573 u32 synthDelay;
574
575 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
576 if (IS_CHAN_B(chan))
577 synthDelay = (4 * synthDelay) / 22;
578 else
579 synthDelay /= 10;
580
581 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
582
583 udelay(synthDelay + BASE_ACTIVATE_DELAY);
584}
585
586static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
587{
588 int rx_chainmask, tx_chainmask;
589
590 rx_chainmask = ah->rxchainmask;
591 tx_chainmask = ah->txchainmask;
592
593 ENABLE_REGWRITE_BUFFER(ah);
594
595 switch (rx_chainmask) {
596 case 0x5:
597 DISABLE_REGWRITE_BUFFER(ah);
598 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
599 AR_PHY_SWAP_ALT_CHAIN);
600 ENABLE_REGWRITE_BUFFER(ah);
601 case 0x3:
602 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
603 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
604 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
605 break;
606 }
607 case 0x1:
608 case 0x2:
609 case 0x7:
610 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
611 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
612 break;
613 default:
614 break;
615 }
616
617 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
618
619 REGWRITE_BUFFER_FLUSH(ah);
620 DISABLE_REGWRITE_BUFFER(ah);
621
622 if (tx_chainmask == 0x5) {
623 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
624 AR_PHY_SWAP_ALT_CHAIN);
625 }
626 if (AR_SREV_9100(ah))
627 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
628 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
629}
630
631static void ar5008_hw_override_ini(struct ath_hw *ah,
632 struct ath9k_channel *chan)
633{
634 u32 val;
635
636 /*
637 * Set the RX_ABORT and RX_DIS and clear if off only after
638 * RXE is set for MAC. This prevents frames with corrupted
639 * descriptor status.
640 */
641 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
642
643 if (AR_SREV_9280_10_OR_LATER(ah)) {
644 val = REG_READ(ah, AR_PCU_MISC_MODE2);
645
646 if (!AR_SREV_9271(ah))
647 val &= ~AR_PCU_MISC_MODE2_HWWAR1;
648
649 if (AR_SREV_9287_10_OR_LATER(ah))
650 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
651
652 REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
653 }
654
655 if (!AR_SREV_5416_20_OR_LATER(ah) ||
656 AR_SREV_9280_10_OR_LATER(ah))
657 return;
658 /*
659 * Disable BB clock gating
660 * Necessary to avoid issues on AR5416 2.0
661 */
662 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
663
664 /*
665 * Disable RIFS search on some chips to avoid baseband
666 * hang issues.
667 */
668 if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
669 val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
670 val &= ~AR_PHY_RIFS_INIT_DELAY;
671 REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
672 }
673}
674
675static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
676 struct ath9k_channel *chan)
677{
678 u32 phymode;
679 u32 enableDacFifo = 0;
680
681 if (AR_SREV_9285_10_OR_LATER(ah))
682 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
683 AR_PHY_FC_ENABLE_DAC_FIFO);
684
685 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
686 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
687
688 if (IS_CHAN_HT40(chan)) {
689 phymode |= AR_PHY_FC_DYN2040_EN;
690
691 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
692 (chan->chanmode == CHANNEL_G_HT40PLUS))
693 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
694
695 }
696 REG_WRITE(ah, AR_PHY_TURBO, phymode);
697
698 ath9k_hw_set11nmac2040(ah);
699
700 ENABLE_REGWRITE_BUFFER(ah);
701
702 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
703 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
704
705 REGWRITE_BUFFER_FLUSH(ah);
706 DISABLE_REGWRITE_BUFFER(ah);
707}
708
709
710static int ar5008_hw_process_ini(struct ath_hw *ah,
711 struct ath9k_channel *chan)
712{
713 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
714 int i, regWrites = 0;
715 struct ieee80211_channel *channel = chan->chan;
716 u32 modesIndex, freqIndex;
717
718 switch (chan->chanmode) {
719 case CHANNEL_A:
720 case CHANNEL_A_HT20:
721 modesIndex = 1;
722 freqIndex = 1;
723 break;
724 case CHANNEL_A_HT40PLUS:
725 case CHANNEL_A_HT40MINUS:
726 modesIndex = 2;
727 freqIndex = 1;
728 break;
729 case CHANNEL_G:
730 case CHANNEL_G_HT20:
731 case CHANNEL_B:
732 modesIndex = 4;
733 freqIndex = 2;
734 break;
735 case CHANNEL_G_HT40PLUS:
736 case CHANNEL_G_HT40MINUS:
737 modesIndex = 3;
738 freqIndex = 2;
739 break;
740
741 default:
742 return -EINVAL;
743 }
744
745 if (AR_SREV_9287_12_OR_LATER(ah)) {
746 /* Enable ASYNC FIFO */
747 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
748 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
749 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
750 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
751 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
752 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
753 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
754 }
755
756 /*
757 * Set correct baseband to analog shift setting to
758 * access analog chips.
759 */
760 REG_WRITE(ah, AR_PHY(0), 0x00000007);
761
762 /* Write ADDAC shifts */
763 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
764 ah->eep_ops->set_addac(ah, chan);
765
766 if (AR_SREV_5416_22_OR_LATER(ah)) {
767 REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
768 } else {
769 struct ar5416IniArray temp;
770 u32 addacSize =
771 sizeof(u32) * ah->iniAddac.ia_rows *
772 ah->iniAddac.ia_columns;
773
774 /* For AR5416 2.0/2.1 */
775 memcpy(ah->addac5416_21,
776 ah->iniAddac.ia_array, addacSize);
777
778 /* override CLKDRV value at [row, column] = [31, 1] */
779 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
780
781 temp.ia_array = ah->addac5416_21;
782 temp.ia_columns = ah->iniAddac.ia_columns;
783 temp.ia_rows = ah->iniAddac.ia_rows;
784 REG_WRITE_ARRAY(&temp, 1, regWrites);
785 }
786
787 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
788
789 ENABLE_REGWRITE_BUFFER(ah);
790
791 for (i = 0; i < ah->iniModes.ia_rows; i++) {
792 u32 reg = INI_RA(&ah->iniModes, i, 0);
793 u32 val = INI_RA(&ah->iniModes, i, modesIndex);
794
795 if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
796 val &= ~AR_AN_TOP2_PWDCLKIND;
797
798 REG_WRITE(ah, reg, val);
799
800 if (reg >= 0x7800 && reg < 0x78a0
801 && ah->config.analog_shiftreg) {
802 udelay(100);
803 }
804
805 DO_DELAY(regWrites);
806 }
807
808 REGWRITE_BUFFER_FLUSH(ah);
809 DISABLE_REGWRITE_BUFFER(ah);
810
811 if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
812 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
813
814 if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
815 AR_SREV_9287_10_OR_LATER(ah))
816 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
817
818 if (AR_SREV_9271_10(ah))
819 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
820 modesIndex, regWrites);
821
822 ENABLE_REGWRITE_BUFFER(ah);
823
824 /* Write common array parameters */
825 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
826 u32 reg = INI_RA(&ah->iniCommon, i, 0);
827 u32 val = INI_RA(&ah->iniCommon, i, 1);
828
829 REG_WRITE(ah, reg, val);
830
831 if (reg >= 0x7800 && reg < 0x78a0
832 && ah->config.analog_shiftreg) {
833 udelay(100);
834 }
835
836 DO_DELAY(regWrites);
837 }
838
839 REGWRITE_BUFFER_FLUSH(ah);
840 DISABLE_REGWRITE_BUFFER(ah);
841
842 if (AR_SREV_9271(ah)) {
843 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
844 REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
845 modesIndex, regWrites);
846 else
847 REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
848 modesIndex, regWrites);
849 }
850
851 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
852
853 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) {
854 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
855 regWrites);
856 }
857
858 ar5008_hw_override_ini(ah, chan);
859 ar5008_hw_set_channel_regs(ah, chan);
860 ar5008_hw_init_chain_masks(ah);
861 ath9k_olc_init(ah);
862
863 /* Set TX power */
864 ah->eep_ops->set_txpower(ah, chan,
865 ath9k_regd_get_ctl(regulatory, chan),
866 channel->max_antenna_gain * 2,
867 channel->max_power * 2,
868 min((u32) MAX_RATE_POWER,
869 (u32) regulatory->power_limit));
870
871 /* Write analog registers */
872 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
873 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
874 "ar5416SetRfRegs failed\n");
875 return -EIO;
876 }
877
878 return 0;
879}
880
881static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
882{
883 u32 rfMode = 0;
884
885 if (chan == NULL)
886 return;
887
888 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
889 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
890
891 if (!AR_SREV_9280_10_OR_LATER(ah))
892 rfMode |= (IS_CHAN_5GHZ(chan)) ?
893 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
894
895 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
896 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
897
898 REG_WRITE(ah, AR_PHY_MODE, rfMode);
899}
900
901static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah)
902{
903 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
904}
905
906static void ar5008_hw_set_delta_slope(struct ath_hw *ah,
907 struct ath9k_channel *chan)
908{
909 u32 coef_scaled, ds_coef_exp, ds_coef_man;
910 u32 clockMhzScaled = 0x64000000;
911 struct chan_centers centers;
912
913 if (IS_CHAN_HALF_RATE(chan))
914 clockMhzScaled = clockMhzScaled >> 1;
915 else if (IS_CHAN_QUARTER_RATE(chan))
916 clockMhzScaled = clockMhzScaled >> 2;
917
918 ath9k_hw_get_channel_centers(ah, chan, &centers);
919 coef_scaled = clockMhzScaled / centers.synth_center;
920
921 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
922 &ds_coef_exp);
923
924 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
925 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
926 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
927 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
928
929 coef_scaled = (9 * coef_scaled) / 10;
930
931 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
932 &ds_coef_exp);
933
934 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
935 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
936 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
937 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
938}
939
940static bool ar5008_hw_rfbus_req(struct ath_hw *ah)
941{
942 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
943 return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
944 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
945}
946
947static void ar5008_hw_rfbus_done(struct ath_hw *ah)
948{
949 u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
950 if (IS_CHAN_B(ah->curchan))
951 synthDelay = (4 * synthDelay) / 22;
952 else
953 synthDelay /= 10;
954
955 udelay(synthDelay + BASE_ACTIVATE_DELAY);
956
957 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
958}
959
960static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
961{
962 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
963 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
964
965 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
966 AR_GPIO_INPUT_MUX2_RFSILENT);
967
968 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
969 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
970}
971
972static void ar5008_restore_chainmask(struct ath_hw *ah)
973{
974 int rx_chainmask = ah->rxchainmask;
975
976 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
977 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
978 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
979 }
980}
981
982static void ar5008_set_diversity(struct ath_hw *ah, bool value)
983{
984 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
985 if (value)
986 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
987 else
988 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
989 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
990}
991
992static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
993 struct ath9k_channel *chan)
994{
995 if (chan && IS_CHAN_5GHZ(chan))
996 return 0x1450;
997 return 0x1458;
998}
999
1000static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
1001 struct ath9k_channel *chan)
1002{
1003 u32 pll;
1004
1005 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1006
1007 if (chan && IS_CHAN_HALF_RATE(chan))
1008 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1009 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1010 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1011
1012 if (chan && IS_CHAN_5GHZ(chan))
1013 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1014 else
1015 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1016
1017 return pll;
1018}
1019
1020static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
1021 struct ath9k_channel *chan)
1022{
1023 u32 pll;
1024
1025 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1026
1027 if (chan && IS_CHAN_HALF_RATE(chan))
1028 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1029 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1030 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1031
1032 if (chan && IS_CHAN_5GHZ(chan))
1033 pll |= SM(0xa, AR_RTC_PLL_DIV);
1034 else
1035 pll |= SM(0xb, AR_RTC_PLL_DIV);
1036
1037 return pll;
1038}
1039
1040static bool ar5008_hw_ani_control(struct ath_hw *ah,
1041 enum ath9k_ani_cmd cmd, int param)
1042{
1043 struct ar5416AniState *aniState = ah->curani;
1044 struct ath_common *common = ath9k_hw_common(ah);
1045
1046 switch (cmd & ah->ani_function) {
1047 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
1048 u32 level = param;
1049
1050 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
1051 ath_print(common, ATH_DBG_ANI,
1052 "level out of range (%u > %u)\n",
1053 level,
1054 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
1055 return false;
1056 }
1057
1058 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1059 AR_PHY_DESIRED_SZ_TOT_DES,
1060 ah->totalSizeDesired[level]);
1061 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
1062 AR_PHY_AGC_CTL1_COARSE_LOW,
1063 ah->coarse_low[level]);
1064 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
1065 AR_PHY_AGC_CTL1_COARSE_HIGH,
1066 ah->coarse_high[level]);
1067 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1068 AR_PHY_FIND_SIG_FIRPWR,
1069 ah->firpwr[level]);
1070
1071 if (level > aniState->noiseImmunityLevel)
1072 ah->stats.ast_ani_niup++;
1073 else if (level < aniState->noiseImmunityLevel)
1074 ah->stats.ast_ani_nidown++;
1075 aniState->noiseImmunityLevel = level;
1076 break;
1077 }
1078 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
1079 const int m1ThreshLow[] = { 127, 50 };
1080 const int m2ThreshLow[] = { 127, 40 };
1081 const int m1Thresh[] = { 127, 0x4d };
1082 const int m2Thresh[] = { 127, 0x40 };
1083 const int m2CountThr[] = { 31, 16 };
1084 const int m2CountThrLow[] = { 63, 48 };
1085 u32 on = param ? 1 : 0;
1086
1087 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1088 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
1089 m1ThreshLow[on]);
1090 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1091 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
1092 m2ThreshLow[on]);
1093 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1094 AR_PHY_SFCORR_M1_THRESH,
1095 m1Thresh[on]);
1096 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1097 AR_PHY_SFCORR_M2_THRESH,
1098 m2Thresh[on]);
1099 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1100 AR_PHY_SFCORR_M2COUNT_THR,
1101 m2CountThr[on]);
1102 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1103 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
1104 m2CountThrLow[on]);
1105
1106 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1107 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
1108 m1ThreshLow[on]);
1109 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1110 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
1111 m2ThreshLow[on]);
1112 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1113 AR_PHY_SFCORR_EXT_M1_THRESH,
1114 m1Thresh[on]);
1115 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1116 AR_PHY_SFCORR_EXT_M2_THRESH,
1117 m2Thresh[on]);
1118
1119 if (on)
1120 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
1121 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1122 else
1123 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
1124 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1125
1126 if (!on != aniState->ofdmWeakSigDetectOff) {
1127 if (on)
1128 ah->stats.ast_ani_ofdmon++;
1129 else
1130 ah->stats.ast_ani_ofdmoff++;
1131 aniState->ofdmWeakSigDetectOff = !on;
1132 }
1133 break;
1134 }
1135 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
1136 const int weakSigThrCck[] = { 8, 6 };
1137 u32 high = param ? 1 : 0;
1138
1139 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
1140 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
1141 weakSigThrCck[high]);
1142 if (high != aniState->cckWeakSigThreshold) {
1143 if (high)
1144 ah->stats.ast_ani_cckhigh++;
1145 else
1146 ah->stats.ast_ani_ccklow++;
1147 aniState->cckWeakSigThreshold = high;
1148 }
1149 break;
1150 }
1151 case ATH9K_ANI_FIRSTEP_LEVEL:{
1152 const int firstep[] = { 0, 4, 8 };
1153 u32 level = param;
1154
1155 if (level >= ARRAY_SIZE(firstep)) {
1156 ath_print(common, ATH_DBG_ANI,
1157 "level out of range (%u > %u)\n",
1158 level,
1159 (unsigned) ARRAY_SIZE(firstep));
1160 return false;
1161 }
1162 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1163 AR_PHY_FIND_SIG_FIRSTEP,
1164 firstep[level]);
1165 if (level > aniState->firstepLevel)
1166 ah->stats.ast_ani_stepup++;
1167 else if (level < aniState->firstepLevel)
1168 ah->stats.ast_ani_stepdown++;
1169 aniState->firstepLevel = level;
1170 break;
1171 }
1172 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
1173 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
1174 u32 level = param;
1175
1176 if (level >= ARRAY_SIZE(cycpwrThr1)) {
1177 ath_print(common, ATH_DBG_ANI,
1178 "level out of range (%u > %u)\n",
1179 level,
1180 (unsigned) ARRAY_SIZE(cycpwrThr1));
1181 return false;
1182 }
1183 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
1184 AR_PHY_TIMING5_CYCPWR_THR1,
1185 cycpwrThr1[level]);
1186 if (level > aniState->spurImmunityLevel)
1187 ah->stats.ast_ani_spurup++;
1188 else if (level < aniState->spurImmunityLevel)
1189 ah->stats.ast_ani_spurdown++;
1190 aniState->spurImmunityLevel = level;
1191 break;
1192 }
1193 case ATH9K_ANI_PRESENT:
1194 break;
1195 default:
1196 ath_print(common, ATH_DBG_ANI,
1197 "invalid cmd %u\n", cmd);
1198 return false;
1199 }
1200
1201 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
1202 ath_print(common, ATH_DBG_ANI,
1203 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
1204 "ofdmWeakSigDetectOff=%d\n",
1205 aniState->noiseImmunityLevel,
1206 aniState->spurImmunityLevel,
1207 !aniState->ofdmWeakSigDetectOff);
1208 ath_print(common, ATH_DBG_ANI,
1209 "cckWeakSigThreshold=%d, "
1210 "firstepLevel=%d, listenTime=%d\n",
1211 aniState->cckWeakSigThreshold,
1212 aniState->firstepLevel,
1213 aniState->listenTime);
1214 ath_print(common, ATH_DBG_ANI,
1215 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
1216 aniState->cycleCount,
1217 aniState->ofdmPhyErrCount,
1218 aniState->cckPhyErrCount);
1219
1220 return true;
1221}
1222
1223static void ar5008_hw_do_getnf(struct ath_hw *ah,
1224 int16_t nfarray[NUM_NF_READINGS])
1225{
1226 struct ath_common *common = ath9k_hw_common(ah);
1227 int16_t nf;
1228
1229 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1230 if (nf & 0x100)
1231 nf = 0 - ((nf ^ 0x1ff) + 1);
1232 ath_print(common, ATH_DBG_CALIBRATE,
1233 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1234 nfarray[0] = nf;
1235
1236 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
1237 if (nf & 0x100)
1238 nf = 0 - ((nf ^ 0x1ff) + 1);
1239 ath_print(common, ATH_DBG_CALIBRATE,
1240 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1241 nfarray[1] = nf;
1242
1243 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
1244 if (nf & 0x100)
1245 nf = 0 - ((nf ^ 0x1ff) + 1);
1246 ath_print(common, ATH_DBG_CALIBRATE,
1247 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1248 nfarray[2] = nf;
1249
1250 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
1251 if (nf & 0x100)
1252 nf = 0 - ((nf ^ 0x1ff) + 1);
1253 ath_print(common, ATH_DBG_CALIBRATE,
1254 "NF calibrated [ext] [chain 0] is %d\n", nf);
1255 nfarray[3] = nf;
1256
1257 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
1258 if (nf & 0x100)
1259 nf = 0 - ((nf ^ 0x1ff) + 1);
1260 ath_print(common, ATH_DBG_CALIBRATE,
1261 "NF calibrated [ext] [chain 1] is %d\n", nf);
1262 nfarray[4] = nf;
1263
1264 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
1265 if (nf & 0x100)
1266 nf = 0 - ((nf ^ 0x1ff) + 1);
1267 ath_print(common, ATH_DBG_CALIBRATE,
1268 "NF calibrated [ext] [chain 2] is %d\n", nf);
1269 nfarray[5] = nf;
1270}
1271
1272static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1273{
1274 struct ath9k_nfcal_hist *h;
1275 int i, j;
1276 int32_t val;
1277 const u32 ar5416_cca_regs[6] = {
1278 AR_PHY_CCA,
1279 AR_PHY_CH1_CCA,
1280 AR_PHY_CH2_CCA,
1281 AR_PHY_EXT_CCA,
1282 AR_PHY_CH1_EXT_CCA,
1283 AR_PHY_CH2_EXT_CCA
1284 };
1285 u8 chainmask, rx_chain_status;
1286
1287 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
1288 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
1289 chainmask = 0x9;
1290 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
1291 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
1292 chainmask = 0x1B;
1293 else
1294 chainmask = 0x09;
1295 } else {
1296 if (rx_chain_status & 0x4)
1297 chainmask = 0x3F;
1298 else if (rx_chain_status & 0x2)
1299 chainmask = 0x1B;
1300 else
1301 chainmask = 0x09;
1302 }
1303
1304 h = ah->nfCalHist;
1305
1306 for (i = 0; i < NUM_NF_READINGS; i++) {
1307 if (chainmask & (1 << i)) {
1308 val = REG_READ(ah, ar5416_cca_regs[i]);
1309 val &= 0xFFFFFE00;
1310 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1311 REG_WRITE(ah, ar5416_cca_regs[i], val);
1312 }
1313 }
1314
1315 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1316 AR_PHY_AGC_CONTROL_ENABLE_NF);
1317 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1318 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1319 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1320
1321 for (j = 0; j < 5; j++) {
1322 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1323 AR_PHY_AGC_CONTROL_NF) == 0)
1324 break;
1325 udelay(50);
1326 }
1327
1328 ENABLE_REGWRITE_BUFFER(ah);
1329
1330 for (i = 0; i < NUM_NF_READINGS; i++) {
1331 if (chainmask & (1 << i)) {
1332 val = REG_READ(ah, ar5416_cca_regs[i]);
1333 val &= 0xFFFFFE00;
1334 val |= (((u32) (-50) << 1) & 0x1ff);
1335 REG_WRITE(ah, ar5416_cca_regs[i], val);
1336 }
1337 }
1338
1339 REGWRITE_BUFFER_FLUSH(ah);
1340 DISABLE_REGWRITE_BUFFER(ah);
1341}
1342
1343void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1344{
1345 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1346
1347 priv_ops->rf_set_freq = ar5008_hw_set_channel;
1348 priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
1349
1350 priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks;
1351 priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks;
1352 priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;
1353 priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;
1354 priv_ops->init_bb = ar5008_hw_init_bb;
1355 priv_ops->process_ini = ar5008_hw_process_ini;
1356 priv_ops->set_rfmode = ar5008_hw_set_rfmode;
1357 priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive;
1358 priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
1359 priv_ops->rfbus_req = ar5008_hw_rfbus_req;
1360 priv_ops->rfbus_done = ar5008_hw_rfbus_done;
1361 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
1362 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1363 priv_ops->set_diversity = ar5008_set_diversity;
1364 priv_ops->ani_control = ar5008_hw_ani_control;
1365 priv_ops->do_getnf = ar5008_hw_do_getnf;
1366 priv_ops->loadnf = ar5008_hw_loadnf;
1367
1368 if (AR_SREV_9100(ah))
1369 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
1370 else if (AR_SREV_9160_10_OR_LATER(ah))
1371 priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
1372 else
1373 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
1374}
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
new file mode 100644
index 000000000000..0b94bd385b0a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
@@ -0,0 +1,1254 @@
1
2static const u32 ar5416Common_9100[][2] = {
3 { 0x0000000c, 0x00000000 },
4 { 0x00000030, 0x00020015 },
5 { 0x00000034, 0x00000005 },
6 { 0x00000040, 0x00000000 },
7 { 0x00000044, 0x00000008 },
8 { 0x00000048, 0x00000008 },
9 { 0x0000004c, 0x00000010 },
10 { 0x00000050, 0x00000000 },
11 { 0x00000054, 0x0000001f },
12 { 0x00000800, 0x00000000 },
13 { 0x00000804, 0x00000000 },
14 { 0x00000808, 0x00000000 },
15 { 0x0000080c, 0x00000000 },
16 { 0x00000810, 0x00000000 },
17 { 0x00000814, 0x00000000 },
18 { 0x00000818, 0x00000000 },
19 { 0x0000081c, 0x00000000 },
20 { 0x00000820, 0x00000000 },
21 { 0x00000824, 0x00000000 },
22 { 0x00001040, 0x002ffc0f },
23 { 0x00001044, 0x002ffc0f },
24 { 0x00001048, 0x002ffc0f },
25 { 0x0000104c, 0x002ffc0f },
26 { 0x00001050, 0x002ffc0f },
27 { 0x00001054, 0x002ffc0f },
28 { 0x00001058, 0x002ffc0f },
29 { 0x0000105c, 0x002ffc0f },
30 { 0x00001060, 0x002ffc0f },
31 { 0x00001064, 0x002ffc0f },
32 { 0x00001230, 0x00000000 },
33 { 0x00001270, 0x00000000 },
34 { 0x00001038, 0x00000000 },
35 { 0x00001078, 0x00000000 },
36 { 0x000010b8, 0x00000000 },
37 { 0x000010f8, 0x00000000 },
38 { 0x00001138, 0x00000000 },
39 { 0x00001178, 0x00000000 },
40 { 0x000011b8, 0x00000000 },
41 { 0x000011f8, 0x00000000 },
42 { 0x00001238, 0x00000000 },
43 { 0x00001278, 0x00000000 },
44 { 0x000012b8, 0x00000000 },
45 { 0x000012f8, 0x00000000 },
46 { 0x00001338, 0x00000000 },
47 { 0x00001378, 0x00000000 },
48 { 0x000013b8, 0x00000000 },
49 { 0x000013f8, 0x00000000 },
50 { 0x00001438, 0x00000000 },
51 { 0x00001478, 0x00000000 },
52 { 0x000014b8, 0x00000000 },
53 { 0x000014f8, 0x00000000 },
54 { 0x00001538, 0x00000000 },
55 { 0x00001578, 0x00000000 },
56 { 0x000015b8, 0x00000000 },
57 { 0x000015f8, 0x00000000 },
58 { 0x00001638, 0x00000000 },
59 { 0x00001678, 0x00000000 },
60 { 0x000016b8, 0x00000000 },
61 { 0x000016f8, 0x00000000 },
62 { 0x00001738, 0x00000000 },
63 { 0x00001778, 0x00000000 },
64 { 0x000017b8, 0x00000000 },
65 { 0x000017f8, 0x00000000 },
66 { 0x0000103c, 0x00000000 },
67 { 0x0000107c, 0x00000000 },
68 { 0x000010bc, 0x00000000 },
69 { 0x000010fc, 0x00000000 },
70 { 0x0000113c, 0x00000000 },
71 { 0x0000117c, 0x00000000 },
72 { 0x000011bc, 0x00000000 },
73 { 0x000011fc, 0x00000000 },
74 { 0x0000123c, 0x00000000 },
75 { 0x0000127c, 0x00000000 },
76 { 0x000012bc, 0x00000000 },
77 { 0x000012fc, 0x00000000 },
78 { 0x0000133c, 0x00000000 },
79 { 0x0000137c, 0x00000000 },
80 { 0x000013bc, 0x00000000 },
81 { 0x000013fc, 0x00000000 },
82 { 0x0000143c, 0x00000000 },
83 { 0x0000147c, 0x00000000 },
84 { 0x00020010, 0x00000003 },
85 { 0x00020038, 0x000004c2 },
86 { 0x00008004, 0x00000000 },
87 { 0x00008008, 0x00000000 },
88 { 0x0000800c, 0x00000000 },
89 { 0x00008018, 0x00000700 },
90 { 0x00008020, 0x00000000 },
91 { 0x00008038, 0x00000000 },
92 { 0x0000803c, 0x00000000 },
93 { 0x00008048, 0x40000000 },
94 { 0x00008054, 0x00004000 },
95 { 0x00008058, 0x00000000 },
96 { 0x0000805c, 0x000fc78f },
97 { 0x00008060, 0x0000000f },
98 { 0x00008064, 0x00000000 },
99 { 0x000080c0, 0x2a82301a },
100 { 0x000080c4, 0x05dc01e0 },
101 { 0x000080c8, 0x1f402710 },
102 { 0x000080cc, 0x01f40000 },
103 { 0x000080d0, 0x00001e00 },
104 { 0x000080d4, 0x00000000 },
105 { 0x000080d8, 0x00400000 },
106 { 0x000080e0, 0xffffffff },
107 { 0x000080e4, 0x0000ffff },
108 { 0x000080e8, 0x003f3f3f },
109 { 0x000080ec, 0x00000000 },
110 { 0x000080f0, 0x00000000 },
111 { 0x000080f4, 0x00000000 },
112 { 0x000080f8, 0x00000000 },
113 { 0x000080fc, 0x00020000 },
114 { 0x00008100, 0x00020000 },
115 { 0x00008104, 0x00000001 },
116 { 0x00008108, 0x00000052 },
117 { 0x0000810c, 0x00000000 },
118 { 0x00008110, 0x00000168 },
119 { 0x00008118, 0x000100aa },
120 { 0x0000811c, 0x00003210 },
121 { 0x00008120, 0x08f04800 },
122 { 0x00008124, 0x00000000 },
123 { 0x00008128, 0x00000000 },
124 { 0x0000812c, 0x00000000 },
125 { 0x00008130, 0x00000000 },
126 { 0x00008134, 0x00000000 },
127 { 0x00008138, 0x00000000 },
128 { 0x0000813c, 0x00000000 },
129 { 0x00008144, 0x00000000 },
130 { 0x00008168, 0x00000000 },
131 { 0x0000816c, 0x00000000 },
132 { 0x00008170, 0x32143320 },
133 { 0x00008174, 0xfaa4fa50 },
134 { 0x00008178, 0x00000100 },
135 { 0x0000817c, 0x00000000 },
136 { 0x000081c4, 0x00000000 },
137 { 0x000081d0, 0x00003210 },
138 { 0x000081ec, 0x00000000 },
139 { 0x000081f0, 0x00000000 },
140 { 0x000081f4, 0x00000000 },
141 { 0x000081f8, 0x00000000 },
142 { 0x000081fc, 0x00000000 },
143 { 0x00008200, 0x00000000 },
144 { 0x00008204, 0x00000000 },
145 { 0x00008208, 0x00000000 },
146 { 0x0000820c, 0x00000000 },
147 { 0x00008210, 0x00000000 },
148 { 0x00008214, 0x00000000 },
149 { 0x00008218, 0x00000000 },
150 { 0x0000821c, 0x00000000 },
151 { 0x00008220, 0x00000000 },
152 { 0x00008224, 0x00000000 },
153 { 0x00008228, 0x00000000 },
154 { 0x0000822c, 0x00000000 },
155 { 0x00008230, 0x00000000 },
156 { 0x00008234, 0x00000000 },
157 { 0x00008238, 0x00000000 },
158 { 0x0000823c, 0x00000000 },
159 { 0x00008240, 0x00100000 },
160 { 0x00008244, 0x0010f400 },
161 { 0x00008248, 0x00000100 },
162 { 0x0000824c, 0x0001e800 },
163 { 0x00008250, 0x00000000 },
164 { 0x00008254, 0x00000000 },
165 { 0x00008258, 0x00000000 },
166 { 0x0000825c, 0x400000ff },
167 { 0x00008260, 0x00080922 },
168 { 0x00008270, 0x00000000 },
169 { 0x00008274, 0x40000000 },
170 { 0x00008278, 0x003e4180 },
171 { 0x0000827c, 0x00000000 },
172 { 0x00008284, 0x0000002c },
173 { 0x00008288, 0x0000002c },
174 { 0x0000828c, 0x00000000 },
175 { 0x00008294, 0x00000000 },
176 { 0x00008298, 0x00000000 },
177 { 0x00008300, 0x00000000 },
178 { 0x00008304, 0x00000000 },
179 { 0x00008308, 0x00000000 },
180 { 0x0000830c, 0x00000000 },
181 { 0x00008310, 0x00000000 },
182 { 0x00008314, 0x00000000 },
183 { 0x00008318, 0x00000000 },
184 { 0x00008328, 0x00000000 },
185 { 0x0000832c, 0x00000007 },
186 { 0x00008330, 0x00000302 },
187 { 0x00008334, 0x00000e00 },
188 { 0x00008338, 0x00000000 },
189 { 0x0000833c, 0x00000000 },
190 { 0x00008340, 0x000107ff },
191 { 0x00009808, 0x00000000 },
192 { 0x0000980c, 0xad848e19 },
193 { 0x00009810, 0x7d14e000 },
194 { 0x00009814, 0x9c0a9f6b },
195 { 0x0000981c, 0x00000000 },
196 { 0x0000982c, 0x0000a000 },
197 { 0x00009830, 0x00000000 },
198 { 0x0000983c, 0x00200400 },
199 { 0x00009840, 0x206a01ae },
200 { 0x0000984c, 0x1284233c },
201 { 0x00009854, 0x00000859 },
202 { 0x00009900, 0x00000000 },
203 { 0x00009904, 0x00000000 },
204 { 0x00009908, 0x00000000 },
205 { 0x0000990c, 0x00000000 },
206 { 0x0000991c, 0x10000fff },
207 { 0x00009920, 0x05100000 },
208 { 0x0000a920, 0x05100000 },
209 { 0x0000b920, 0x05100000 },
210 { 0x00009928, 0x00000001 },
211 { 0x0000992c, 0x00000004 },
212 { 0x00009934, 0x1e1f2022 },
213 { 0x00009938, 0x0a0b0c0d },
214 { 0x0000993c, 0x00000000 },
215 { 0x00009948, 0x9280b212 },
216 { 0x0000994c, 0x00020028 },
217 { 0x0000c95c, 0x004b6a8e },
218 { 0x0000c968, 0x000003ce },
219 { 0x00009970, 0x190fb515 },
220 { 0x00009974, 0x00000000 },
221 { 0x00009978, 0x00000001 },
222 { 0x0000997c, 0x00000000 },
223 { 0x00009980, 0x00000000 },
224 { 0x00009984, 0x00000000 },
225 { 0x00009988, 0x00000000 },
226 { 0x0000998c, 0x00000000 },
227 { 0x00009990, 0x00000000 },
228 { 0x00009994, 0x00000000 },
229 { 0x00009998, 0x00000000 },
230 { 0x0000999c, 0x00000000 },
231 { 0x000099a0, 0x00000000 },
232 { 0x000099a4, 0x00000001 },
233 { 0x000099a8, 0x201fff00 },
234 { 0x000099ac, 0x006f0000 },
235 { 0x000099b0, 0x03051000 },
236 { 0x000099dc, 0x00000000 },
237 { 0x000099e0, 0x00000200 },
238 { 0x000099e4, 0xaaaaaaaa },
239 { 0x000099e8, 0x3c466478 },
240 { 0x000099ec, 0x0cc80caa },
241 { 0x000099fc, 0x00001042 },
242 { 0x00009b00, 0x00000000 },
243 { 0x00009b04, 0x00000001 },
244 { 0x00009b08, 0x00000002 },
245 { 0x00009b0c, 0x00000003 },
246 { 0x00009b10, 0x00000004 },
247 { 0x00009b14, 0x00000005 },
248 { 0x00009b18, 0x00000008 },
249 { 0x00009b1c, 0x00000009 },
250 { 0x00009b20, 0x0000000a },
251 { 0x00009b24, 0x0000000b },
252 { 0x00009b28, 0x0000000c },
253 { 0x00009b2c, 0x0000000d },
254 { 0x00009b30, 0x00000010 },
255 { 0x00009b34, 0x00000011 },
256 { 0x00009b38, 0x00000012 },
257 { 0x00009b3c, 0x00000013 },
258 { 0x00009b40, 0x00000014 },
259 { 0x00009b44, 0x00000015 },
260 { 0x00009b48, 0x00000018 },
261 { 0x00009b4c, 0x00000019 },
262 { 0x00009b50, 0x0000001a },
263 { 0x00009b54, 0x0000001b },
264 { 0x00009b58, 0x0000001c },
265 { 0x00009b5c, 0x0000001d },
266 { 0x00009b60, 0x00000020 },
267 { 0x00009b64, 0x00000021 },
268 { 0x00009b68, 0x00000022 },
269 { 0x00009b6c, 0x00000023 },
270 { 0x00009b70, 0x00000024 },
271 { 0x00009b74, 0x00000025 },
272 { 0x00009b78, 0x00000028 },
273 { 0x00009b7c, 0x00000029 },
274 { 0x00009b80, 0x0000002a },
275 { 0x00009b84, 0x0000002b },
276 { 0x00009b88, 0x0000002c },
277 { 0x00009b8c, 0x0000002d },
278 { 0x00009b90, 0x00000030 },
279 { 0x00009b94, 0x00000031 },
280 { 0x00009b98, 0x00000032 },
281 { 0x00009b9c, 0x00000033 },
282 { 0x00009ba0, 0x00000034 },
283 { 0x00009ba4, 0x00000035 },
284 { 0x00009ba8, 0x00000035 },
285 { 0x00009bac, 0x00000035 },
286 { 0x00009bb0, 0x00000035 },
287 { 0x00009bb4, 0x00000035 },
288 { 0x00009bb8, 0x00000035 },
289 { 0x00009bbc, 0x00000035 },
290 { 0x00009bc0, 0x00000035 },
291 { 0x00009bc4, 0x00000035 },
292 { 0x00009bc8, 0x00000035 },
293 { 0x00009bcc, 0x00000035 },
294 { 0x00009bd0, 0x00000035 },
295 { 0x00009bd4, 0x00000035 },
296 { 0x00009bd8, 0x00000035 },
297 { 0x00009bdc, 0x00000035 },
298 { 0x00009be0, 0x00000035 },
299 { 0x00009be4, 0x00000035 },
300 { 0x00009be8, 0x00000035 },
301 { 0x00009bec, 0x00000035 },
302 { 0x00009bf0, 0x00000035 },
303 { 0x00009bf4, 0x00000035 },
304 { 0x00009bf8, 0x00000010 },
305 { 0x00009bfc, 0x0000001a },
306 { 0x0000a210, 0x40806333 },
307 { 0x0000a214, 0x00106c10 },
308 { 0x0000a218, 0x009c4060 },
309 { 0x0000a220, 0x018830c6 },
310 { 0x0000a224, 0x00000400 },
311 { 0x0000a228, 0x001a0bb5 },
312 { 0x0000a22c, 0x00000000 },
313 { 0x0000a234, 0x20202020 },
314 { 0x0000a238, 0x20202020 },
315 { 0x0000a23c, 0x13c889ae },
316 { 0x0000a240, 0x38490a20 },
317 { 0x0000a244, 0x00007bb6 },
318 { 0x0000a248, 0x0fff3ffc },
319 { 0x0000a24c, 0x00000001 },
320 { 0x0000a250, 0x0000a000 },
321 { 0x0000a254, 0x00000000 },
322 { 0x0000a258, 0x0cc75380 },
323 { 0x0000a25c, 0x0f0f0f01 },
324 { 0x0000a260, 0xdfa91f01 },
325 { 0x0000a268, 0x00000001 },
326 { 0x0000a26c, 0x0ebae9c6 },
327 { 0x0000b26c, 0x0ebae9c6 },
328 { 0x0000c26c, 0x0ebae9c6 },
329 { 0x0000d270, 0x00820820 },
330 { 0x0000a278, 0x1ce739ce },
331 { 0x0000a27c, 0x050701ce },
332 { 0x0000a338, 0x00000000 },
333 { 0x0000a33c, 0x00000000 },
334 { 0x0000a340, 0x00000000 },
335 { 0x0000a344, 0x00000000 },
336 { 0x0000a348, 0x3fffffff },
337 { 0x0000a34c, 0x3fffffff },
338 { 0x0000a350, 0x3fffffff },
339 { 0x0000a354, 0x0003ffff },
340 { 0x0000a358, 0x79a8aa33 },
341 { 0x0000d35c, 0x07ffffef },
342 { 0x0000d360, 0x0fffffe7 },
343 { 0x0000d364, 0x17ffffe5 },
344 { 0x0000d368, 0x1fffffe4 },
345 { 0x0000d36c, 0x37ffffe3 },
346 { 0x0000d370, 0x3fffffe3 },
347 { 0x0000d374, 0x57ffffe3 },
348 { 0x0000d378, 0x5fffffe2 },
349 { 0x0000d37c, 0x7fffffe2 },
350 { 0x0000d380, 0x7f3c7bba },
351 { 0x0000d384, 0xf3307ff0 },
352 { 0x0000a388, 0x0c000000 },
353 { 0x0000a38c, 0x20202020 },
354 { 0x0000a390, 0x20202020 },
355 { 0x0000a394, 0x1ce739ce },
356 { 0x0000a398, 0x000001ce },
357 { 0x0000a39c, 0x00000001 },
358 { 0x0000a3a0, 0x00000000 },
359 { 0x0000a3a4, 0x00000000 },
360 { 0x0000a3a8, 0x00000000 },
361 { 0x0000a3ac, 0x00000000 },
362 { 0x0000a3b0, 0x00000000 },
363 { 0x0000a3b4, 0x00000000 },
364 { 0x0000a3b8, 0x00000000 },
365 { 0x0000a3bc, 0x00000000 },
366 { 0x0000a3c0, 0x00000000 },
367 { 0x0000a3c4, 0x00000000 },
368 { 0x0000a3c8, 0x00000246 },
369 { 0x0000a3cc, 0x20202020 },
370 { 0x0000a3d0, 0x20202020 },
371 { 0x0000a3d4, 0x20202020 },
372 { 0x0000a3dc, 0x1ce739ce },
373 { 0x0000a3e0, 0x000001ce },
374};
375
376static const u32 ar5416Bank0_9100[][2] = {
377 { 0x000098b0, 0x1e5795e5 },
378 { 0x000098e0, 0x02008020 },
379};
380
381static const u32 ar5416BB_RfGain_9100[][3] = {
382 { 0x00009a00, 0x00000000, 0x00000000 },
383 { 0x00009a04, 0x00000040, 0x00000040 },
384 { 0x00009a08, 0x00000080, 0x00000080 },
385 { 0x00009a0c, 0x000001a1, 0x00000141 },
386 { 0x00009a10, 0x000001e1, 0x00000181 },
387 { 0x00009a14, 0x00000021, 0x000001c1 },
388 { 0x00009a18, 0x00000061, 0x00000001 },
389 { 0x00009a1c, 0x00000168, 0x00000041 },
390 { 0x00009a20, 0x000001a8, 0x000001a8 },
391 { 0x00009a24, 0x000001e8, 0x000001e8 },
392 { 0x00009a28, 0x00000028, 0x00000028 },
393 { 0x00009a2c, 0x00000068, 0x00000068 },
394 { 0x00009a30, 0x00000189, 0x000000a8 },
395 { 0x00009a34, 0x000001c9, 0x00000169 },
396 { 0x00009a38, 0x00000009, 0x000001a9 },
397 { 0x00009a3c, 0x00000049, 0x000001e9 },
398 { 0x00009a40, 0x00000089, 0x00000029 },
399 { 0x00009a44, 0x00000170, 0x00000069 },
400 { 0x00009a48, 0x000001b0, 0x00000190 },
401 { 0x00009a4c, 0x000001f0, 0x000001d0 },
402 { 0x00009a50, 0x00000030, 0x00000010 },
403 { 0x00009a54, 0x00000070, 0x00000050 },
404 { 0x00009a58, 0x00000191, 0x00000090 },
405 { 0x00009a5c, 0x000001d1, 0x00000151 },
406 { 0x00009a60, 0x00000011, 0x00000191 },
407 { 0x00009a64, 0x00000051, 0x000001d1 },
408 { 0x00009a68, 0x00000091, 0x00000011 },
409 { 0x00009a6c, 0x000001b8, 0x00000051 },
410 { 0x00009a70, 0x000001f8, 0x00000198 },
411 { 0x00009a74, 0x00000038, 0x000001d8 },
412 { 0x00009a78, 0x00000078, 0x00000018 },
413 { 0x00009a7c, 0x00000199, 0x00000058 },
414 { 0x00009a80, 0x000001d9, 0x00000098 },
415 { 0x00009a84, 0x00000019, 0x00000159 },
416 { 0x00009a88, 0x00000059, 0x00000199 },
417 { 0x00009a8c, 0x00000099, 0x000001d9 },
418 { 0x00009a90, 0x000000d9, 0x00000019 },
419 { 0x00009a94, 0x000000f9, 0x00000059 },
420 { 0x00009a98, 0x000000f9, 0x00000099 },
421 { 0x00009a9c, 0x000000f9, 0x000000d9 },
422 { 0x00009aa0, 0x000000f9, 0x000000f9 },
423 { 0x00009aa4, 0x000000f9, 0x000000f9 },
424 { 0x00009aa8, 0x000000f9, 0x000000f9 },
425 { 0x00009aac, 0x000000f9, 0x000000f9 },
426 { 0x00009ab0, 0x000000f9, 0x000000f9 },
427 { 0x00009ab4, 0x000000f9, 0x000000f9 },
428 { 0x00009ab8, 0x000000f9, 0x000000f9 },
429 { 0x00009abc, 0x000000f9, 0x000000f9 },
430 { 0x00009ac0, 0x000000f9, 0x000000f9 },
431 { 0x00009ac4, 0x000000f9, 0x000000f9 },
432 { 0x00009ac8, 0x000000f9, 0x000000f9 },
433 { 0x00009acc, 0x000000f9, 0x000000f9 },
434 { 0x00009ad0, 0x000000f9, 0x000000f9 },
435 { 0x00009ad4, 0x000000f9, 0x000000f9 },
436 { 0x00009ad8, 0x000000f9, 0x000000f9 },
437 { 0x00009adc, 0x000000f9, 0x000000f9 },
438 { 0x00009ae0, 0x000000f9, 0x000000f9 },
439 { 0x00009ae4, 0x000000f9, 0x000000f9 },
440 { 0x00009ae8, 0x000000f9, 0x000000f9 },
441 { 0x00009aec, 0x000000f9, 0x000000f9 },
442 { 0x00009af0, 0x000000f9, 0x000000f9 },
443 { 0x00009af4, 0x000000f9, 0x000000f9 },
444 { 0x00009af8, 0x000000f9, 0x000000f9 },
445 { 0x00009afc, 0x000000f9, 0x000000f9 },
446};
447
448static const u32 ar5416Bank1_9100[][2] = {
449 { 0x000098b0, 0x02108421},
450 { 0x000098ec, 0x00000008},
451};
452
453static const u32 ar5416Bank2_9100[][2] = {
454 { 0x000098b0, 0x0e73ff17},
455 { 0x000098e0, 0x00000420},
456};
457
458static const u32 ar5416Bank3_9100[][3] = {
459 { 0x000098f0, 0x01400018, 0x01c00018 },
460};
461
462static const u32 ar5416Bank6_9100[][3] = {
463
464 { 0x0000989c, 0x00000000, 0x00000000 },
465 { 0x0000989c, 0x00000000, 0x00000000 },
466 { 0x0000989c, 0x00000000, 0x00000000 },
467 { 0x0000989c, 0x00e00000, 0x00e00000 },
468 { 0x0000989c, 0x005e0000, 0x005e0000 },
469 { 0x0000989c, 0x00120000, 0x00120000 },
470 { 0x0000989c, 0x00620000, 0x00620000 },
471 { 0x0000989c, 0x00020000, 0x00020000 },
472 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
473 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
474 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
475 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
476 { 0x0000989c, 0x005f0000, 0x005f0000 },
477 { 0x0000989c, 0x00870000, 0x00870000 },
478 { 0x0000989c, 0x00f90000, 0x00f90000 },
479 { 0x0000989c, 0x007b0000, 0x007b0000 },
480 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
481 { 0x0000989c, 0x00f50000, 0x00f50000 },
482 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
483 { 0x0000989c, 0x00110000, 0x00110000 },
484 { 0x0000989c, 0x006100a8, 0x006100a8 },
485 { 0x0000989c, 0x004210a2, 0x004210a2 },
486 { 0x0000989c, 0x0014000f, 0x0014000f },
487 { 0x0000989c, 0x00c40002, 0x00c40002 },
488 { 0x0000989c, 0x003000f2, 0x003000f2 },
489 { 0x0000989c, 0x00440016, 0x00440016 },
490 { 0x0000989c, 0x00410040, 0x00410040 },
491 { 0x0000989c, 0x000180d6, 0x000180d6 },
492 { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
493 { 0x0000989c, 0x000000b1, 0x000000b1 },
494 { 0x0000989c, 0x00002000, 0x00002000 },
495 { 0x0000989c, 0x000000d4, 0x000000d4 },
496 { 0x000098d0, 0x0000000f, 0x0010000f },
497};
498
499
500static const u32 ar5416Bank6TPC_9100[][3] = {
501
502 { 0x0000989c, 0x00000000, 0x00000000 },
503 { 0x0000989c, 0x00000000, 0x00000000 },
504 { 0x0000989c, 0x00000000, 0x00000000 },
505 { 0x0000989c, 0x00e00000, 0x00e00000 },
506 { 0x0000989c, 0x005e0000, 0x005e0000 },
507 { 0x0000989c, 0x00120000, 0x00120000 },
508 { 0x0000989c, 0x00620000, 0x00620000 },
509 { 0x0000989c, 0x00020000, 0x00020000 },
510 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
511 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
512 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
513 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
514 { 0x0000989c, 0x005f0000, 0x005f0000 },
515 { 0x0000989c, 0x00870000, 0x00870000 },
516 { 0x0000989c, 0x00f90000, 0x00f90000 },
517 { 0x0000989c, 0x007b0000, 0x007b0000 },
518 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
519 { 0x0000989c, 0x00f50000, 0x00f50000 },
520 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
521 { 0x0000989c, 0x00110000, 0x00110000 },
522 { 0x0000989c, 0x006100a8, 0x006100a8 },
523 { 0x0000989c, 0x00423022, 0x00423022 },
524 { 0x0000989c, 0x2014008f, 0x2014008f },
525 { 0x0000989c, 0x00c40002, 0x00c40002 },
526 { 0x0000989c, 0x003000f2, 0x003000f2 },
527 { 0x0000989c, 0x00440016, 0x00440016 },
528 { 0x0000989c, 0x00410040, 0x00410040 },
529 { 0x0000989c, 0x0001805e, 0x0001805e },
530 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
531 { 0x0000989c, 0x000000e1, 0x000000e1 },
532 { 0x0000989c, 0x00007080, 0x00007080 },
533 { 0x0000989c, 0x000000d4, 0x000000d4 },
534 { 0x000098d0, 0x0000000f, 0x0010000f },
535};
536
537static const u32 ar5416Bank7_9100[][2] = {
538 { 0x0000989c, 0x00000500 },
539 { 0x0000989c, 0x00000800 },
540 { 0x000098cc, 0x0000000e },
541};
542
543static const u32 ar5416Addac_9100[][2] = {
544 {0x0000989c, 0x00000000 },
545 {0x0000989c, 0x00000000 },
546 {0x0000989c, 0x00000000 },
547 {0x0000989c, 0x00000000 },
548 {0x0000989c, 0x00000000 },
549 {0x0000989c, 0x00000000 },
550 {0x0000989c, 0x00000000 },
551 {0x0000989c, 0x00000010 },
552 {0x0000989c, 0x00000000 },
553 {0x0000989c, 0x00000000 },
554 {0x0000989c, 0x00000000 },
555 {0x0000989c, 0x00000000 },
556 {0x0000989c, 0x00000000 },
557 {0x0000989c, 0x00000000 },
558 {0x0000989c, 0x00000000 },
559 {0x0000989c, 0x00000000 },
560 {0x0000989c, 0x00000000 },
561 {0x0000989c, 0x00000000 },
562 {0x0000989c, 0x00000000 },
563 {0x0000989c, 0x00000000 },
564 {0x0000989c, 0x00000000 },
565 {0x0000989c, 0x000000c0 },
566 {0x0000989c, 0x00000015 },
567 {0x0000989c, 0x00000000 },
568 {0x0000989c, 0x00000000 },
569 {0x0000989c, 0x00000000 },
570 {0x0000989c, 0x00000000 },
571 {0x0000989c, 0x00000000 },
572 {0x0000989c, 0x00000000 },
573 {0x0000989c, 0x00000000 },
574 {0x0000989c, 0x00000000 },
575 {0x000098cc, 0x00000000 },
576};
577
578static const u32 ar5416Modes_9160[][6] = {
579 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
580 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
581 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
582 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
583 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
584 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
585 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
586 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
587 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
588 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
589 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
590 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
591 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
592 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
593 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
594 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
595 { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
596 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
597 { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
598 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
599 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
600 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
601 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
602 { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
603 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
604 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
605 { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
606 { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
607 { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
608 { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
609 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
610 { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
611 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
612 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
613 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
614 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
615 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
616 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
617 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
618 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
619 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
620 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
621 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
622 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
623 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
624 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
625 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
626 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
627 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
628 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
629 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
630 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
631 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
632 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
633 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
634 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
635 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
636 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
637 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
638 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
639 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
640 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
641};
642
643static const u32 ar5416Common_9160[][2] = {
644 { 0x0000000c, 0x00000000 },
645 { 0x00000030, 0x00020015 },
646 { 0x00000034, 0x00000005 },
647 { 0x00000040, 0x00000000 },
648 { 0x00000044, 0x00000008 },
649 { 0x00000048, 0x00000008 },
650 { 0x0000004c, 0x00000010 },
651 { 0x00000050, 0x00000000 },
652 { 0x00000054, 0x0000001f },
653 { 0x00000800, 0x00000000 },
654 { 0x00000804, 0x00000000 },
655 { 0x00000808, 0x00000000 },
656 { 0x0000080c, 0x00000000 },
657 { 0x00000810, 0x00000000 },
658 { 0x00000814, 0x00000000 },
659 { 0x00000818, 0x00000000 },
660 { 0x0000081c, 0x00000000 },
661 { 0x00000820, 0x00000000 },
662 { 0x00000824, 0x00000000 },
663 { 0x00001040, 0x002ffc0f },
664 { 0x00001044, 0x002ffc0f },
665 { 0x00001048, 0x002ffc0f },
666 { 0x0000104c, 0x002ffc0f },
667 { 0x00001050, 0x002ffc0f },
668 { 0x00001054, 0x002ffc0f },
669 { 0x00001058, 0x002ffc0f },
670 { 0x0000105c, 0x002ffc0f },
671 { 0x00001060, 0x002ffc0f },
672 { 0x00001064, 0x002ffc0f },
673 { 0x00001230, 0x00000000 },
674 { 0x00001270, 0x00000000 },
675 { 0x00001038, 0x00000000 },
676 { 0x00001078, 0x00000000 },
677 { 0x000010b8, 0x00000000 },
678 { 0x000010f8, 0x00000000 },
679 { 0x00001138, 0x00000000 },
680 { 0x00001178, 0x00000000 },
681 { 0x000011b8, 0x00000000 },
682 { 0x000011f8, 0x00000000 },
683 { 0x00001238, 0x00000000 },
684 { 0x00001278, 0x00000000 },
685 { 0x000012b8, 0x00000000 },
686 { 0x000012f8, 0x00000000 },
687 { 0x00001338, 0x00000000 },
688 { 0x00001378, 0x00000000 },
689 { 0x000013b8, 0x00000000 },
690 { 0x000013f8, 0x00000000 },
691 { 0x00001438, 0x00000000 },
692 { 0x00001478, 0x00000000 },
693 { 0x000014b8, 0x00000000 },
694 { 0x000014f8, 0x00000000 },
695 { 0x00001538, 0x00000000 },
696 { 0x00001578, 0x00000000 },
697 { 0x000015b8, 0x00000000 },
698 { 0x000015f8, 0x00000000 },
699 { 0x00001638, 0x00000000 },
700 { 0x00001678, 0x00000000 },
701 { 0x000016b8, 0x00000000 },
702 { 0x000016f8, 0x00000000 },
703 { 0x00001738, 0x00000000 },
704 { 0x00001778, 0x00000000 },
705 { 0x000017b8, 0x00000000 },
706 { 0x000017f8, 0x00000000 },
707 { 0x0000103c, 0x00000000 },
708 { 0x0000107c, 0x00000000 },
709 { 0x000010bc, 0x00000000 },
710 { 0x000010fc, 0x00000000 },
711 { 0x0000113c, 0x00000000 },
712 { 0x0000117c, 0x00000000 },
713 { 0x000011bc, 0x00000000 },
714 { 0x000011fc, 0x00000000 },
715 { 0x0000123c, 0x00000000 },
716 { 0x0000127c, 0x00000000 },
717 { 0x000012bc, 0x00000000 },
718 { 0x000012fc, 0x00000000 },
719 { 0x0000133c, 0x00000000 },
720 { 0x0000137c, 0x00000000 },
721 { 0x000013bc, 0x00000000 },
722 { 0x000013fc, 0x00000000 },
723 { 0x0000143c, 0x00000000 },
724 { 0x0000147c, 0x00000000 },
725 { 0x00004030, 0x00000002 },
726 { 0x0000403c, 0x00000002 },
727 { 0x00007010, 0x00000020 },
728 { 0x00007038, 0x000004c2 },
729 { 0x00008004, 0x00000000 },
730 { 0x00008008, 0x00000000 },
731 { 0x0000800c, 0x00000000 },
732 { 0x00008018, 0x00000700 },
733 { 0x00008020, 0x00000000 },
734 { 0x00008038, 0x00000000 },
735 { 0x0000803c, 0x00000000 },
736 { 0x00008048, 0x40000000 },
737 { 0x00008054, 0x00000000 },
738 { 0x00008058, 0x00000000 },
739 { 0x0000805c, 0x000fc78f },
740 { 0x00008060, 0x0000000f },
741 { 0x00008064, 0x00000000 },
742 { 0x000080c0, 0x2a82301a },
743 { 0x000080c4, 0x05dc01e0 },
744 { 0x000080c8, 0x1f402710 },
745 { 0x000080cc, 0x01f40000 },
746 { 0x000080d0, 0x00001e00 },
747 { 0x000080d4, 0x00000000 },
748 { 0x000080d8, 0x00400000 },
749 { 0x000080e0, 0xffffffff },
750 { 0x000080e4, 0x0000ffff },
751 { 0x000080e8, 0x003f3f3f },
752 { 0x000080ec, 0x00000000 },
753 { 0x000080f0, 0x00000000 },
754 { 0x000080f4, 0x00000000 },
755 { 0x000080f8, 0x00000000 },
756 { 0x000080fc, 0x00020000 },
757 { 0x00008100, 0x00020000 },
758 { 0x00008104, 0x00000001 },
759 { 0x00008108, 0x00000052 },
760 { 0x0000810c, 0x00000000 },
761 { 0x00008110, 0x00000168 },
762 { 0x00008118, 0x000100aa },
763 { 0x0000811c, 0x00003210 },
764 { 0x00008120, 0x08f04800 },
765 { 0x00008124, 0x00000000 },
766 { 0x00008128, 0x00000000 },
767 { 0x0000812c, 0x00000000 },
768 { 0x00008130, 0x00000000 },
769 { 0x00008134, 0x00000000 },
770 { 0x00008138, 0x00000000 },
771 { 0x0000813c, 0x00000000 },
772 { 0x00008144, 0xffffffff },
773 { 0x00008168, 0x00000000 },
774 { 0x0000816c, 0x00000000 },
775 { 0x00008170, 0x32143320 },
776 { 0x00008174, 0xfaa4fa50 },
777 { 0x00008178, 0x00000100 },
778 { 0x0000817c, 0x00000000 },
779 { 0x000081c4, 0x00000000 },
780 { 0x000081d0, 0x00003210 },
781 { 0x000081ec, 0x00000000 },
782 { 0x000081f0, 0x00000000 },
783 { 0x000081f4, 0x00000000 },
784 { 0x000081f8, 0x00000000 },
785 { 0x000081fc, 0x00000000 },
786 { 0x00008200, 0x00000000 },
787 { 0x00008204, 0x00000000 },
788 { 0x00008208, 0x00000000 },
789 { 0x0000820c, 0x00000000 },
790 { 0x00008210, 0x00000000 },
791 { 0x00008214, 0x00000000 },
792 { 0x00008218, 0x00000000 },
793 { 0x0000821c, 0x00000000 },
794 { 0x00008220, 0x00000000 },
795 { 0x00008224, 0x00000000 },
796 { 0x00008228, 0x00000000 },
797 { 0x0000822c, 0x00000000 },
798 { 0x00008230, 0x00000000 },
799 { 0x00008234, 0x00000000 },
800 { 0x00008238, 0x00000000 },
801 { 0x0000823c, 0x00000000 },
802 { 0x00008240, 0x00100000 },
803 { 0x00008244, 0x0010f400 },
804 { 0x00008248, 0x00000100 },
805 { 0x0000824c, 0x0001e800 },
806 { 0x00008250, 0x00000000 },
807 { 0x00008254, 0x00000000 },
808 { 0x00008258, 0x00000000 },
809 { 0x0000825c, 0x400000ff },
810 { 0x00008260, 0x00080922 },
811 { 0x00008270, 0x00000000 },
812 { 0x00008274, 0x40000000 },
813 { 0x00008278, 0x003e4180 },
814 { 0x0000827c, 0x00000000 },
815 { 0x00008284, 0x0000002c },
816 { 0x00008288, 0x0000002c },
817 { 0x0000828c, 0x00000000 },
818 { 0x00008294, 0x00000000 },
819 { 0x00008298, 0x00000000 },
820 { 0x00008300, 0x00000000 },
821 { 0x00008304, 0x00000000 },
822 { 0x00008308, 0x00000000 },
823 { 0x0000830c, 0x00000000 },
824 { 0x00008310, 0x00000000 },
825 { 0x00008314, 0x00000000 },
826 { 0x00008318, 0x00000000 },
827 { 0x00008328, 0x00000000 },
828 { 0x0000832c, 0x00000007 },
829 { 0x00008330, 0x00000302 },
830 { 0x00008334, 0x00000e00 },
831 { 0x00008338, 0x00ff0000 },
832 { 0x0000833c, 0x00000000 },
833 { 0x00008340, 0x000107ff },
834 { 0x00009808, 0x00000000 },
835 { 0x0000980c, 0xad848e19 },
836 { 0x00009810, 0x7d14e000 },
837 { 0x00009814, 0x9c0a9f6b },
838 { 0x0000981c, 0x00000000 },
839 { 0x0000982c, 0x0000a000 },
840 { 0x00009830, 0x00000000 },
841 { 0x0000983c, 0x00200400 },
842 { 0x00009840, 0x206a01ae },
843 { 0x0000984c, 0x1284233c },
844 { 0x00009854, 0x00000859 },
845 { 0x00009900, 0x00000000 },
846 { 0x00009904, 0x00000000 },
847 { 0x00009908, 0x00000000 },
848 { 0x0000990c, 0x00000000 },
849 { 0x0000991c, 0x10000fff },
850 { 0x00009920, 0x05100000 },
851 { 0x0000a920, 0x05100000 },
852 { 0x0000b920, 0x05100000 },
853 { 0x00009928, 0x00000001 },
854 { 0x0000992c, 0x00000004 },
855 { 0x00009934, 0x1e1f2022 },
856 { 0x00009938, 0x0a0b0c0d },
857 { 0x0000993c, 0x00000000 },
858 { 0x00009948, 0x9280b212 },
859 { 0x0000994c, 0x00020028 },
860 { 0x00009954, 0x5f3ca3de },
861 { 0x00009958, 0x2108ecff },
862 { 0x00009940, 0x00750604 },
863 { 0x0000c95c, 0x004b6a8e },
864 { 0x00009970, 0x190fb515 },
865 { 0x00009974, 0x00000000 },
866 { 0x00009978, 0x00000001 },
867 { 0x0000997c, 0x00000000 },
868 { 0x00009980, 0x00000000 },
869 { 0x00009984, 0x00000000 },
870 { 0x00009988, 0x00000000 },
871 { 0x0000998c, 0x00000000 },
872 { 0x00009990, 0x00000000 },
873 { 0x00009994, 0x00000000 },
874 { 0x00009998, 0x00000000 },
875 { 0x0000999c, 0x00000000 },
876 { 0x000099a0, 0x00000000 },
877 { 0x000099a4, 0x00000001 },
878 { 0x000099a8, 0x201fff00 },
879 { 0x000099ac, 0x006f0000 },
880 { 0x000099b0, 0x03051000 },
881 { 0x000099dc, 0x00000000 },
882 { 0x000099e0, 0x00000200 },
883 { 0x000099e4, 0xaaaaaaaa },
884 { 0x000099e8, 0x3c466478 },
885 { 0x000099ec, 0x0cc80caa },
886 { 0x000099fc, 0x00001042 },
887 { 0x00009b00, 0x00000000 },
888 { 0x00009b04, 0x00000001 },
889 { 0x00009b08, 0x00000002 },
890 { 0x00009b0c, 0x00000003 },
891 { 0x00009b10, 0x00000004 },
892 { 0x00009b14, 0x00000005 },
893 { 0x00009b18, 0x00000008 },
894 { 0x00009b1c, 0x00000009 },
895 { 0x00009b20, 0x0000000a },
896 { 0x00009b24, 0x0000000b },
897 { 0x00009b28, 0x0000000c },
898 { 0x00009b2c, 0x0000000d },
899 { 0x00009b30, 0x00000010 },
900 { 0x00009b34, 0x00000011 },
901 { 0x00009b38, 0x00000012 },
902 { 0x00009b3c, 0x00000013 },
903 { 0x00009b40, 0x00000014 },
904 { 0x00009b44, 0x00000015 },
905 { 0x00009b48, 0x00000018 },
906 { 0x00009b4c, 0x00000019 },
907 { 0x00009b50, 0x0000001a },
908 { 0x00009b54, 0x0000001b },
909 { 0x00009b58, 0x0000001c },
910 { 0x00009b5c, 0x0000001d },
911 { 0x00009b60, 0x00000020 },
912 { 0x00009b64, 0x00000021 },
913 { 0x00009b68, 0x00000022 },
914 { 0x00009b6c, 0x00000023 },
915 { 0x00009b70, 0x00000024 },
916 { 0x00009b74, 0x00000025 },
917 { 0x00009b78, 0x00000028 },
918 { 0x00009b7c, 0x00000029 },
919 { 0x00009b80, 0x0000002a },
920 { 0x00009b84, 0x0000002b },
921 { 0x00009b88, 0x0000002c },
922 { 0x00009b8c, 0x0000002d },
923 { 0x00009b90, 0x00000030 },
924 { 0x00009b94, 0x00000031 },
925 { 0x00009b98, 0x00000032 },
926 { 0x00009b9c, 0x00000033 },
927 { 0x00009ba0, 0x00000034 },
928 { 0x00009ba4, 0x00000035 },
929 { 0x00009ba8, 0x00000035 },
930 { 0x00009bac, 0x00000035 },
931 { 0x00009bb0, 0x00000035 },
932 { 0x00009bb4, 0x00000035 },
933 { 0x00009bb8, 0x00000035 },
934 { 0x00009bbc, 0x00000035 },
935 { 0x00009bc0, 0x00000035 },
936 { 0x00009bc4, 0x00000035 },
937 { 0x00009bc8, 0x00000035 },
938 { 0x00009bcc, 0x00000035 },
939 { 0x00009bd0, 0x00000035 },
940 { 0x00009bd4, 0x00000035 },
941 { 0x00009bd8, 0x00000035 },
942 { 0x00009bdc, 0x00000035 },
943 { 0x00009be0, 0x00000035 },
944 { 0x00009be4, 0x00000035 },
945 { 0x00009be8, 0x00000035 },
946 { 0x00009bec, 0x00000035 },
947 { 0x00009bf0, 0x00000035 },
948 { 0x00009bf4, 0x00000035 },
949 { 0x00009bf8, 0x00000010 },
950 { 0x00009bfc, 0x0000001a },
951 { 0x0000a210, 0x40806333 },
952 { 0x0000a214, 0x00106c10 },
953 { 0x0000a218, 0x009c4060 },
954 { 0x0000a220, 0x018830c6 },
955 { 0x0000a224, 0x00000400 },
956 { 0x0000a228, 0x001a0bb5 },
957 { 0x0000a22c, 0x00000000 },
958 { 0x0000a234, 0x20202020 },
959 { 0x0000a238, 0x20202020 },
960 { 0x0000a23c, 0x13c889af },
961 { 0x0000a240, 0x38490a20 },
962 { 0x0000a244, 0x00007bb6 },
963 { 0x0000a248, 0x0fff3ffc },
964 { 0x0000a24c, 0x00000001 },
965 { 0x0000a250, 0x0000e000 },
966 { 0x0000a254, 0x00000000 },
967 { 0x0000a258, 0x0cc75380 },
968 { 0x0000a25c, 0x0f0f0f01 },
969 { 0x0000a260, 0xdfa91f01 },
970 { 0x0000a268, 0x00000001 },
971 { 0x0000a26c, 0x0ebae9c6 },
972 { 0x0000b26c, 0x0ebae9c6 },
973 { 0x0000c26c, 0x0ebae9c6 },
974 { 0x0000d270, 0x00820820 },
975 { 0x0000a278, 0x1ce739ce },
976 { 0x0000a27c, 0x050701ce },
977 { 0x0000a338, 0x00000000 },
978 { 0x0000a33c, 0x00000000 },
979 { 0x0000a340, 0x00000000 },
980 { 0x0000a344, 0x00000000 },
981 { 0x0000a348, 0x3fffffff },
982 { 0x0000a34c, 0x3fffffff },
983 { 0x0000a350, 0x3fffffff },
984 { 0x0000a354, 0x0003ffff },
985 { 0x0000a358, 0x79bfaa03 },
986 { 0x0000d35c, 0x07ffffef },
987 { 0x0000d360, 0x0fffffe7 },
988 { 0x0000d364, 0x17ffffe5 },
989 { 0x0000d368, 0x1fffffe4 },
990 { 0x0000d36c, 0x37ffffe3 },
991 { 0x0000d370, 0x3fffffe3 },
992 { 0x0000d374, 0x57ffffe3 },
993 { 0x0000d378, 0x5fffffe2 },
994 { 0x0000d37c, 0x7fffffe2 },
995 { 0x0000d380, 0x7f3c7bba },
996 { 0x0000d384, 0xf3307ff0 },
997 { 0x0000a388, 0x0c000000 },
998 { 0x0000a38c, 0x20202020 },
999 { 0x0000a390, 0x20202020 },
1000 { 0x0000a394, 0x1ce739ce },
1001 { 0x0000a398, 0x000001ce },
1002 { 0x0000a39c, 0x00000001 },
1003 { 0x0000a3a0, 0x00000000 },
1004 { 0x0000a3a4, 0x00000000 },
1005 { 0x0000a3a8, 0x00000000 },
1006 { 0x0000a3ac, 0x00000000 },
1007 { 0x0000a3b0, 0x00000000 },
1008 { 0x0000a3b4, 0x00000000 },
1009 { 0x0000a3b8, 0x00000000 },
1010 { 0x0000a3bc, 0x00000000 },
1011 { 0x0000a3c0, 0x00000000 },
1012 { 0x0000a3c4, 0x00000000 },
1013 { 0x0000a3c8, 0x00000246 },
1014 { 0x0000a3cc, 0x20202020 },
1015 { 0x0000a3d0, 0x20202020 },
1016 { 0x0000a3d4, 0x20202020 },
1017 { 0x0000a3dc, 0x1ce739ce },
1018 { 0x0000a3e0, 0x000001ce },
1019};
1020
1021static const u32 ar5416Bank0_9160[][2] = {
1022 { 0x000098b0, 0x1e5795e5 },
1023 { 0x000098e0, 0x02008020 },
1024};
1025
1026static const u32 ar5416BB_RfGain_9160[][3] = {
1027 { 0x00009a00, 0x00000000, 0x00000000 },
1028 { 0x00009a04, 0x00000040, 0x00000040 },
1029 { 0x00009a08, 0x00000080, 0x00000080 },
1030 { 0x00009a0c, 0x000001a1, 0x00000141 },
1031 { 0x00009a10, 0x000001e1, 0x00000181 },
1032 { 0x00009a14, 0x00000021, 0x000001c1 },
1033 { 0x00009a18, 0x00000061, 0x00000001 },
1034 { 0x00009a1c, 0x00000168, 0x00000041 },
1035 { 0x00009a20, 0x000001a8, 0x000001a8 },
1036 { 0x00009a24, 0x000001e8, 0x000001e8 },
1037 { 0x00009a28, 0x00000028, 0x00000028 },
1038 { 0x00009a2c, 0x00000068, 0x00000068 },
1039 { 0x00009a30, 0x00000189, 0x000000a8 },
1040 { 0x00009a34, 0x000001c9, 0x00000169 },
1041 { 0x00009a38, 0x00000009, 0x000001a9 },
1042 { 0x00009a3c, 0x00000049, 0x000001e9 },
1043 { 0x00009a40, 0x00000089, 0x00000029 },
1044 { 0x00009a44, 0x00000170, 0x00000069 },
1045 { 0x00009a48, 0x000001b0, 0x00000190 },
1046 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1047 { 0x00009a50, 0x00000030, 0x00000010 },
1048 { 0x00009a54, 0x00000070, 0x00000050 },
1049 { 0x00009a58, 0x00000191, 0x00000090 },
1050 { 0x00009a5c, 0x000001d1, 0x00000151 },
1051 { 0x00009a60, 0x00000011, 0x00000191 },
1052 { 0x00009a64, 0x00000051, 0x000001d1 },
1053 { 0x00009a68, 0x00000091, 0x00000011 },
1054 { 0x00009a6c, 0x000001b8, 0x00000051 },
1055 { 0x00009a70, 0x000001f8, 0x00000198 },
1056 { 0x00009a74, 0x00000038, 0x000001d8 },
1057 { 0x00009a78, 0x00000078, 0x00000018 },
1058 { 0x00009a7c, 0x00000199, 0x00000058 },
1059 { 0x00009a80, 0x000001d9, 0x00000098 },
1060 { 0x00009a84, 0x00000019, 0x00000159 },
1061 { 0x00009a88, 0x00000059, 0x00000199 },
1062 { 0x00009a8c, 0x00000099, 0x000001d9 },
1063 { 0x00009a90, 0x000000d9, 0x00000019 },
1064 { 0x00009a94, 0x000000f9, 0x00000059 },
1065 { 0x00009a98, 0x000000f9, 0x00000099 },
1066 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1067 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1068 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1069 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1070 { 0x00009aac, 0x000000f9, 0x000000f9 },
1071 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1072 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1073 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1074 { 0x00009abc, 0x000000f9, 0x000000f9 },
1075 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1076 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1077 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1078 { 0x00009acc, 0x000000f9, 0x000000f9 },
1079 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1080 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1081 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1082 { 0x00009adc, 0x000000f9, 0x000000f9 },
1083 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1084 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1085 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1086 { 0x00009aec, 0x000000f9, 0x000000f9 },
1087 { 0x00009af0, 0x000000f9, 0x000000f9 },
1088 { 0x00009af4, 0x000000f9, 0x000000f9 },
1089 { 0x00009af8, 0x000000f9, 0x000000f9 },
1090 { 0x00009afc, 0x000000f9, 0x000000f9 },
1091};
1092
1093static const u32 ar5416Bank1_9160[][2] = {
1094 { 0x000098b0, 0x02108421 },
1095 { 0x000098ec, 0x00000008 },
1096};
1097
1098static const u32 ar5416Bank2_9160[][2] = {
1099 { 0x000098b0, 0x0e73ff17 },
1100 { 0x000098e0, 0x00000420 },
1101};
1102
1103static const u32 ar5416Bank3_9160[][3] = {
1104 { 0x000098f0, 0x01400018, 0x01c00018 },
1105};
1106
1107static const u32 ar5416Bank6_9160[][3] = {
1108 { 0x0000989c, 0x00000000, 0x00000000 },
1109 { 0x0000989c, 0x00000000, 0x00000000 },
1110 { 0x0000989c, 0x00000000, 0x00000000 },
1111 { 0x0000989c, 0x00e00000, 0x00e00000 },
1112 { 0x0000989c, 0x005e0000, 0x005e0000 },
1113 { 0x0000989c, 0x00120000, 0x00120000 },
1114 { 0x0000989c, 0x00620000, 0x00620000 },
1115 { 0x0000989c, 0x00020000, 0x00020000 },
1116 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1117 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1118 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1119 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1120 { 0x0000989c, 0x005f0000, 0x005f0000 },
1121 { 0x0000989c, 0x00870000, 0x00870000 },
1122 { 0x0000989c, 0x00f90000, 0x00f90000 },
1123 { 0x0000989c, 0x007b0000, 0x007b0000 },
1124 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1125 { 0x0000989c, 0x00f50000, 0x00f50000 },
1126 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1127 { 0x0000989c, 0x00110000, 0x00110000 },
1128 { 0x0000989c, 0x006100a8, 0x006100a8 },
1129 { 0x0000989c, 0x004210a2, 0x004210a2 },
1130 { 0x0000989c, 0x0014008f, 0x0014008f },
1131 { 0x0000989c, 0x00c40003, 0x00c40003 },
1132 { 0x0000989c, 0x003000f2, 0x003000f2 },
1133 { 0x0000989c, 0x00440016, 0x00440016 },
1134 { 0x0000989c, 0x00410040, 0x00410040 },
1135 { 0x0000989c, 0x0001805e, 0x0001805e },
1136 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1137 { 0x0000989c, 0x000000f1, 0x000000f1 },
1138 { 0x0000989c, 0x00002081, 0x00002081 },
1139 { 0x0000989c, 0x000000d4, 0x000000d4 },
1140 { 0x000098d0, 0x0000000f, 0x0010000f },
1141};
1142
1143static const u32 ar5416Bank6TPC_9160[][3] = {
1144 { 0x0000989c, 0x00000000, 0x00000000 },
1145 { 0x0000989c, 0x00000000, 0x00000000 },
1146 { 0x0000989c, 0x00000000, 0x00000000 },
1147 { 0x0000989c, 0x00e00000, 0x00e00000 },
1148 { 0x0000989c, 0x005e0000, 0x005e0000 },
1149 { 0x0000989c, 0x00120000, 0x00120000 },
1150 { 0x0000989c, 0x00620000, 0x00620000 },
1151 { 0x0000989c, 0x00020000, 0x00020000 },
1152 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1153 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1154 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1155 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1156 { 0x0000989c, 0x005f0000, 0x005f0000 },
1157 { 0x0000989c, 0x00870000, 0x00870000 },
1158 { 0x0000989c, 0x00f90000, 0x00f90000 },
1159 { 0x0000989c, 0x007b0000, 0x007b0000 },
1160 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1161 { 0x0000989c, 0x00f50000, 0x00f50000 },
1162 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1163 { 0x0000989c, 0x00110000, 0x00110000 },
1164 { 0x0000989c, 0x006100a8, 0x006100a8 },
1165 { 0x0000989c, 0x00423022, 0x00423022 },
1166 { 0x0000989c, 0x2014008f, 0x2014008f },
1167 { 0x0000989c, 0x00c40002, 0x00c40002 },
1168 { 0x0000989c, 0x003000f2, 0x003000f2 },
1169 { 0x0000989c, 0x00440016, 0x00440016 },
1170 { 0x0000989c, 0x00410040, 0x00410040 },
1171 { 0x0000989c, 0x0001805e, 0x0001805e },
1172 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1173 { 0x0000989c, 0x000000e1, 0x000000e1 },
1174 { 0x0000989c, 0x00007080, 0x00007080 },
1175 { 0x0000989c, 0x000000d4, 0x000000d4 },
1176 { 0x000098d0, 0x0000000f, 0x0010000f },
1177};
1178
1179static const u32 ar5416Bank7_9160[][2] = {
1180 { 0x0000989c, 0x00000500 },
1181 { 0x0000989c, 0x00000800 },
1182 { 0x000098cc, 0x0000000e },
1183};
1184
1185static const u32 ar5416Addac_9160[][2] = {
1186 {0x0000989c, 0x00000000 },
1187 {0x0000989c, 0x00000000 },
1188 {0x0000989c, 0x00000000 },
1189 {0x0000989c, 0x00000000 },
1190 {0x0000989c, 0x00000000 },
1191 {0x0000989c, 0x00000000 },
1192 {0x0000989c, 0x000000c0 },
1193 {0x0000989c, 0x00000018 },
1194 {0x0000989c, 0x00000004 },
1195 {0x0000989c, 0x00000000 },
1196 {0x0000989c, 0x00000000 },
1197 {0x0000989c, 0x00000000 },
1198 {0x0000989c, 0x00000000 },
1199 {0x0000989c, 0x00000000 },
1200 {0x0000989c, 0x00000000 },
1201 {0x0000989c, 0x00000000 },
1202 {0x0000989c, 0x00000000 },
1203 {0x0000989c, 0x00000000 },
1204 {0x0000989c, 0x00000000 },
1205 {0x0000989c, 0x00000000 },
1206 {0x0000989c, 0x00000000 },
1207 {0x0000989c, 0x000000c0 },
1208 {0x0000989c, 0x00000019 },
1209 {0x0000989c, 0x00000004 },
1210 {0x0000989c, 0x00000000 },
1211 {0x0000989c, 0x00000000 },
1212 {0x0000989c, 0x00000000 },
1213 {0x0000989c, 0x00000004 },
1214 {0x0000989c, 0x00000003 },
1215 {0x0000989c, 0x00000008 },
1216 {0x0000989c, 0x00000000 },
1217 {0x000098cc, 0x00000000 },
1218};
1219
1220static const u32 ar5416Addac_91601_1[][2] = {
1221 {0x0000989c, 0x00000000 },
1222 {0x0000989c, 0x00000000 },
1223 {0x0000989c, 0x00000000 },
1224 {0x0000989c, 0x00000000 },
1225 {0x0000989c, 0x00000000 },
1226 {0x0000989c, 0x00000000 },
1227 {0x0000989c, 0x000000c0 },
1228 {0x0000989c, 0x00000018 },
1229 {0x0000989c, 0x00000004 },
1230 {0x0000989c, 0x00000000 },
1231 {0x0000989c, 0x00000000 },
1232 {0x0000989c, 0x00000000 },
1233 {0x0000989c, 0x00000000 },
1234 {0x0000989c, 0x00000000 },
1235 {0x0000989c, 0x00000000 },
1236 {0x0000989c, 0x00000000 },
1237 {0x0000989c, 0x00000000 },
1238 {0x0000989c, 0x00000000 },
1239 {0x0000989c, 0x00000000 },
1240 {0x0000989c, 0x00000000 },
1241 {0x0000989c, 0x00000000 },
1242 {0x0000989c, 0x000000c0 },
1243 {0x0000989c, 0x00000019 },
1244 {0x0000989c, 0x00000004 },
1245 {0x0000989c, 0x00000000 },
1246 {0x0000989c, 0x00000000 },
1247 {0x0000989c, 0x00000000 },
1248 {0x0000989c, 0x00000000 },
1249 {0x0000989c, 0x00000000 },
1250 {0x0000989c, 0x00000000 },
1251 {0x0000989c, 0x00000000 },
1252 {0x000098cc, 0x00000000 },
1253};
1254
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
new file mode 100644
index 000000000000..5fdbb53b47e0
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -0,0 +1,1000 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "hw-ops.h"
19#include "ar9002_phy.h"
20
21#define AR9285_CLCAL_REDO_THRESH 1
22
23static void ar9002_hw_setup_calibration(struct ath_hw *ah,
24 struct ath9k_cal_list *currCal)
25{
26 struct ath_common *common = ath9k_hw_common(ah);
27
28 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
29 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
30 currCal->calData->calCountMax);
31
32 switch (currCal->calData->calType) {
33 case IQ_MISMATCH_CAL:
34 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
35 ath_print(common, ATH_DBG_CALIBRATE,
36 "starting IQ Mismatch Calibration\n");
37 break;
38 case ADC_GAIN_CAL:
39 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
40 ath_print(common, ATH_DBG_CALIBRATE,
41 "starting ADC Gain Calibration\n");
42 break;
43 case ADC_DC_CAL:
44 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
45 ath_print(common, ATH_DBG_CALIBRATE,
46 "starting ADC DC Calibration\n");
47 break;
48 case ADC_DC_INIT_CAL:
49 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
50 ath_print(common, ATH_DBG_CALIBRATE,
51 "starting Init ADC DC Calibration\n");
52 break;
53 case TEMP_COMP_CAL:
54 break; /* Not supported */
55 }
56
57 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
58 AR_PHY_TIMING_CTRL4_DO_CAL);
59}
60
61static bool ar9002_hw_per_calibration(struct ath_hw *ah,
62 struct ath9k_channel *ichan,
63 u8 rxchainmask,
64 struct ath9k_cal_list *currCal)
65{
66 bool iscaldone = false;
67
68 if (currCal->calState == CAL_RUNNING) {
69 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
70 AR_PHY_TIMING_CTRL4_DO_CAL)) {
71
72 currCal->calData->calCollect(ah);
73 ah->cal_samples++;
74
75 if (ah->cal_samples >=
76 currCal->calData->calNumSamples) {
77 int i, numChains = 0;
78 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
79 if (rxchainmask & (1 << i))
80 numChains++;
81 }
82
83 currCal->calData->calPostProc(ah, numChains);
84 ichan->CalValid |= currCal->calData->calType;
85 currCal->calState = CAL_DONE;
86 iscaldone = true;
87 } else {
88 ar9002_hw_setup_calibration(ah, currCal);
89 }
90 }
91 } else if (!(ichan->CalValid & currCal->calData->calType)) {
92 ath9k_hw_reset_calibration(ah, currCal);
93 }
94
95 return iscaldone;
96}
97
98/* Assumes you are talking about the currently configured channel */
99static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
100 enum ath9k_cal_types calType)
101{
102 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
103
104 switch (calType & ah->supp_cals) {
105 case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
106 return true;
107 case ADC_GAIN_CAL:
108 case ADC_DC_CAL:
109 if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
110 conf_is_ht20(conf)))
111 return true;
112 break;
113 }
114 return false;
115}
116
117static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
118{
119 int i;
120
121 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
122 ah->totalPowerMeasI[i] +=
123 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
124 ah->totalPowerMeasQ[i] +=
125 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
126 ah->totalIqCorrMeas[i] +=
127 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
128 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
129 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
130 ah->cal_samples, i, ah->totalPowerMeasI[i],
131 ah->totalPowerMeasQ[i],
132 ah->totalIqCorrMeas[i]);
133 }
134}
135
136static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah)
137{
138 int i;
139
140 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
141 ah->totalAdcIOddPhase[i] +=
142 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
143 ah->totalAdcIEvenPhase[i] +=
144 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
145 ah->totalAdcQOddPhase[i] +=
146 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
147 ah->totalAdcQEvenPhase[i] +=
148 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
149
150 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
151 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
152 "oddq=0x%08x; evenq=0x%08x;\n",
153 ah->cal_samples, i,
154 ah->totalAdcIOddPhase[i],
155 ah->totalAdcIEvenPhase[i],
156 ah->totalAdcQOddPhase[i],
157 ah->totalAdcQEvenPhase[i]);
158 }
159}
160
161static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah)
162{
163 int i;
164
165 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
166 ah->totalAdcDcOffsetIOddPhase[i] +=
167 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
168 ah->totalAdcDcOffsetIEvenPhase[i] +=
169 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
170 ah->totalAdcDcOffsetQOddPhase[i] +=
171 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
172 ah->totalAdcDcOffsetQEvenPhase[i] +=
173 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
174
175 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
176 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
177 "oddq=0x%08x; evenq=0x%08x;\n",
178 ah->cal_samples, i,
179 ah->totalAdcDcOffsetIOddPhase[i],
180 ah->totalAdcDcOffsetIEvenPhase[i],
181 ah->totalAdcDcOffsetQOddPhase[i],
182 ah->totalAdcDcOffsetQEvenPhase[i]);
183 }
184}
185
186static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
187{
188 struct ath_common *common = ath9k_hw_common(ah);
189 u32 powerMeasQ, powerMeasI, iqCorrMeas;
190 u32 qCoffDenom, iCoffDenom;
191 int32_t qCoff, iCoff;
192 int iqCorrNeg, i;
193
194 for (i = 0; i < numChains; i++) {
195 powerMeasI = ah->totalPowerMeasI[i];
196 powerMeasQ = ah->totalPowerMeasQ[i];
197 iqCorrMeas = ah->totalIqCorrMeas[i];
198
199 ath_print(common, ATH_DBG_CALIBRATE,
200 "Starting IQ Cal and Correction for Chain %d\n",
201 i);
202
203 ath_print(common, ATH_DBG_CALIBRATE,
204 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
205 i, ah->totalIqCorrMeas[i]);
206
207 iqCorrNeg = 0;
208
209 if (iqCorrMeas > 0x80000000) {
210 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
211 iqCorrNeg = 1;
212 }
213
214 ath_print(common, ATH_DBG_CALIBRATE,
215 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
216 ath_print(common, ATH_DBG_CALIBRATE,
217 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
218 ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
219 iqCorrNeg);
220
221 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
222 qCoffDenom = powerMeasQ / 64;
223
224 if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
225 (qCoffDenom != 0)) {
226 iCoff = iqCorrMeas / iCoffDenom;
227 qCoff = powerMeasI / qCoffDenom - 64;
228 ath_print(common, ATH_DBG_CALIBRATE,
229 "Chn %d iCoff = 0x%08x\n", i, iCoff);
230 ath_print(common, ATH_DBG_CALIBRATE,
231 "Chn %d qCoff = 0x%08x\n", i, qCoff);
232
233 iCoff = iCoff & 0x3f;
234 ath_print(common, ATH_DBG_CALIBRATE,
235 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
236 if (iqCorrNeg == 0x0)
237 iCoff = 0x40 - iCoff;
238
239 if (qCoff > 15)
240 qCoff = 15;
241 else if (qCoff <= -16)
242 qCoff = 16;
243
244 ath_print(common, ATH_DBG_CALIBRATE,
245 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
246 i, iCoff, qCoff);
247
248 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
249 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
250 iCoff);
251 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
252 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
253 qCoff);
254 ath_print(common, ATH_DBG_CALIBRATE,
255 "IQ Cal and Correction done for Chain %d\n",
256 i);
257 }
258 }
259
260 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
261 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
262}
263
264static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
265{
266 struct ath_common *common = ath9k_hw_common(ah);
267 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
268 u32 qGainMismatch, iGainMismatch, val, i;
269
270 for (i = 0; i < numChains; i++) {
271 iOddMeasOffset = ah->totalAdcIOddPhase[i];
272 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
273 qOddMeasOffset = ah->totalAdcQOddPhase[i];
274 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
275
276 ath_print(common, ATH_DBG_CALIBRATE,
277 "Starting ADC Gain Cal for Chain %d\n", i);
278
279 ath_print(common, ATH_DBG_CALIBRATE,
280 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
281 iOddMeasOffset);
282 ath_print(common, ATH_DBG_CALIBRATE,
283 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
284 iEvenMeasOffset);
285 ath_print(common, ATH_DBG_CALIBRATE,
286 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
287 qOddMeasOffset);
288 ath_print(common, ATH_DBG_CALIBRATE,
289 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
290 qEvenMeasOffset);
291
292 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
293 iGainMismatch =
294 ((iEvenMeasOffset * 32) /
295 iOddMeasOffset) & 0x3f;
296 qGainMismatch =
297 ((qOddMeasOffset * 32) /
298 qEvenMeasOffset) & 0x3f;
299
300 ath_print(common, ATH_DBG_CALIBRATE,
301 "Chn %d gain_mismatch_i = 0x%08x\n", i,
302 iGainMismatch);
303 ath_print(common, ATH_DBG_CALIBRATE,
304 "Chn %d gain_mismatch_q = 0x%08x\n", i,
305 qGainMismatch);
306
307 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
308 val &= 0xfffff000;
309 val |= (qGainMismatch) | (iGainMismatch << 6);
310 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
311
312 ath_print(common, ATH_DBG_CALIBRATE,
313 "ADC Gain Cal done for Chain %d\n", i);
314 }
315 }
316
317 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
318 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
319 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
320}
321
322static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
323{
324 struct ath_common *common = ath9k_hw_common(ah);
325 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
326 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
327 const struct ath9k_percal_data *calData =
328 ah->cal_list_curr->calData;
329 u32 numSamples =
330 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
331
332 for (i = 0; i < numChains; i++) {
333 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
334 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
335 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
336 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
337
338 ath_print(common, ATH_DBG_CALIBRATE,
339 "Starting ADC DC Offset Cal for Chain %d\n", i);
340
341 ath_print(common, ATH_DBG_CALIBRATE,
342 "Chn %d pwr_meas_odd_i = %d\n", i,
343 iOddMeasOffset);
344 ath_print(common, ATH_DBG_CALIBRATE,
345 "Chn %d pwr_meas_even_i = %d\n", i,
346 iEvenMeasOffset);
347 ath_print(common, ATH_DBG_CALIBRATE,
348 "Chn %d pwr_meas_odd_q = %d\n", i,
349 qOddMeasOffset);
350 ath_print(common, ATH_DBG_CALIBRATE,
351 "Chn %d pwr_meas_even_q = %d\n", i,
352 qEvenMeasOffset);
353
354 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
355 numSamples) & 0x1ff;
356 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
357 numSamples) & 0x1ff;
358
359 ath_print(common, ATH_DBG_CALIBRATE,
360 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
361 iDcMismatch);
362 ath_print(common, ATH_DBG_CALIBRATE,
363 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
364 qDcMismatch);
365
366 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
367 val &= 0xc0000fff;
368 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
369 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
370
371 ath_print(common, ATH_DBG_CALIBRATE,
372 "ADC DC Offset Cal done for Chain %d\n", i);
373 }
374
375 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
376 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
377 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
378}
379
380static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah)
381{
382 u32 rddata;
383 int32_t delta, currPDADC, slope;
384
385 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
386 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
387
388 if (ah->initPDADC == 0 || currPDADC == 0) {
389 /*
390 * Zero value indicates that no frames have been transmitted
391 * yet, can't do temperature compensation until frames are
392 * transmitted.
393 */
394 return;
395 } else {
396 slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
397
398 if (slope == 0) { /* to avoid divide by zero case */
399 delta = 0;
400 } else {
401 delta = ((currPDADC - ah->initPDADC)*4) / slope;
402 }
403 REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
404 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
405 REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
406 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
407 }
408}
409
410static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah)
411{
412 u32 rddata, i;
413 int delta, currPDADC, regval;
414
415 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
416 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
417
418 if (ah->initPDADC == 0 || currPDADC == 0)
419 return;
420
421 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
422 delta = (currPDADC - ah->initPDADC + 4) / 8;
423 else
424 delta = (currPDADC - ah->initPDADC + 5) / 10;
425
426 if (delta != ah->PDADCdelta) {
427 ah->PDADCdelta = delta;
428 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
429 regval = ah->originalGain[i] - delta;
430 if (regval < 0)
431 regval = 0;
432
433 REG_RMW_FIELD(ah,
434 AR_PHY_TX_GAIN_TBL1 + i * 4,
435 AR_PHY_TX_GAIN, regval);
436 }
437 }
438}
439
440static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
441{
442 u32 regVal;
443 unsigned int i;
444 u32 regList[][2] = {
445 { 0x786c, 0 },
446 { 0x7854, 0 },
447 { 0x7820, 0 },
448 { 0x7824, 0 },
449 { 0x7868, 0 },
450 { 0x783c, 0 },
451 { 0x7838, 0 } ,
452 { 0x7828, 0 } ,
453 };
454
455 for (i = 0; i < ARRAY_SIZE(regList); i++)
456 regList[i][1] = REG_READ(ah, regList[i][0]);
457
458 regVal = REG_READ(ah, 0x7834);
459 regVal &= (~(0x1));
460 REG_WRITE(ah, 0x7834, regVal);
461 regVal = REG_READ(ah, 0x9808);
462 regVal |= (0x1 << 27);
463 REG_WRITE(ah, 0x9808, regVal);
464
465 /* 786c,b23,1, pwddac=1 */
466 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
467 /* 7854, b5,1, pdrxtxbb=1 */
468 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
469 /* 7854, b7,1, pdv2i=1 */
470 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
471 /* 7854, b8,1, pddacinterface=1 */
472 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
473 /* 7824,b12,0, offcal=0 */
474 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
475 /* 7838, b1,0, pwddb=0 */
476 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
477 /* 7820,b11,0, enpacal=0 */
478 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
479 /* 7820,b25,1, pdpadrv1=0 */
480 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
481 /* 7820,b24,0, pdpadrv2=0 */
482 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
483 /* 7820,b23,0, pdpaout=0 */
484 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
485 /* 783c,b14-16,7, padrvgn2tab_0=7 */
486 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
487 /*
488 * 7838,b29-31,0, padrvgn1tab_0=0
489 * does not matter since we turn it off
490 */
491 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
492
493 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
494
495 /* Set:
496 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
497 * txon=1,paon=1,oscon=1,synthon_force=1
498 */
499 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
500 udelay(30);
501 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
502
503 /* find off_6_1; */
504 for (i = 6; i > 0; i--) {
505 regVal = REG_READ(ah, 0x7834);
506 regVal |= (1 << (20 + i));
507 REG_WRITE(ah, 0x7834, regVal);
508 udelay(1);
509 /* regVal = REG_READ(ah, 0x7834); */
510 regVal &= (~(0x1 << (20 + i)));
511 regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
512 << (20 + i));
513 REG_WRITE(ah, 0x7834, regVal);
514 }
515
516 regVal = (regVal >> 20) & 0x7f;
517
518 /* Update PA cal info */
519 if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
520 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
521 ah->pacal_info.max_skipcount =
522 2 * ah->pacal_info.max_skipcount;
523 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
524 } else {
525 ah->pacal_info.max_skipcount = 1;
526 ah->pacal_info.skipcount = 0;
527 ah->pacal_info.prev_offset = regVal;
528 }
529
530 ENABLE_REGWRITE_BUFFER(ah);
531
532 regVal = REG_READ(ah, 0x7834);
533 regVal |= 0x1;
534 REG_WRITE(ah, 0x7834, regVal);
535 regVal = REG_READ(ah, 0x9808);
536 regVal &= (~(0x1 << 27));
537 REG_WRITE(ah, 0x9808, regVal);
538
539 for (i = 0; i < ARRAY_SIZE(regList); i++)
540 REG_WRITE(ah, regList[i][0], regList[i][1]);
541
542 REGWRITE_BUFFER_FLUSH(ah);
543 DISABLE_REGWRITE_BUFFER(ah);
544}
545
546static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
547{
548 struct ath_common *common = ath9k_hw_common(ah);
549 u32 regVal;
550 int i, offset, offs_6_1, offs_0;
551 u32 ccomp_org, reg_field;
552 u32 regList[][2] = {
553 { 0x786c, 0 },
554 { 0x7854, 0 },
555 { 0x7820, 0 },
556 { 0x7824, 0 },
557 { 0x7868, 0 },
558 { 0x783c, 0 },
559 { 0x7838, 0 },
560 };
561
562 ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
563
564 /* PA CAL is not needed for high power solution */
565 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
566 AR5416_EEP_TXGAIN_HIGH_POWER)
567 return;
568
569 if (AR_SREV_9285_11(ah)) {
570 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
571 udelay(10);
572 }
573
574 for (i = 0; i < ARRAY_SIZE(regList); i++)
575 regList[i][1] = REG_READ(ah, regList[i][0]);
576
577 regVal = REG_READ(ah, 0x7834);
578 regVal &= (~(0x1));
579 REG_WRITE(ah, 0x7834, regVal);
580 regVal = REG_READ(ah, 0x9808);
581 regVal |= (0x1 << 27);
582 REG_WRITE(ah, 0x9808, regVal);
583
584 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
585 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
586 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
587 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
588 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
589 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
590 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
591 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
592 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
593 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
594 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
595 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
596 ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
597 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
598
599 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
600 udelay(30);
601 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
602 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
603
604 for (i = 6; i > 0; i--) {
605 regVal = REG_READ(ah, 0x7834);
606 regVal |= (1 << (19 + i));
607 REG_WRITE(ah, 0x7834, regVal);
608 udelay(1);
609 regVal = REG_READ(ah, 0x7834);
610 regVal &= (~(0x1 << (19 + i)));
611 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
612 regVal |= (reg_field << (19 + i));
613 REG_WRITE(ah, 0x7834, regVal);
614 }
615
616 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
617 udelay(1);
618 reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
619 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
620 offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
621 offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
622
623 offset = (offs_6_1<<1) | offs_0;
624 offset = offset - 0;
625 offs_6_1 = offset>>1;
626 offs_0 = offset & 1;
627
628 if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
629 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
630 ah->pacal_info.max_skipcount =
631 2 * ah->pacal_info.max_skipcount;
632 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
633 } else {
634 ah->pacal_info.max_skipcount = 1;
635 ah->pacal_info.skipcount = 0;
636 ah->pacal_info.prev_offset = offset;
637 }
638
639 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
640 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
641
642 regVal = REG_READ(ah, 0x7834);
643 regVal |= 0x1;
644 REG_WRITE(ah, 0x7834, regVal);
645 regVal = REG_READ(ah, 0x9808);
646 regVal &= (~(0x1 << 27));
647 REG_WRITE(ah, 0x9808, regVal);
648
649 for (i = 0; i < ARRAY_SIZE(regList); i++)
650 REG_WRITE(ah, regList[i][0], regList[i][1]);
651
652 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
653
654 if (AR_SREV_9285_11(ah))
655 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
656
657}
658
659static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset)
660{
661 if (AR_SREV_9271(ah)) {
662 if (is_reset || !ah->pacal_info.skipcount)
663 ar9271_hw_pa_cal(ah, is_reset);
664 else
665 ah->pacal_info.skipcount--;
666 } else if (AR_SREV_9285_11_OR_LATER(ah)) {
667 if (is_reset || !ah->pacal_info.skipcount)
668 ar9285_hw_pa_cal(ah, is_reset);
669 else
670 ah->pacal_info.skipcount--;
671 }
672}
673
674static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah)
675{
676 if (OLC_FOR_AR9287_10_LATER)
677 ar9287_hw_olc_temp_compensation(ah);
678 else if (OLC_FOR_AR9280_20_LATER)
679 ar9280_hw_olc_temp_compensation(ah);
680}
681
682static bool ar9002_hw_calibrate(struct ath_hw *ah,
683 struct ath9k_channel *chan,
684 u8 rxchainmask,
685 bool longcal)
686{
687 bool iscaldone = true;
688 struct ath9k_cal_list *currCal = ah->cal_list_curr;
689
690 if (currCal &&
691 (currCal->calState == CAL_RUNNING ||
692 currCal->calState == CAL_WAITING)) {
693 iscaldone = ar9002_hw_per_calibration(ah, chan,
694 rxchainmask, currCal);
695 if (iscaldone) {
696 ah->cal_list_curr = currCal = currCal->calNext;
697
698 if (currCal->calState == CAL_WAITING) {
699 iscaldone = false;
700 ath9k_hw_reset_calibration(ah, currCal);
701 }
702 }
703 }
704
705 /* Do NF cal only at longer intervals */
706 if (longcal) {
707 /* Do periodic PAOffset Cal */
708 ar9002_hw_pa_cal(ah, false);
709 ar9002_hw_olc_temp_compensation(ah);
710
711 /*
712 * Get the value from the previous NF cal and update
713 * history buffer.
714 */
715 ath9k_hw_getnf(ah, chan);
716
717 /*
718 * Load the NF from history buffer of the current channel.
719 * NF is slow time-variant, so it is OK to use a historical
720 * value.
721 */
722 ath9k_hw_loadnf(ah, ah->curchan);
723
724 ath9k_hw_start_nfcal(ah);
725 }
726
727 return iscaldone;
728}
729
730/* Carrier leakage Calibration fix */
731static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan)
732{
733 struct ath_common *common = ath9k_hw_common(ah);
734
735 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
736 if (IS_CHAN_HT20(chan)) {
737 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
738 REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
739 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
740 AR_PHY_AGC_CONTROL_FLTR_CAL);
741 REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
742 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
743 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
744 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
745 ath_print(common, ATH_DBG_CALIBRATE, "offset "
746 "calibration failed to complete in "
747 "1ms; noisy ??\n");
748 return false;
749 }
750 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
751 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
752 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
753 }
754 REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
755 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
756 REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
757 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
758 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
759 0, AH_WAIT_TIMEOUT)) {
760 ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
761 "failed to complete in 1ms; noisy ??\n");
762 return false;
763 }
764
765 REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
766 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
767 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
768
769 return true;
770}
771
772static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan)
773{
774 int i;
775 u_int32_t txgain_max;
776 u_int32_t clc_gain, gain_mask = 0, clc_num = 0;
777 u_int32_t reg_clc_I0, reg_clc_Q0;
778 u_int32_t i0_num = 0;
779 u_int32_t q0_num = 0;
780 u_int32_t total_num = 0;
781 u_int32_t reg_rf2g5_org;
782 bool retv = true;
783
784 if (!(ar9285_hw_cl_cal(ah, chan)))
785 return false;
786
787 txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7),
788 AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX);
789
790 for (i = 0; i < (txgain_max+1); i++) {
791 clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) &
792 AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S;
793 if (!(gain_mask & (1 << clc_gain))) {
794 gain_mask |= (1 << clc_gain);
795 clc_num++;
796 }
797 }
798
799 for (i = 0; i < clc_num; i++) {
800 reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
801 & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S;
802 reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2)))
803 & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S;
804 if (reg_clc_I0 == 0)
805 i0_num++;
806
807 if (reg_clc_Q0 == 0)
808 q0_num++;
809 }
810 total_num = i0_num + q0_num;
811 if (total_num > AR9285_CLCAL_REDO_THRESH) {
812 reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5);
813 if (AR_SREV_9285E_20(ah)) {
814 REG_WRITE(ah, AR9285_RF2G5,
815 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
816 AR9285_RF2G5_IC50TX_XE_SET);
817 } else {
818 REG_WRITE(ah, AR9285_RF2G5,
819 (reg_rf2g5_org & AR9285_RF2G5_IC50TX) |
820 AR9285_RF2G5_IC50TX_SET);
821 }
822 retv = ar9285_hw_cl_cal(ah, chan);
823 REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org);
824 }
825 return retv;
826}
827
828static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
829{
830 struct ath_common *common = ath9k_hw_common(ah);
831
832 if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
833 if (!ar9285_hw_clc(ah, chan))
834 return false;
835 } else {
836 if (AR_SREV_9280_10_OR_LATER(ah)) {
837 if (!AR_SREV_9287_10_OR_LATER(ah))
838 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
839 AR_PHY_ADC_CTL_OFF_PWDADC);
840 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
841 AR_PHY_AGC_CONTROL_FLTR_CAL);
842 }
843
844 /* Calibrate the AGC */
845 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
846 REG_READ(ah, AR_PHY_AGC_CONTROL) |
847 AR_PHY_AGC_CONTROL_CAL);
848
849 /* Poll for offset calibration complete */
850 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
851 AR_PHY_AGC_CONTROL_CAL,
852 0, AH_WAIT_TIMEOUT)) {
853 ath_print(common, ATH_DBG_CALIBRATE,
854 "offset calibration failed to "
855 "complete in 1ms; noisy environment?\n");
856 return false;
857 }
858
859 if (AR_SREV_9280_10_OR_LATER(ah)) {
860 if (!AR_SREV_9287_10_OR_LATER(ah))
861 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
862 AR_PHY_ADC_CTL_OFF_PWDADC);
863 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
864 AR_PHY_AGC_CONTROL_FLTR_CAL);
865 }
866 }
867
868 /* Do PA Calibration */
869 ar9002_hw_pa_cal(ah, true);
870
871 /* Do NF Calibration after DC offset and other calibrations */
872 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
873 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
874
875 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
876
877 /* Enable IQ, ADC Gain and ADC DC offset CALs */
878 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
879 if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
880 INIT_CAL(&ah->adcgain_caldata);
881 INSERT_CAL(ah, &ah->adcgain_caldata);
882 ath_print(common, ATH_DBG_CALIBRATE,
883 "enabling ADC Gain Calibration.\n");
884 }
885 if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
886 INIT_CAL(&ah->adcdc_caldata);
887 INSERT_CAL(ah, &ah->adcdc_caldata);
888 ath_print(common, ATH_DBG_CALIBRATE,
889 "enabling ADC DC Calibration.\n");
890 }
891 if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
892 INIT_CAL(&ah->iq_caldata);
893 INSERT_CAL(ah, &ah->iq_caldata);
894 ath_print(common, ATH_DBG_CALIBRATE,
895 "enabling IQ Calibration.\n");
896 }
897
898 ah->cal_list_curr = ah->cal_list;
899
900 if (ah->cal_list_curr)
901 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
902 }
903
904 chan->CalValid = 0;
905
906 return true;
907}
908
909static const struct ath9k_percal_data iq_cal_multi_sample = {
910 IQ_MISMATCH_CAL,
911 MAX_CAL_SAMPLES,
912 PER_MIN_LOG_COUNT,
913 ar9002_hw_iqcal_collect,
914 ar9002_hw_iqcalibrate
915};
916static const struct ath9k_percal_data iq_cal_single_sample = {
917 IQ_MISMATCH_CAL,
918 MIN_CAL_SAMPLES,
919 PER_MAX_LOG_COUNT,
920 ar9002_hw_iqcal_collect,
921 ar9002_hw_iqcalibrate
922};
923static const struct ath9k_percal_data adc_gain_cal_multi_sample = {
924 ADC_GAIN_CAL,
925 MAX_CAL_SAMPLES,
926 PER_MIN_LOG_COUNT,
927 ar9002_hw_adc_gaincal_collect,
928 ar9002_hw_adc_gaincal_calibrate
929};
930static const struct ath9k_percal_data adc_gain_cal_single_sample = {
931 ADC_GAIN_CAL,
932 MIN_CAL_SAMPLES,
933 PER_MAX_LOG_COUNT,
934 ar9002_hw_adc_gaincal_collect,
935 ar9002_hw_adc_gaincal_calibrate
936};
937static const struct ath9k_percal_data adc_dc_cal_multi_sample = {
938 ADC_DC_CAL,
939 MAX_CAL_SAMPLES,
940 PER_MIN_LOG_COUNT,
941 ar9002_hw_adc_dccal_collect,
942 ar9002_hw_adc_dccal_calibrate
943};
944static const struct ath9k_percal_data adc_dc_cal_single_sample = {
945 ADC_DC_CAL,
946 MIN_CAL_SAMPLES,
947 PER_MAX_LOG_COUNT,
948 ar9002_hw_adc_dccal_collect,
949 ar9002_hw_adc_dccal_calibrate
950};
951static const struct ath9k_percal_data adc_init_dc_cal = {
952 ADC_DC_INIT_CAL,
953 MIN_CAL_SAMPLES,
954 INIT_LOG_COUNT,
955 ar9002_hw_adc_dccal_collect,
956 ar9002_hw_adc_dccal_calibrate
957};
958
959static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
960{
961 if (AR_SREV_9100(ah)) {
962 ah->iq_caldata.calData = &iq_cal_multi_sample;
963 ah->supp_cals = IQ_MISMATCH_CAL;
964 return;
965 }
966
967 if (AR_SREV_9160_10_OR_LATER(ah)) {
968 if (AR_SREV_9280_10_OR_LATER(ah)) {
969 ah->iq_caldata.calData = &iq_cal_single_sample;
970 ah->adcgain_caldata.calData =
971 &adc_gain_cal_single_sample;
972 ah->adcdc_caldata.calData =
973 &adc_dc_cal_single_sample;
974 ah->adcdc_calinitdata.calData =
975 &adc_init_dc_cal;
976 } else {
977 ah->iq_caldata.calData = &iq_cal_multi_sample;
978 ah->adcgain_caldata.calData =
979 &adc_gain_cal_multi_sample;
980 ah->adcdc_caldata.calData =
981 &adc_dc_cal_multi_sample;
982 ah->adcdc_calinitdata.calData =
983 &adc_init_dc_cal;
984 }
985 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
986 }
987}
988
989void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
990{
991 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
992 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
993
994 priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
995 priv_ops->init_cal = ar9002_hw_init_cal;
996 priv_ops->setup_calibration = ar9002_hw_setup_calibration;
997 priv_ops->iscal_supported = ar9002_hw_iscal_supported;
998
999 ops->calibrate = ar9002_hw_calibrate;
1000}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
new file mode 100644
index 000000000000..a8a8cdc04afa
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -0,0 +1,598 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar5008_initvals.h"
19#include "ar9001_initvals.h"
20#include "ar9002_initvals.h"
21
22/* General hardware code for the A5008/AR9001/AR9002 hadware families */
23
24static bool ar9002_hw_macversion_supported(u32 macversion)
25{
26 switch (macversion) {
27 case AR_SREV_VERSION_5416_PCI:
28 case AR_SREV_VERSION_5416_PCIE:
29 case AR_SREV_VERSION_9160:
30 case AR_SREV_VERSION_9100:
31 case AR_SREV_VERSION_9280:
32 case AR_SREV_VERSION_9285:
33 case AR_SREV_VERSION_9287:
34 case AR_SREV_VERSION_9271:
35 return true;
36 default:
37 break;
38 }
39 return false;
40}
41
42static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
43{
44 if (AR_SREV_9271(ah)) {
45 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
46 ARRAY_SIZE(ar9271Modes_9271), 6);
47 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
48 ARRAY_SIZE(ar9271Common_9271), 2);
49 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
50 ar9271Common_normal_cck_fir_coeff_9271,
51 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
52 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
53 ar9271Common_japan_2484_cck_fir_coeff_9271,
54 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
55 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
56 ar9271Modes_9271_1_0_only,
57 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
58 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
59 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
60 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
61 ar9271Modes_high_power_tx_gain_9271,
62 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
63 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
64 ar9271Modes_normal_power_tx_gain_9271,
65 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
66 return;
67 }
68
69 if (AR_SREV_9287_11_OR_LATER(ah)) {
70 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
71 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
72 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
73 ARRAY_SIZE(ar9287Common_9287_1_1), 2);
74 if (ah->config.pcie_clock_req)
75 INIT_INI_ARRAY(&ah->iniPcieSerdes,
76 ar9287PciePhy_clkreq_off_L1_9287_1_1,
77 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
78 else
79 INIT_INI_ARRAY(&ah->iniPcieSerdes,
80 ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
81 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
82 2);
83 } else if (AR_SREV_9287_10_OR_LATER(ah)) {
84 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
85 ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
86 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
87 ARRAY_SIZE(ar9287Common_9287_1_0), 2);
88
89 if (ah->config.pcie_clock_req)
90 INIT_INI_ARRAY(&ah->iniPcieSerdes,
91 ar9287PciePhy_clkreq_off_L1_9287_1_0,
92 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
93 else
94 INIT_INI_ARRAY(&ah->iniPcieSerdes,
95 ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
96 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
97 2);
98 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
99
100
101 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
102 ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
103 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
104 ARRAY_SIZE(ar9285Common_9285_1_2), 2);
105
106 if (ah->config.pcie_clock_req) {
107 INIT_INI_ARRAY(&ah->iniPcieSerdes,
108 ar9285PciePhy_clkreq_off_L1_9285_1_2,
109 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
110 } else {
111 INIT_INI_ARRAY(&ah->iniPcieSerdes,
112 ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
113 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
114 2);
115 }
116 } else if (AR_SREV_9285_10_OR_LATER(ah)) {
117 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
118 ARRAY_SIZE(ar9285Modes_9285), 6);
119 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
120 ARRAY_SIZE(ar9285Common_9285), 2);
121
122 if (ah->config.pcie_clock_req) {
123 INIT_INI_ARRAY(&ah->iniPcieSerdes,
124 ar9285PciePhy_clkreq_off_L1_9285,
125 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
126 } else {
127 INIT_INI_ARRAY(&ah->iniPcieSerdes,
128 ar9285PciePhy_clkreq_always_on_L1_9285,
129 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
130 }
131 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
132 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
133 ARRAY_SIZE(ar9280Modes_9280_2), 6);
134 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
135 ARRAY_SIZE(ar9280Common_9280_2), 2);
136
137 if (ah->config.pcie_clock_req) {
138 INIT_INI_ARRAY(&ah->iniPcieSerdes,
139 ar9280PciePhy_clkreq_off_L1_9280,
140 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
141 } else {
142 INIT_INI_ARRAY(&ah->iniPcieSerdes,
143 ar9280PciePhy_clkreq_always_on_L1_9280,
144 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
145 }
146 INIT_INI_ARRAY(&ah->iniModesAdditional,
147 ar9280Modes_fast_clock_9280_2,
148 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
149 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
150 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
151 ARRAY_SIZE(ar9280Modes_9280), 6);
152 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
153 ARRAY_SIZE(ar9280Common_9280), 2);
154 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
155 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
156 ARRAY_SIZE(ar5416Modes_9160), 6);
157 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
158 ARRAY_SIZE(ar5416Common_9160), 2);
159 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
160 ARRAY_SIZE(ar5416Bank0_9160), 2);
161 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
162 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
163 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
164 ARRAY_SIZE(ar5416Bank1_9160), 2);
165 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
166 ARRAY_SIZE(ar5416Bank2_9160), 2);
167 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
168 ARRAY_SIZE(ar5416Bank3_9160), 3);
169 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
170 ARRAY_SIZE(ar5416Bank6_9160), 3);
171 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
172 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
173 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
174 ARRAY_SIZE(ar5416Bank7_9160), 2);
175 if (AR_SREV_9160_11(ah)) {
176 INIT_INI_ARRAY(&ah->iniAddac,
177 ar5416Addac_91601_1,
178 ARRAY_SIZE(ar5416Addac_91601_1), 2);
179 } else {
180 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
181 ARRAY_SIZE(ar5416Addac_9160), 2);
182 }
183 } else if (AR_SREV_9100_OR_LATER(ah)) {
184 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
185 ARRAY_SIZE(ar5416Modes_9100), 6);
186 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
187 ARRAY_SIZE(ar5416Common_9100), 2);
188 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
189 ARRAY_SIZE(ar5416Bank0_9100), 2);
190 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
191 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
192 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
193 ARRAY_SIZE(ar5416Bank1_9100), 2);
194 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
195 ARRAY_SIZE(ar5416Bank2_9100), 2);
196 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
197 ARRAY_SIZE(ar5416Bank3_9100), 3);
198 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
199 ARRAY_SIZE(ar5416Bank6_9100), 3);
200 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
201 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
202 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
203 ARRAY_SIZE(ar5416Bank7_9100), 2);
204 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
205 ARRAY_SIZE(ar5416Addac_9100), 2);
206 } else {
207 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
208 ARRAY_SIZE(ar5416Modes), 6);
209 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
210 ARRAY_SIZE(ar5416Common), 2);
211 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
212 ARRAY_SIZE(ar5416Bank0), 2);
213 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
214 ARRAY_SIZE(ar5416BB_RfGain), 3);
215 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
216 ARRAY_SIZE(ar5416Bank1), 2);
217 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
218 ARRAY_SIZE(ar5416Bank2), 2);
219 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
220 ARRAY_SIZE(ar5416Bank3), 3);
221 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
222 ARRAY_SIZE(ar5416Bank6), 3);
223 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
224 ARRAY_SIZE(ar5416Bank6TPC), 3);
225 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
226 ARRAY_SIZE(ar5416Bank7), 2);
227 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
228 ARRAY_SIZE(ar5416Addac), 2);
229 }
230}
231
232/* Support for Japan ch.14 (2484) spread */
233void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
234{
235 if (AR_SREV_9287_11_OR_LATER(ah)) {
236 INIT_INI_ARRAY(&ah->iniCckfirNormal,
237 ar9287Common_normal_cck_fir_coeff_92871_1,
238 ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1),
239 2);
240 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
241 ar9287Common_japan_2484_cck_fir_coeff_92871_1,
242 ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1),
243 2);
244 }
245}
246
247static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
248{
249 u32 rxgain_type;
250
251 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
252 AR5416_EEP_MINOR_VER_17) {
253 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
254
255 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
256 INIT_INI_ARRAY(&ah->iniModesRxGain,
257 ar9280Modes_backoff_13db_rxgain_9280_2,
258 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
259 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
260 INIT_INI_ARRAY(&ah->iniModesRxGain,
261 ar9280Modes_backoff_23db_rxgain_9280_2,
262 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
263 else
264 INIT_INI_ARRAY(&ah->iniModesRxGain,
265 ar9280Modes_original_rxgain_9280_2,
266 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
267 } else {
268 INIT_INI_ARRAY(&ah->iniModesRxGain,
269 ar9280Modes_original_rxgain_9280_2,
270 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
271 }
272}
273
274static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
275{
276 u32 txgain_type;
277
278 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
279 AR5416_EEP_MINOR_VER_19) {
280 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
281
282 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
283 INIT_INI_ARRAY(&ah->iniModesTxGain,
284 ar9280Modes_high_power_tx_gain_9280_2,
285 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
286 else
287 INIT_INI_ARRAY(&ah->iniModesTxGain,
288 ar9280Modes_original_tx_gain_9280_2,
289 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
290 } else {
291 INIT_INI_ARRAY(&ah->iniModesTxGain,
292 ar9280Modes_original_tx_gain_9280_2,
293 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
294 }
295}
296
297static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
298{
299 if (AR_SREV_9287_11_OR_LATER(ah))
300 INIT_INI_ARRAY(&ah->iniModesRxGain,
301 ar9287Modes_rx_gain_9287_1_1,
302 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
303 else if (AR_SREV_9287_10(ah))
304 INIT_INI_ARRAY(&ah->iniModesRxGain,
305 ar9287Modes_rx_gain_9287_1_0,
306 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
307 else if (AR_SREV_9280_20(ah))
308 ar9280_20_hw_init_rxgain_ini(ah);
309
310 if (AR_SREV_9287_11_OR_LATER(ah)) {
311 INIT_INI_ARRAY(&ah->iniModesTxGain,
312 ar9287Modes_tx_gain_9287_1_1,
313 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
314 } else if (AR_SREV_9287_10(ah)) {
315 INIT_INI_ARRAY(&ah->iniModesTxGain,
316 ar9287Modes_tx_gain_9287_1_0,
317 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
318 } else if (AR_SREV_9280_20(ah)) {
319 ar9280_20_hw_init_txgain_ini(ah);
320 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
321 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
322
323 /* txgain table */
324 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
325 if (AR_SREV_9285E_20(ah)) {
326 INIT_INI_ARRAY(&ah->iniModesTxGain,
327 ar9285Modes_XE2_0_high_power,
328 ARRAY_SIZE(
329 ar9285Modes_XE2_0_high_power), 6);
330 } else {
331 INIT_INI_ARRAY(&ah->iniModesTxGain,
332 ar9285Modes_high_power_tx_gain_9285_1_2,
333 ARRAY_SIZE(
334 ar9285Modes_high_power_tx_gain_9285_1_2), 6);
335 }
336 } else {
337 if (AR_SREV_9285E_20(ah)) {
338 INIT_INI_ARRAY(&ah->iniModesTxGain,
339 ar9285Modes_XE2_0_normal_power,
340 ARRAY_SIZE(
341 ar9285Modes_XE2_0_normal_power), 6);
342 } else {
343 INIT_INI_ARRAY(&ah->iniModesTxGain,
344 ar9285Modes_original_tx_gain_9285_1_2,
345 ARRAY_SIZE(
346 ar9285Modes_original_tx_gain_9285_1_2), 6);
347 }
348 }
349 }
350}
351
352/*
353 * Helper for ASPM support.
354 *
355 * Disable PLL when in L0s as well as receiver clock when in L1.
356 * This power saving option must be enabled through the SerDes.
357 *
358 * Programming the SerDes must go through the same 288 bit serial shift
359 * register as the other analog registers. Hence the 9 writes.
360 */
361static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
362 int restore,
363 int power_off)
364{
365 u8 i;
366 u32 val;
367
368 if (ah->is_pciexpress != true)
369 return;
370
371 /* Do not touch SerDes registers */
372 if (ah->config.pcie_powersave_enable == 2)
373 return;
374
375 /* Nothing to do on restore for 11N */
376 if (!restore) {
377 if (AR_SREV_9280_20_OR_LATER(ah)) {
378 /*
379 * AR9280 2.0 or later chips use SerDes values from the
380 * initvals.h initialized depending on chipset during
381 * __ath9k_hw_init()
382 */
383 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
384 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
385 INI_RA(&ah->iniPcieSerdes, i, 1));
386 }
387 } else if (AR_SREV_9280(ah) &&
388 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
389 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
390 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
391
392 /* RX shut off when elecidle is asserted */
393 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
394 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
395 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
396
397 /* Shut off CLKREQ active in L1 */
398 if (ah->config.pcie_clock_req)
399 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
400 else
401 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
402
403 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
404 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
405 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
406
407 /* Load the new settings */
408 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
409
410 } else {
411 ENABLE_REGWRITE_BUFFER(ah);
412
413 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
414 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
415
416 /* RX shut off when elecidle is asserted */
417 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
418 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
419 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
420
421 /*
422 * Ignore ah->ah_config.pcie_clock_req setting for
423 * pre-AR9280 11n
424 */
425 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
426
427 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
428 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
429 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
430
431 /* Load the new settings */
432 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
433
434 REGWRITE_BUFFER_FLUSH(ah);
435 DISABLE_REGWRITE_BUFFER(ah);
436 }
437
438 udelay(1000);
439
440 /* set bit 19 to allow forcing of pcie core into L1 state */
441 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
442
443 /* Several PCIe massages to ensure proper behaviour */
444 if (ah->config.pcie_waen) {
445 val = ah->config.pcie_waen;
446 if (!power_off)
447 val &= (~AR_WA_D3_L1_DISABLE);
448 } else {
449 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
450 AR_SREV_9287(ah)) {
451 val = AR9285_WA_DEFAULT;
452 if (!power_off)
453 val &= (~AR_WA_D3_L1_DISABLE);
454 } else if (AR_SREV_9280(ah)) {
455 /*
456 * On AR9280 chips bit 22 of 0x4004 needs to be
457 * set otherwise card may disappear.
458 */
459 val = AR9280_WA_DEFAULT;
460 if (!power_off)
461 val &= (~AR_WA_D3_L1_DISABLE);
462 } else
463 val = AR_WA_DEFAULT;
464 }
465
466 REG_WRITE(ah, AR_WA, val);
467 }
468
469 if (power_off) {
470 /*
471 * Set PCIe workaround bits
472 * bit 14 in WA register (disable L1) should only
473 * be set when device enters D3 and be cleared
474 * when device comes back to D0.
475 */
476 if (ah->config.pcie_waen) {
477 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
478 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
479 } else {
480 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
481 AR_SREV_9287(ah)) &&
482 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
483 (AR_SREV_9280(ah) &&
484 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
485 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
486 }
487 }
488 }
489}
490
491static int ar9002_hw_get_radiorev(struct ath_hw *ah)
492{
493 u32 val;
494 int i;
495
496 ENABLE_REGWRITE_BUFFER(ah);
497
498 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
499 for (i = 0; i < 8; i++)
500 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
501
502 REGWRITE_BUFFER_FLUSH(ah);
503 DISABLE_REGWRITE_BUFFER(ah);
504
505 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
506 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
507
508 return ath9k_hw_reverse_bits(val, 8);
509}
510
511int ar9002_hw_rf_claim(struct ath_hw *ah)
512{
513 u32 val;
514
515 REG_WRITE(ah, AR_PHY(0), 0x00000007);
516
517 val = ar9002_hw_get_radiorev(ah);
518 switch (val & AR_RADIO_SREV_MAJOR) {
519 case 0:
520 val = AR_RAD5133_SREV_MAJOR;
521 break;
522 case AR_RAD5133_SREV_MAJOR:
523 case AR_RAD5122_SREV_MAJOR:
524 case AR_RAD2133_SREV_MAJOR:
525 case AR_RAD2122_SREV_MAJOR:
526 break;
527 default:
528 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
529 "Radio Chip Rev 0x%02X not supported\n",
530 val & AR_RADIO_SREV_MAJOR);
531 return -EOPNOTSUPP;
532 }
533
534 ah->hw_version.analog5GhzRev = val;
535
536 return 0;
537}
538
539/*
540 * Enable ASYNC FIFO
541 *
542 * If Async FIFO is enabled, the following counters change as MAC now runs
543 * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
544 *
545 * The values below tested for ht40 2 chain.
546 * Overwrite the delay/timeouts initialized in process ini.
547 */
548void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
549{
550 if (AR_SREV_9287_12_OR_LATER(ah)) {
551 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
552 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
553 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
554 AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
555 REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
556 AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
557
558 REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
559 REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
560
561 REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
562 AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
563 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
564 AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
565 }
566}
567
568/*
569 * We don't enable WEP aggregation on mac80211 but we keep this
570 * around for HAL unification purposes.
571 */
572void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
573{
574 if (AR_SREV_9287_12_OR_LATER(ah)) {
575 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
576 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
577 }
578}
579
580/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
581void ar9002_hw_attach_ops(struct ath_hw *ah)
582{
583 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
584 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
585
586 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
587 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
588 priv_ops->macversion_supported = ar9002_hw_macversion_supported;
589
590 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
591
592 ar5008_hw_attach_phy_ops(ah);
593 if (AR_SREV_9280_10_OR_LATER(ah))
594 ar9002_hw_attach_phy_ops(ah);
595
596 ar9002_hw_attach_calib_ops(ah);
597 ar9002_hw_attach_mac_ops(ah);
598}
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index 8a3bf3ab998d..dae7f3304eb8 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2010 Atheros Communications 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,1982 +14,9 @@
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
17static const u32 ar5416Modes[][6] = { 17#ifndef INITVALS_9002_10_H
18 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 18#define INITVALS_9002_10_H
19 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
20 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
21 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
22 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
23 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
24 { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
25 { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
26 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
27 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
28 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
29 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
30 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
31 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
32 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
33 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
34 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
35 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
36 { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
37 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
38 { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
39 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
40 { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
41 { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
42 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
43 { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
44 { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
45 { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
46 { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
47 { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
48 { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
49 { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
50 { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
51 { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
52 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
53 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
54 { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
55 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
56 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
57 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
58 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
59 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
60 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
61 { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
62 { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
63 { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
64 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
65 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
66 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
67 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
68 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
69 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
70 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
71 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
72 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
73 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
74 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
75 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
76 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
77 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
78 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
79 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
80 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
81};
82
83static const u32 ar5416Common[][2] = {
84 { 0x0000000c, 0x00000000 },
85 { 0x00000030, 0x00020015 },
86 { 0x00000034, 0x00000005 },
87 { 0x00000040, 0x00000000 },
88 { 0x00000044, 0x00000008 },
89 { 0x00000048, 0x00000008 },
90 { 0x0000004c, 0x00000010 },
91 { 0x00000050, 0x00000000 },
92 { 0x00000054, 0x0000001f },
93 { 0x00000800, 0x00000000 },
94 { 0x00000804, 0x00000000 },
95 { 0x00000808, 0x00000000 },
96 { 0x0000080c, 0x00000000 },
97 { 0x00000810, 0x00000000 },
98 { 0x00000814, 0x00000000 },
99 { 0x00000818, 0x00000000 },
100 { 0x0000081c, 0x00000000 },
101 { 0x00000820, 0x00000000 },
102 { 0x00000824, 0x00000000 },
103 { 0x00001040, 0x002ffc0f },
104 { 0x00001044, 0x002ffc0f },
105 { 0x00001048, 0x002ffc0f },
106 { 0x0000104c, 0x002ffc0f },
107 { 0x00001050, 0x002ffc0f },
108 { 0x00001054, 0x002ffc0f },
109 { 0x00001058, 0x002ffc0f },
110 { 0x0000105c, 0x002ffc0f },
111 { 0x00001060, 0x002ffc0f },
112 { 0x00001064, 0x002ffc0f },
113 { 0x00001230, 0x00000000 },
114 { 0x00001270, 0x00000000 },
115 { 0x00001038, 0x00000000 },
116 { 0x00001078, 0x00000000 },
117 { 0x000010b8, 0x00000000 },
118 { 0x000010f8, 0x00000000 },
119 { 0x00001138, 0x00000000 },
120 { 0x00001178, 0x00000000 },
121 { 0x000011b8, 0x00000000 },
122 { 0x000011f8, 0x00000000 },
123 { 0x00001238, 0x00000000 },
124 { 0x00001278, 0x00000000 },
125 { 0x000012b8, 0x00000000 },
126 { 0x000012f8, 0x00000000 },
127 { 0x00001338, 0x00000000 },
128 { 0x00001378, 0x00000000 },
129 { 0x000013b8, 0x00000000 },
130 { 0x000013f8, 0x00000000 },
131 { 0x00001438, 0x00000000 },
132 { 0x00001478, 0x00000000 },
133 { 0x000014b8, 0x00000000 },
134 { 0x000014f8, 0x00000000 },
135 { 0x00001538, 0x00000000 },
136 { 0x00001578, 0x00000000 },
137 { 0x000015b8, 0x00000000 },
138 { 0x000015f8, 0x00000000 },
139 { 0x00001638, 0x00000000 },
140 { 0x00001678, 0x00000000 },
141 { 0x000016b8, 0x00000000 },
142 { 0x000016f8, 0x00000000 },
143 { 0x00001738, 0x00000000 },
144 { 0x00001778, 0x00000000 },
145 { 0x000017b8, 0x00000000 },
146 { 0x000017f8, 0x00000000 },
147 { 0x0000103c, 0x00000000 },
148 { 0x0000107c, 0x00000000 },
149 { 0x000010bc, 0x00000000 },
150 { 0x000010fc, 0x00000000 },
151 { 0x0000113c, 0x00000000 },
152 { 0x0000117c, 0x00000000 },
153 { 0x000011bc, 0x00000000 },
154 { 0x000011fc, 0x00000000 },
155 { 0x0000123c, 0x00000000 },
156 { 0x0000127c, 0x00000000 },
157 { 0x000012bc, 0x00000000 },
158 { 0x000012fc, 0x00000000 },
159 { 0x0000133c, 0x00000000 },
160 { 0x0000137c, 0x00000000 },
161 { 0x000013bc, 0x00000000 },
162 { 0x000013fc, 0x00000000 },
163 { 0x0000143c, 0x00000000 },
164 { 0x0000147c, 0x00000000 },
165 { 0x00004030, 0x00000002 },
166 { 0x0000403c, 0x00000002 },
167 { 0x00007010, 0x00000000 },
168 { 0x00007038, 0x000004c2 },
169 { 0x00008004, 0x00000000 },
170 { 0x00008008, 0x00000000 },
171 { 0x0000800c, 0x00000000 },
172 { 0x00008018, 0x00000700 },
173 { 0x00008020, 0x00000000 },
174 { 0x00008038, 0x00000000 },
175 { 0x0000803c, 0x00000000 },
176 { 0x00008048, 0x40000000 },
177 { 0x00008054, 0x00000000 },
178 { 0x00008058, 0x00000000 },
179 { 0x0000805c, 0x000fc78f },
180 { 0x00008060, 0x0000000f },
181 { 0x00008064, 0x00000000 },
182 { 0x000080c0, 0x2a82301a },
183 { 0x000080c4, 0x05dc01e0 },
184 { 0x000080c8, 0x1f402710 },
185 { 0x000080cc, 0x01f40000 },
186 { 0x000080d0, 0x00001e00 },
187 { 0x000080d4, 0x00000000 },
188 { 0x000080d8, 0x00400000 },
189 { 0x000080e0, 0xffffffff },
190 { 0x000080e4, 0x0000ffff },
191 { 0x000080e8, 0x003f3f3f },
192 { 0x000080ec, 0x00000000 },
193 { 0x000080f0, 0x00000000 },
194 { 0x000080f4, 0x00000000 },
195 { 0x000080f8, 0x00000000 },
196 { 0x000080fc, 0x00020000 },
197 { 0x00008100, 0x00020000 },
198 { 0x00008104, 0x00000001 },
199 { 0x00008108, 0x00000052 },
200 { 0x0000810c, 0x00000000 },
201 { 0x00008110, 0x00000168 },
202 { 0x00008118, 0x000100aa },
203 { 0x0000811c, 0x00003210 },
204 { 0x00008124, 0x00000000 },
205 { 0x00008128, 0x00000000 },
206 { 0x0000812c, 0x00000000 },
207 { 0x00008130, 0x00000000 },
208 { 0x00008134, 0x00000000 },
209 { 0x00008138, 0x00000000 },
210 { 0x0000813c, 0x00000000 },
211 { 0x00008144, 0xffffffff },
212 { 0x00008168, 0x00000000 },
213 { 0x0000816c, 0x00000000 },
214 { 0x00008170, 0x32143320 },
215 { 0x00008174, 0xfaa4fa50 },
216 { 0x00008178, 0x00000100 },
217 { 0x0000817c, 0x00000000 },
218 { 0x000081c4, 0x00000000 },
219 { 0x000081ec, 0x00000000 },
220 { 0x000081f0, 0x00000000 },
221 { 0x000081f4, 0x00000000 },
222 { 0x000081f8, 0x00000000 },
223 { 0x000081fc, 0x00000000 },
224 { 0x00008200, 0x00000000 },
225 { 0x00008204, 0x00000000 },
226 { 0x00008208, 0x00000000 },
227 { 0x0000820c, 0x00000000 },
228 { 0x00008210, 0x00000000 },
229 { 0x00008214, 0x00000000 },
230 { 0x00008218, 0x00000000 },
231 { 0x0000821c, 0x00000000 },
232 { 0x00008220, 0x00000000 },
233 { 0x00008224, 0x00000000 },
234 { 0x00008228, 0x00000000 },
235 { 0x0000822c, 0x00000000 },
236 { 0x00008230, 0x00000000 },
237 { 0x00008234, 0x00000000 },
238 { 0x00008238, 0x00000000 },
239 { 0x0000823c, 0x00000000 },
240 { 0x00008240, 0x00100000 },
241 { 0x00008244, 0x0010f400 },
242 { 0x00008248, 0x00000100 },
243 { 0x0000824c, 0x0001e800 },
244 { 0x00008250, 0x00000000 },
245 { 0x00008254, 0x00000000 },
246 { 0x00008258, 0x00000000 },
247 { 0x0000825c, 0x400000ff },
248 { 0x00008260, 0x00080922 },
249 { 0x00008264, 0xa8000010 },
250 { 0x00008270, 0x00000000 },
251 { 0x00008274, 0x40000000 },
252 { 0x00008278, 0x003e4180 },
253 { 0x0000827c, 0x00000000 },
254 { 0x00008284, 0x0000002c },
255 { 0x00008288, 0x0000002c },
256 { 0x0000828c, 0x00000000 },
257 { 0x00008294, 0x00000000 },
258 { 0x00008298, 0x00000000 },
259 { 0x00008300, 0x00000000 },
260 { 0x00008304, 0x00000000 },
261 { 0x00008308, 0x00000000 },
262 { 0x0000830c, 0x00000000 },
263 { 0x00008310, 0x00000000 },
264 { 0x00008314, 0x00000000 },
265 { 0x00008318, 0x00000000 },
266 { 0x00008328, 0x00000000 },
267 { 0x0000832c, 0x00000007 },
268 { 0x00008330, 0x00000302 },
269 { 0x00008334, 0x00000e00 },
270 { 0x00008338, 0x00070000 },
271 { 0x0000833c, 0x00000000 },
272 { 0x00008340, 0x000107ff },
273 { 0x00009808, 0x00000000 },
274 { 0x0000980c, 0xad848e19 },
275 { 0x00009810, 0x7d14e000 },
276 { 0x00009814, 0x9c0a9f6b },
277 { 0x0000981c, 0x00000000 },
278 { 0x0000982c, 0x0000a000 },
279 { 0x00009830, 0x00000000 },
280 { 0x0000983c, 0x00200400 },
281 { 0x00009840, 0x206a002e },
282 { 0x0000984c, 0x1284233c },
283 { 0x00009854, 0x00000859 },
284 { 0x00009900, 0x00000000 },
285 { 0x00009904, 0x00000000 },
286 { 0x00009908, 0x00000000 },
287 { 0x0000990c, 0x00000000 },
288 { 0x0000991c, 0x10000fff },
289 { 0x00009920, 0x05100000 },
290 { 0x0000a920, 0x05100000 },
291 { 0x0000b920, 0x05100000 },
292 { 0x00009928, 0x00000001 },
293 { 0x0000992c, 0x00000004 },
294 { 0x00009934, 0x1e1f2022 },
295 { 0x00009938, 0x0a0b0c0d },
296 { 0x0000993c, 0x00000000 },
297 { 0x00009948, 0x9280b212 },
298 { 0x0000994c, 0x00020028 },
299 { 0x00009954, 0x5d50e188 },
300 { 0x00009958, 0x00081fff },
301 { 0x0000c95c, 0x004b6a8e },
302 { 0x0000c968, 0x000003ce },
303 { 0x00009970, 0x190fb515 },
304 { 0x00009974, 0x00000000 },
305 { 0x00009978, 0x00000001 },
306 { 0x0000997c, 0x00000000 },
307 { 0x00009980, 0x00000000 },
308 { 0x00009984, 0x00000000 },
309 { 0x00009988, 0x00000000 },
310 { 0x0000998c, 0x00000000 },
311 { 0x00009990, 0x00000000 },
312 { 0x00009994, 0x00000000 },
313 { 0x00009998, 0x00000000 },
314 { 0x0000999c, 0x00000000 },
315 { 0x000099a0, 0x00000000 },
316 { 0x000099a4, 0x00000001 },
317 { 0x000099a8, 0x001fff00 },
318 { 0x000099ac, 0x00000000 },
319 { 0x000099b0, 0x03051000 },
320 { 0x000099dc, 0x00000000 },
321 { 0x000099e0, 0x00000200 },
322 { 0x000099e4, 0xaaaaaaaa },
323 { 0x000099e8, 0x3c466478 },
324 { 0x000099ec, 0x000000aa },
325 { 0x000099fc, 0x00001042 },
326 { 0x00009b00, 0x00000000 },
327 { 0x00009b04, 0x00000001 },
328 { 0x00009b08, 0x00000002 },
329 { 0x00009b0c, 0x00000003 },
330 { 0x00009b10, 0x00000004 },
331 { 0x00009b14, 0x00000005 },
332 { 0x00009b18, 0x00000008 },
333 { 0x00009b1c, 0x00000009 },
334 { 0x00009b20, 0x0000000a },
335 { 0x00009b24, 0x0000000b },
336 { 0x00009b28, 0x0000000c },
337 { 0x00009b2c, 0x0000000d },
338 { 0x00009b30, 0x00000010 },
339 { 0x00009b34, 0x00000011 },
340 { 0x00009b38, 0x00000012 },
341 { 0x00009b3c, 0x00000013 },
342 { 0x00009b40, 0x00000014 },
343 { 0x00009b44, 0x00000015 },
344 { 0x00009b48, 0x00000018 },
345 { 0x00009b4c, 0x00000019 },
346 { 0x00009b50, 0x0000001a },
347 { 0x00009b54, 0x0000001b },
348 { 0x00009b58, 0x0000001c },
349 { 0x00009b5c, 0x0000001d },
350 { 0x00009b60, 0x00000020 },
351 { 0x00009b64, 0x00000021 },
352 { 0x00009b68, 0x00000022 },
353 { 0x00009b6c, 0x00000023 },
354 { 0x00009b70, 0x00000024 },
355 { 0x00009b74, 0x00000025 },
356 { 0x00009b78, 0x00000028 },
357 { 0x00009b7c, 0x00000029 },
358 { 0x00009b80, 0x0000002a },
359 { 0x00009b84, 0x0000002b },
360 { 0x00009b88, 0x0000002c },
361 { 0x00009b8c, 0x0000002d },
362 { 0x00009b90, 0x00000030 },
363 { 0x00009b94, 0x00000031 },
364 { 0x00009b98, 0x00000032 },
365 { 0x00009b9c, 0x00000033 },
366 { 0x00009ba0, 0x00000034 },
367 { 0x00009ba4, 0x00000035 },
368 { 0x00009ba8, 0x00000035 },
369 { 0x00009bac, 0x00000035 },
370 { 0x00009bb0, 0x00000035 },
371 { 0x00009bb4, 0x00000035 },
372 { 0x00009bb8, 0x00000035 },
373 { 0x00009bbc, 0x00000035 },
374 { 0x00009bc0, 0x00000035 },
375 { 0x00009bc4, 0x00000035 },
376 { 0x00009bc8, 0x00000035 },
377 { 0x00009bcc, 0x00000035 },
378 { 0x00009bd0, 0x00000035 },
379 { 0x00009bd4, 0x00000035 },
380 { 0x00009bd8, 0x00000035 },
381 { 0x00009bdc, 0x00000035 },
382 { 0x00009be0, 0x00000035 },
383 { 0x00009be4, 0x00000035 },
384 { 0x00009be8, 0x00000035 },
385 { 0x00009bec, 0x00000035 },
386 { 0x00009bf0, 0x00000035 },
387 { 0x00009bf4, 0x00000035 },
388 { 0x00009bf8, 0x00000010 },
389 { 0x00009bfc, 0x0000001a },
390 { 0x0000a210, 0x40806333 },
391 { 0x0000a214, 0x00106c10 },
392 { 0x0000a218, 0x009c4060 },
393 { 0x0000a220, 0x018830c6 },
394 { 0x0000a224, 0x00000400 },
395 { 0x0000a228, 0x00000bb5 },
396 { 0x0000a22c, 0x00000011 },
397 { 0x0000a234, 0x20202020 },
398 { 0x0000a238, 0x20202020 },
399 { 0x0000a23c, 0x13c889af },
400 { 0x0000a240, 0x38490a20 },
401 { 0x0000a244, 0x00007bb6 },
402 { 0x0000a248, 0x0fff3ffc },
403 { 0x0000a24c, 0x00000001 },
404 { 0x0000a250, 0x0000a000 },
405 { 0x0000a254, 0x00000000 },
406 { 0x0000a258, 0x0cc75380 },
407 { 0x0000a25c, 0x0f0f0f01 },
408 { 0x0000a260, 0xdfa91f01 },
409 { 0x0000a268, 0x00000000 },
410 { 0x0000a26c, 0x0e79e5c6 },
411 { 0x0000b26c, 0x0e79e5c6 },
412 { 0x0000c26c, 0x0e79e5c6 },
413 { 0x0000d270, 0x00820820 },
414 { 0x0000a278, 0x1ce739ce },
415 { 0x0000a27c, 0x051701ce },
416 { 0x0000a338, 0x00000000 },
417 { 0x0000a33c, 0x00000000 },
418 { 0x0000a340, 0x00000000 },
419 { 0x0000a344, 0x00000000 },
420 { 0x0000a348, 0x3fffffff },
421 { 0x0000a34c, 0x3fffffff },
422 { 0x0000a350, 0x3fffffff },
423 { 0x0000a354, 0x0003ffff },
424 { 0x0000a358, 0x79a8aa1f },
425 { 0x0000d35c, 0x07ffffef },
426 { 0x0000d360, 0x0fffffe7 },
427 { 0x0000d364, 0x17ffffe5 },
428 { 0x0000d368, 0x1fffffe4 },
429 { 0x0000d36c, 0x37ffffe3 },
430 { 0x0000d370, 0x3fffffe3 },
431 { 0x0000d374, 0x57ffffe3 },
432 { 0x0000d378, 0x5fffffe2 },
433 { 0x0000d37c, 0x7fffffe2 },
434 { 0x0000d380, 0x7f3c7bba },
435 { 0x0000d384, 0xf3307ff0 },
436 { 0x0000a388, 0x08000000 },
437 { 0x0000a38c, 0x20202020 },
438 { 0x0000a390, 0x20202020 },
439 { 0x0000a394, 0x1ce739ce },
440 { 0x0000a398, 0x000001ce },
441 { 0x0000a39c, 0x00000001 },
442 { 0x0000a3a0, 0x00000000 },
443 { 0x0000a3a4, 0x00000000 },
444 { 0x0000a3a8, 0x00000000 },
445 { 0x0000a3ac, 0x00000000 },
446 { 0x0000a3b0, 0x00000000 },
447 { 0x0000a3b4, 0x00000000 },
448 { 0x0000a3b8, 0x00000000 },
449 { 0x0000a3bc, 0x00000000 },
450 { 0x0000a3c0, 0x00000000 },
451 { 0x0000a3c4, 0x00000000 },
452 { 0x0000a3c8, 0x00000246 },
453 { 0x0000a3cc, 0x20202020 },
454 { 0x0000a3d0, 0x20202020 },
455 { 0x0000a3d4, 0x20202020 },
456 { 0x0000a3dc, 0x1ce739ce },
457 { 0x0000a3e0, 0x000001ce },
458};
459
460static const u32 ar5416Bank0[][2] = {
461 { 0x000098b0, 0x1e5795e5 },
462 { 0x000098e0, 0x02008020 },
463};
464
465static const u32 ar5416BB_RfGain[][3] = {
466 { 0x00009a00, 0x00000000, 0x00000000 },
467 { 0x00009a04, 0x00000040, 0x00000040 },
468 { 0x00009a08, 0x00000080, 0x00000080 },
469 { 0x00009a0c, 0x000001a1, 0x00000141 },
470 { 0x00009a10, 0x000001e1, 0x00000181 },
471 { 0x00009a14, 0x00000021, 0x000001c1 },
472 { 0x00009a18, 0x00000061, 0x00000001 },
473 { 0x00009a1c, 0x00000168, 0x00000041 },
474 { 0x00009a20, 0x000001a8, 0x000001a8 },
475 { 0x00009a24, 0x000001e8, 0x000001e8 },
476 { 0x00009a28, 0x00000028, 0x00000028 },
477 { 0x00009a2c, 0x00000068, 0x00000068 },
478 { 0x00009a30, 0x00000189, 0x000000a8 },
479 { 0x00009a34, 0x000001c9, 0x00000169 },
480 { 0x00009a38, 0x00000009, 0x000001a9 },
481 { 0x00009a3c, 0x00000049, 0x000001e9 },
482 { 0x00009a40, 0x00000089, 0x00000029 },
483 { 0x00009a44, 0x00000170, 0x00000069 },
484 { 0x00009a48, 0x000001b0, 0x00000190 },
485 { 0x00009a4c, 0x000001f0, 0x000001d0 },
486 { 0x00009a50, 0x00000030, 0x00000010 },
487 { 0x00009a54, 0x00000070, 0x00000050 },
488 { 0x00009a58, 0x00000191, 0x00000090 },
489 { 0x00009a5c, 0x000001d1, 0x00000151 },
490 { 0x00009a60, 0x00000011, 0x00000191 },
491 { 0x00009a64, 0x00000051, 0x000001d1 },
492 { 0x00009a68, 0x00000091, 0x00000011 },
493 { 0x00009a6c, 0x000001b8, 0x00000051 },
494 { 0x00009a70, 0x000001f8, 0x00000198 },
495 { 0x00009a74, 0x00000038, 0x000001d8 },
496 { 0x00009a78, 0x00000078, 0x00000018 },
497 { 0x00009a7c, 0x00000199, 0x00000058 },
498 { 0x00009a80, 0x000001d9, 0x00000098 },
499 { 0x00009a84, 0x00000019, 0x00000159 },
500 { 0x00009a88, 0x00000059, 0x00000199 },
501 { 0x00009a8c, 0x00000099, 0x000001d9 },
502 { 0x00009a90, 0x000000d9, 0x00000019 },
503 { 0x00009a94, 0x000000f9, 0x00000059 },
504 { 0x00009a98, 0x000000f9, 0x00000099 },
505 { 0x00009a9c, 0x000000f9, 0x000000d9 },
506 { 0x00009aa0, 0x000000f9, 0x000000f9 },
507 { 0x00009aa4, 0x000000f9, 0x000000f9 },
508 { 0x00009aa8, 0x000000f9, 0x000000f9 },
509 { 0x00009aac, 0x000000f9, 0x000000f9 },
510 { 0x00009ab0, 0x000000f9, 0x000000f9 },
511 { 0x00009ab4, 0x000000f9, 0x000000f9 },
512 { 0x00009ab8, 0x000000f9, 0x000000f9 },
513 { 0x00009abc, 0x000000f9, 0x000000f9 },
514 { 0x00009ac0, 0x000000f9, 0x000000f9 },
515 { 0x00009ac4, 0x000000f9, 0x000000f9 },
516 { 0x00009ac8, 0x000000f9, 0x000000f9 },
517 { 0x00009acc, 0x000000f9, 0x000000f9 },
518 { 0x00009ad0, 0x000000f9, 0x000000f9 },
519 { 0x00009ad4, 0x000000f9, 0x000000f9 },
520 { 0x00009ad8, 0x000000f9, 0x000000f9 },
521 { 0x00009adc, 0x000000f9, 0x000000f9 },
522 { 0x00009ae0, 0x000000f9, 0x000000f9 },
523 { 0x00009ae4, 0x000000f9, 0x000000f9 },
524 { 0x00009ae8, 0x000000f9, 0x000000f9 },
525 { 0x00009aec, 0x000000f9, 0x000000f9 },
526 { 0x00009af0, 0x000000f9, 0x000000f9 },
527 { 0x00009af4, 0x000000f9, 0x000000f9 },
528 { 0x00009af8, 0x000000f9, 0x000000f9 },
529 { 0x00009afc, 0x000000f9, 0x000000f9 },
530};
531
532static const u32 ar5416Bank1[][2] = {
533 { 0x000098b0, 0x02108421 },
534 { 0x000098ec, 0x00000008 },
535};
536
537static const u32 ar5416Bank2[][2] = {
538 { 0x000098b0, 0x0e73ff17 },
539 { 0x000098e0, 0x00000420 },
540};
541
542static const u32 ar5416Bank3[][3] = {
543 { 0x000098f0, 0x01400018, 0x01c00018 },
544};
545
546static const u32 ar5416Bank6[][3] = {
547
548 { 0x0000989c, 0x00000000, 0x00000000 },
549 { 0x0000989c, 0x00000000, 0x00000000 },
550 { 0x0000989c, 0x00000000, 0x00000000 },
551 { 0x0000989c, 0x00e00000, 0x00e00000 },
552 { 0x0000989c, 0x005e0000, 0x005e0000 },
553 { 0x0000989c, 0x00120000, 0x00120000 },
554 { 0x0000989c, 0x00620000, 0x00620000 },
555 { 0x0000989c, 0x00020000, 0x00020000 },
556 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
557 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
558 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
559 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
560 { 0x0000989c, 0x005f0000, 0x005f0000 },
561 { 0x0000989c, 0x00870000, 0x00870000 },
562 { 0x0000989c, 0x00f90000, 0x00f90000 },
563 { 0x0000989c, 0x007b0000, 0x007b0000 },
564 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
565 { 0x0000989c, 0x00f50000, 0x00f50000 },
566 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
567 { 0x0000989c, 0x00110000, 0x00110000 },
568 { 0x0000989c, 0x006100a8, 0x006100a8 },
569 { 0x0000989c, 0x004210a2, 0x004210a2 },
570 { 0x0000989c, 0x0014008f, 0x0014008f },
571 { 0x0000989c, 0x00c40003, 0x00c40003 },
572 { 0x0000989c, 0x003000f2, 0x003000f2 },
573 { 0x0000989c, 0x00440016, 0x00440016 },
574 { 0x0000989c, 0x00410040, 0x00410040 },
575 { 0x0000989c, 0x0001805e, 0x0001805e },
576 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
577 { 0x0000989c, 0x000000f1, 0x000000f1 },
578 { 0x0000989c, 0x00002081, 0x00002081 },
579 { 0x0000989c, 0x000000d4, 0x000000d4 },
580 { 0x000098d0, 0x0000000f, 0x0010000f },
581};
582
583static const u32 ar5416Bank6TPC[][3] = {
584 { 0x0000989c, 0x00000000, 0x00000000 },
585 { 0x0000989c, 0x00000000, 0x00000000 },
586 { 0x0000989c, 0x00000000, 0x00000000 },
587 { 0x0000989c, 0x00e00000, 0x00e00000 },
588 { 0x0000989c, 0x005e0000, 0x005e0000 },
589 { 0x0000989c, 0x00120000, 0x00120000 },
590 { 0x0000989c, 0x00620000, 0x00620000 },
591 { 0x0000989c, 0x00020000, 0x00020000 },
592 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
593 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
594 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
595 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
596 { 0x0000989c, 0x005f0000, 0x005f0000 },
597 { 0x0000989c, 0x00870000, 0x00870000 },
598 { 0x0000989c, 0x00f90000, 0x00f90000 },
599 { 0x0000989c, 0x007b0000, 0x007b0000 },
600 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
601 { 0x0000989c, 0x00f50000, 0x00f50000 },
602 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
603 { 0x0000989c, 0x00110000, 0x00110000 },
604 { 0x0000989c, 0x006100a8, 0x006100a8 },
605 { 0x0000989c, 0x00423022, 0x00423022 },
606 { 0x0000989c, 0x201400df, 0x201400df },
607 { 0x0000989c, 0x00c40002, 0x00c40002 },
608 { 0x0000989c, 0x003000f2, 0x003000f2 },
609 { 0x0000989c, 0x00440016, 0x00440016 },
610 { 0x0000989c, 0x00410040, 0x00410040 },
611 { 0x0000989c, 0x0001805e, 0x0001805e },
612 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
613 { 0x0000989c, 0x000000e1, 0x000000e1 },
614 { 0x0000989c, 0x00007081, 0x00007081 },
615 { 0x0000989c, 0x000000d4, 0x000000d4 },
616 { 0x000098d0, 0x0000000f, 0x0010000f },
617};
618
619static const u32 ar5416Bank7[][2] = {
620 { 0x0000989c, 0x00000500 },
621 { 0x0000989c, 0x00000800 },
622 { 0x000098cc, 0x0000000e },
623};
624
625static const u32 ar5416Addac[][2] = {
626 {0x0000989c, 0x00000000 },
627 {0x0000989c, 0x00000003 },
628 {0x0000989c, 0x00000000 },
629 {0x0000989c, 0x0000000c },
630 {0x0000989c, 0x00000000 },
631 {0x0000989c, 0x00000030 },
632 {0x0000989c, 0x00000000 },
633 {0x0000989c, 0x00000000 },
634 {0x0000989c, 0x00000000 },
635 {0x0000989c, 0x00000000 },
636 {0x0000989c, 0x00000000 },
637 {0x0000989c, 0x00000000 },
638 {0x0000989c, 0x00000000 },
639 {0x0000989c, 0x00000000 },
640 {0x0000989c, 0x00000000 },
641 {0x0000989c, 0x00000000 },
642 {0x0000989c, 0x00000000 },
643 {0x0000989c, 0x00000000 },
644 {0x0000989c, 0x00000060 },
645 {0x0000989c, 0x00000000 },
646 {0x0000989c, 0x00000000 },
647 {0x0000989c, 0x00000000 },
648 {0x0000989c, 0x00000000 },
649 {0x0000989c, 0x00000000 },
650 {0x0000989c, 0x00000000 },
651 {0x0000989c, 0x00000000 },
652 {0x0000989c, 0x00000000 },
653 {0x0000989c, 0x00000000 },
654 {0x0000989c, 0x00000000 },
655 {0x0000989c, 0x00000000 },
656 {0x0000989c, 0x00000000 },
657 {0x0000989c, 0x00000058 },
658 {0x0000989c, 0x00000000 },
659 {0x0000989c, 0x00000000 },
660 {0x0000989c, 0x00000000 },
661 {0x0000989c, 0x00000000 },
662 {0x000098cc, 0x00000000 },
663};
664
665static const u32 ar5416Modes_9100[][6] = {
666 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
667 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
668 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
669 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
670 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
671 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
672 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
673 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
674 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
675 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
676 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
677 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
678 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
679 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
680 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
681 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
682 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
683 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
684 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
685 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
686 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
687 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
688 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
689 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
690 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
691 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
692 { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
693 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
694 { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
695 { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
696#ifdef TB243
697 { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
698 { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
699 { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
700 { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
701#else
702 { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
703 { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
704 { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
705 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
706#endif
707 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
708 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
709 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
710 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
711 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
712 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
713 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
714 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
715 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
716 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
717 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
718 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
719 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
720 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
721 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
722 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
723 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
724 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
725 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
726 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
727 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
728 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
729 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
730 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
731 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
732 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
733 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
734 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
735 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
736 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
737};
738
739static const u32 ar5416Common_9100[][2] = {
740 { 0x0000000c, 0x00000000 },
741 { 0x00000030, 0x00020015 },
742 { 0x00000034, 0x00000005 },
743 { 0x00000040, 0x00000000 },
744 { 0x00000044, 0x00000008 },
745 { 0x00000048, 0x00000008 },
746 { 0x0000004c, 0x00000010 },
747 { 0x00000050, 0x00000000 },
748 { 0x00000054, 0x0000001f },
749 { 0x00000800, 0x00000000 },
750 { 0x00000804, 0x00000000 },
751 { 0x00000808, 0x00000000 },
752 { 0x0000080c, 0x00000000 },
753 { 0x00000810, 0x00000000 },
754 { 0x00000814, 0x00000000 },
755 { 0x00000818, 0x00000000 },
756 { 0x0000081c, 0x00000000 },
757 { 0x00000820, 0x00000000 },
758 { 0x00000824, 0x00000000 },
759 { 0x00001040, 0x002ffc0f },
760 { 0x00001044, 0x002ffc0f },
761 { 0x00001048, 0x002ffc0f },
762 { 0x0000104c, 0x002ffc0f },
763 { 0x00001050, 0x002ffc0f },
764 { 0x00001054, 0x002ffc0f },
765 { 0x00001058, 0x002ffc0f },
766 { 0x0000105c, 0x002ffc0f },
767 { 0x00001060, 0x002ffc0f },
768 { 0x00001064, 0x002ffc0f },
769 { 0x00001230, 0x00000000 },
770 { 0x00001270, 0x00000000 },
771 { 0x00001038, 0x00000000 },
772 { 0x00001078, 0x00000000 },
773 { 0x000010b8, 0x00000000 },
774 { 0x000010f8, 0x00000000 },
775 { 0x00001138, 0x00000000 },
776 { 0x00001178, 0x00000000 },
777 { 0x000011b8, 0x00000000 },
778 { 0x000011f8, 0x00000000 },
779 { 0x00001238, 0x00000000 },
780 { 0x00001278, 0x00000000 },
781 { 0x000012b8, 0x00000000 },
782 { 0x000012f8, 0x00000000 },
783 { 0x00001338, 0x00000000 },
784 { 0x00001378, 0x00000000 },
785 { 0x000013b8, 0x00000000 },
786 { 0x000013f8, 0x00000000 },
787 { 0x00001438, 0x00000000 },
788 { 0x00001478, 0x00000000 },
789 { 0x000014b8, 0x00000000 },
790 { 0x000014f8, 0x00000000 },
791 { 0x00001538, 0x00000000 },
792 { 0x00001578, 0x00000000 },
793 { 0x000015b8, 0x00000000 },
794 { 0x000015f8, 0x00000000 },
795 { 0x00001638, 0x00000000 },
796 { 0x00001678, 0x00000000 },
797 { 0x000016b8, 0x00000000 },
798 { 0x000016f8, 0x00000000 },
799 { 0x00001738, 0x00000000 },
800 { 0x00001778, 0x00000000 },
801 { 0x000017b8, 0x00000000 },
802 { 0x000017f8, 0x00000000 },
803 { 0x0000103c, 0x00000000 },
804 { 0x0000107c, 0x00000000 },
805 { 0x000010bc, 0x00000000 },
806 { 0x000010fc, 0x00000000 },
807 { 0x0000113c, 0x00000000 },
808 { 0x0000117c, 0x00000000 },
809 { 0x000011bc, 0x00000000 },
810 { 0x000011fc, 0x00000000 },
811 { 0x0000123c, 0x00000000 },
812 { 0x0000127c, 0x00000000 },
813 { 0x000012bc, 0x00000000 },
814 { 0x000012fc, 0x00000000 },
815 { 0x0000133c, 0x00000000 },
816 { 0x0000137c, 0x00000000 },
817 { 0x000013bc, 0x00000000 },
818 { 0x000013fc, 0x00000000 },
819 { 0x0000143c, 0x00000000 },
820 { 0x0000147c, 0x00000000 },
821 { 0x00020010, 0x00000003 },
822 { 0x00020038, 0x000004c2 },
823 { 0x00008004, 0x00000000 },
824 { 0x00008008, 0x00000000 },
825 { 0x0000800c, 0x00000000 },
826 { 0x00008018, 0x00000700 },
827 { 0x00008020, 0x00000000 },
828 { 0x00008038, 0x00000000 },
829 { 0x0000803c, 0x00000000 },
830 { 0x00008048, 0x40000000 },
831 { 0x00008054, 0x00004000 },
832 { 0x00008058, 0x00000000 },
833 { 0x0000805c, 0x000fc78f },
834 { 0x00008060, 0x0000000f },
835 { 0x00008064, 0x00000000 },
836 { 0x000080c0, 0x2a82301a },
837 { 0x000080c4, 0x05dc01e0 },
838 { 0x000080c8, 0x1f402710 },
839 { 0x000080cc, 0x01f40000 },
840 { 0x000080d0, 0x00001e00 },
841 { 0x000080d4, 0x00000000 },
842 { 0x000080d8, 0x00400000 },
843 { 0x000080e0, 0xffffffff },
844 { 0x000080e4, 0x0000ffff },
845 { 0x000080e8, 0x003f3f3f },
846 { 0x000080ec, 0x00000000 },
847 { 0x000080f0, 0x00000000 },
848 { 0x000080f4, 0x00000000 },
849 { 0x000080f8, 0x00000000 },
850 { 0x000080fc, 0x00020000 },
851 { 0x00008100, 0x00020000 },
852 { 0x00008104, 0x00000001 },
853 { 0x00008108, 0x00000052 },
854 { 0x0000810c, 0x00000000 },
855 { 0x00008110, 0x00000168 },
856 { 0x00008118, 0x000100aa },
857 { 0x0000811c, 0x00003210 },
858 { 0x00008120, 0x08f04800 },
859 { 0x00008124, 0x00000000 },
860 { 0x00008128, 0x00000000 },
861 { 0x0000812c, 0x00000000 },
862 { 0x00008130, 0x00000000 },
863 { 0x00008134, 0x00000000 },
864 { 0x00008138, 0x00000000 },
865 { 0x0000813c, 0x00000000 },
866 { 0x00008144, 0x00000000 },
867 { 0x00008168, 0x00000000 },
868 { 0x0000816c, 0x00000000 },
869 { 0x00008170, 0x32143320 },
870 { 0x00008174, 0xfaa4fa50 },
871 { 0x00008178, 0x00000100 },
872 { 0x0000817c, 0x00000000 },
873 { 0x000081c4, 0x00000000 },
874 { 0x000081d0, 0x00003210 },
875 { 0x000081ec, 0x00000000 },
876 { 0x000081f0, 0x00000000 },
877 { 0x000081f4, 0x00000000 },
878 { 0x000081f8, 0x00000000 },
879 { 0x000081fc, 0x00000000 },
880 { 0x00008200, 0x00000000 },
881 { 0x00008204, 0x00000000 },
882 { 0x00008208, 0x00000000 },
883 { 0x0000820c, 0x00000000 },
884 { 0x00008210, 0x00000000 },
885 { 0x00008214, 0x00000000 },
886 { 0x00008218, 0x00000000 },
887 { 0x0000821c, 0x00000000 },
888 { 0x00008220, 0x00000000 },
889 { 0x00008224, 0x00000000 },
890 { 0x00008228, 0x00000000 },
891 { 0x0000822c, 0x00000000 },
892 { 0x00008230, 0x00000000 },
893 { 0x00008234, 0x00000000 },
894 { 0x00008238, 0x00000000 },
895 { 0x0000823c, 0x00000000 },
896 { 0x00008240, 0x00100000 },
897 { 0x00008244, 0x0010f400 },
898 { 0x00008248, 0x00000100 },
899 { 0x0000824c, 0x0001e800 },
900 { 0x00008250, 0x00000000 },
901 { 0x00008254, 0x00000000 },
902 { 0x00008258, 0x00000000 },
903 { 0x0000825c, 0x400000ff },
904 { 0x00008260, 0x00080922 },
905 { 0x00008270, 0x00000000 },
906 { 0x00008274, 0x40000000 },
907 { 0x00008278, 0x003e4180 },
908 { 0x0000827c, 0x00000000 },
909 { 0x00008284, 0x0000002c },
910 { 0x00008288, 0x0000002c },
911 { 0x0000828c, 0x00000000 },
912 { 0x00008294, 0x00000000 },
913 { 0x00008298, 0x00000000 },
914 { 0x00008300, 0x00000000 },
915 { 0x00008304, 0x00000000 },
916 { 0x00008308, 0x00000000 },
917 { 0x0000830c, 0x00000000 },
918 { 0x00008310, 0x00000000 },
919 { 0x00008314, 0x00000000 },
920 { 0x00008318, 0x00000000 },
921 { 0x00008328, 0x00000000 },
922 { 0x0000832c, 0x00000007 },
923 { 0x00008330, 0x00000302 },
924 { 0x00008334, 0x00000e00 },
925 { 0x00008338, 0x00000000 },
926 { 0x0000833c, 0x00000000 },
927 { 0x00008340, 0x000107ff },
928 { 0x00009808, 0x00000000 },
929 { 0x0000980c, 0xad848e19 },
930 { 0x00009810, 0x7d14e000 },
931 { 0x00009814, 0x9c0a9f6b },
932 { 0x0000981c, 0x00000000 },
933 { 0x0000982c, 0x0000a000 },
934 { 0x00009830, 0x00000000 },
935 { 0x0000983c, 0x00200400 },
936 { 0x00009840, 0x206a01ae },
937 { 0x0000984c, 0x1284233c },
938 { 0x00009854, 0x00000859 },
939 { 0x00009900, 0x00000000 },
940 { 0x00009904, 0x00000000 },
941 { 0x00009908, 0x00000000 },
942 { 0x0000990c, 0x00000000 },
943 { 0x0000991c, 0x10000fff },
944 { 0x00009920, 0x05100000 },
945 { 0x0000a920, 0x05100000 },
946 { 0x0000b920, 0x05100000 },
947 { 0x00009928, 0x00000001 },
948 { 0x0000992c, 0x00000004 },
949 { 0x00009934, 0x1e1f2022 },
950 { 0x00009938, 0x0a0b0c0d },
951 { 0x0000993c, 0x00000000 },
952 { 0x00009948, 0x9280b212 },
953 { 0x0000994c, 0x00020028 },
954 { 0x0000c95c, 0x004b6a8e },
955 { 0x0000c968, 0x000003ce },
956 { 0x00009970, 0x190fb515 },
957 { 0x00009974, 0x00000000 },
958 { 0x00009978, 0x00000001 },
959 { 0x0000997c, 0x00000000 },
960 { 0x00009980, 0x00000000 },
961 { 0x00009984, 0x00000000 },
962 { 0x00009988, 0x00000000 },
963 { 0x0000998c, 0x00000000 },
964 { 0x00009990, 0x00000000 },
965 { 0x00009994, 0x00000000 },
966 { 0x00009998, 0x00000000 },
967 { 0x0000999c, 0x00000000 },
968 { 0x000099a0, 0x00000000 },
969 { 0x000099a4, 0x00000001 },
970 { 0x000099a8, 0x201fff00 },
971 { 0x000099ac, 0x006f0000 },
972 { 0x000099b0, 0x03051000 },
973 { 0x000099dc, 0x00000000 },
974 { 0x000099e0, 0x00000200 },
975 { 0x000099e4, 0xaaaaaaaa },
976 { 0x000099e8, 0x3c466478 },
977 { 0x000099ec, 0x0cc80caa },
978 { 0x000099fc, 0x00001042 },
979 { 0x00009b00, 0x00000000 },
980 { 0x00009b04, 0x00000001 },
981 { 0x00009b08, 0x00000002 },
982 { 0x00009b0c, 0x00000003 },
983 { 0x00009b10, 0x00000004 },
984 { 0x00009b14, 0x00000005 },
985 { 0x00009b18, 0x00000008 },
986 { 0x00009b1c, 0x00000009 },
987 { 0x00009b20, 0x0000000a },
988 { 0x00009b24, 0x0000000b },
989 { 0x00009b28, 0x0000000c },
990 { 0x00009b2c, 0x0000000d },
991 { 0x00009b30, 0x00000010 },
992 { 0x00009b34, 0x00000011 },
993 { 0x00009b38, 0x00000012 },
994 { 0x00009b3c, 0x00000013 },
995 { 0x00009b40, 0x00000014 },
996 { 0x00009b44, 0x00000015 },
997 { 0x00009b48, 0x00000018 },
998 { 0x00009b4c, 0x00000019 },
999 { 0x00009b50, 0x0000001a },
1000 { 0x00009b54, 0x0000001b },
1001 { 0x00009b58, 0x0000001c },
1002 { 0x00009b5c, 0x0000001d },
1003 { 0x00009b60, 0x00000020 },
1004 { 0x00009b64, 0x00000021 },
1005 { 0x00009b68, 0x00000022 },
1006 { 0x00009b6c, 0x00000023 },
1007 { 0x00009b70, 0x00000024 },
1008 { 0x00009b74, 0x00000025 },
1009 { 0x00009b78, 0x00000028 },
1010 { 0x00009b7c, 0x00000029 },
1011 { 0x00009b80, 0x0000002a },
1012 { 0x00009b84, 0x0000002b },
1013 { 0x00009b88, 0x0000002c },
1014 { 0x00009b8c, 0x0000002d },
1015 { 0x00009b90, 0x00000030 },
1016 { 0x00009b94, 0x00000031 },
1017 { 0x00009b98, 0x00000032 },
1018 { 0x00009b9c, 0x00000033 },
1019 { 0x00009ba0, 0x00000034 },
1020 { 0x00009ba4, 0x00000035 },
1021 { 0x00009ba8, 0x00000035 },
1022 { 0x00009bac, 0x00000035 },
1023 { 0x00009bb0, 0x00000035 },
1024 { 0x00009bb4, 0x00000035 },
1025 { 0x00009bb8, 0x00000035 },
1026 { 0x00009bbc, 0x00000035 },
1027 { 0x00009bc0, 0x00000035 },
1028 { 0x00009bc4, 0x00000035 },
1029 { 0x00009bc8, 0x00000035 },
1030 { 0x00009bcc, 0x00000035 },
1031 { 0x00009bd0, 0x00000035 },
1032 { 0x00009bd4, 0x00000035 },
1033 { 0x00009bd8, 0x00000035 },
1034 { 0x00009bdc, 0x00000035 },
1035 { 0x00009be0, 0x00000035 },
1036 { 0x00009be4, 0x00000035 },
1037 { 0x00009be8, 0x00000035 },
1038 { 0x00009bec, 0x00000035 },
1039 { 0x00009bf0, 0x00000035 },
1040 { 0x00009bf4, 0x00000035 },
1041 { 0x00009bf8, 0x00000010 },
1042 { 0x00009bfc, 0x0000001a },
1043 { 0x0000a210, 0x40806333 },
1044 { 0x0000a214, 0x00106c10 },
1045 { 0x0000a218, 0x009c4060 },
1046 { 0x0000a220, 0x018830c6 },
1047 { 0x0000a224, 0x00000400 },
1048 { 0x0000a228, 0x001a0bb5 },
1049 { 0x0000a22c, 0x00000000 },
1050 { 0x0000a234, 0x20202020 },
1051 { 0x0000a238, 0x20202020 },
1052 { 0x0000a23c, 0x13c889ae },
1053 { 0x0000a240, 0x38490a20 },
1054 { 0x0000a244, 0x00007bb6 },
1055 { 0x0000a248, 0x0fff3ffc },
1056 { 0x0000a24c, 0x00000001 },
1057 { 0x0000a250, 0x0000a000 },
1058 { 0x0000a254, 0x00000000 },
1059 { 0x0000a258, 0x0cc75380 },
1060 { 0x0000a25c, 0x0f0f0f01 },
1061 { 0x0000a260, 0xdfa91f01 },
1062 { 0x0000a268, 0x00000001 },
1063 { 0x0000a26c, 0x0ebae9c6 },
1064 { 0x0000b26c, 0x0ebae9c6 },
1065 { 0x0000c26c, 0x0ebae9c6 },
1066 { 0x0000d270, 0x00820820 },
1067 { 0x0000a278, 0x1ce739ce },
1068 { 0x0000a27c, 0x050701ce },
1069 { 0x0000a338, 0x00000000 },
1070 { 0x0000a33c, 0x00000000 },
1071 { 0x0000a340, 0x00000000 },
1072 { 0x0000a344, 0x00000000 },
1073 { 0x0000a348, 0x3fffffff },
1074 { 0x0000a34c, 0x3fffffff },
1075 { 0x0000a350, 0x3fffffff },
1076 { 0x0000a354, 0x0003ffff },
1077 { 0x0000a358, 0x79a8aa33 },
1078 { 0x0000d35c, 0x07ffffef },
1079 { 0x0000d360, 0x0fffffe7 },
1080 { 0x0000d364, 0x17ffffe5 },
1081 { 0x0000d368, 0x1fffffe4 },
1082 { 0x0000d36c, 0x37ffffe3 },
1083 { 0x0000d370, 0x3fffffe3 },
1084 { 0x0000d374, 0x57ffffe3 },
1085 { 0x0000d378, 0x5fffffe2 },
1086 { 0x0000d37c, 0x7fffffe2 },
1087 { 0x0000d380, 0x7f3c7bba },
1088 { 0x0000d384, 0xf3307ff0 },
1089 { 0x0000a388, 0x0c000000 },
1090 { 0x0000a38c, 0x20202020 },
1091 { 0x0000a390, 0x20202020 },
1092 { 0x0000a394, 0x1ce739ce },
1093 { 0x0000a398, 0x000001ce },
1094 { 0x0000a39c, 0x00000001 },
1095 { 0x0000a3a0, 0x00000000 },
1096 { 0x0000a3a4, 0x00000000 },
1097 { 0x0000a3a8, 0x00000000 },
1098 { 0x0000a3ac, 0x00000000 },
1099 { 0x0000a3b0, 0x00000000 },
1100 { 0x0000a3b4, 0x00000000 },
1101 { 0x0000a3b8, 0x00000000 },
1102 { 0x0000a3bc, 0x00000000 },
1103 { 0x0000a3c0, 0x00000000 },
1104 { 0x0000a3c4, 0x00000000 },
1105 { 0x0000a3c8, 0x00000246 },
1106 { 0x0000a3cc, 0x20202020 },
1107 { 0x0000a3d0, 0x20202020 },
1108 { 0x0000a3d4, 0x20202020 },
1109 { 0x0000a3dc, 0x1ce739ce },
1110 { 0x0000a3e0, 0x000001ce },
1111};
1112
1113static const u32 ar5416Bank0_9100[][2] = {
1114 { 0x000098b0, 0x1e5795e5 },
1115 { 0x000098e0, 0x02008020 },
1116};
1117
1118static const u32 ar5416BB_RfGain_9100[][3] = {
1119 { 0x00009a00, 0x00000000, 0x00000000 },
1120 { 0x00009a04, 0x00000040, 0x00000040 },
1121 { 0x00009a08, 0x00000080, 0x00000080 },
1122 { 0x00009a0c, 0x000001a1, 0x00000141 },
1123 { 0x00009a10, 0x000001e1, 0x00000181 },
1124 { 0x00009a14, 0x00000021, 0x000001c1 },
1125 { 0x00009a18, 0x00000061, 0x00000001 },
1126 { 0x00009a1c, 0x00000168, 0x00000041 },
1127 { 0x00009a20, 0x000001a8, 0x000001a8 },
1128 { 0x00009a24, 0x000001e8, 0x000001e8 },
1129 { 0x00009a28, 0x00000028, 0x00000028 },
1130 { 0x00009a2c, 0x00000068, 0x00000068 },
1131 { 0x00009a30, 0x00000189, 0x000000a8 },
1132 { 0x00009a34, 0x000001c9, 0x00000169 },
1133 { 0x00009a38, 0x00000009, 0x000001a9 },
1134 { 0x00009a3c, 0x00000049, 0x000001e9 },
1135 { 0x00009a40, 0x00000089, 0x00000029 },
1136 { 0x00009a44, 0x00000170, 0x00000069 },
1137 { 0x00009a48, 0x000001b0, 0x00000190 },
1138 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1139 { 0x00009a50, 0x00000030, 0x00000010 },
1140 { 0x00009a54, 0x00000070, 0x00000050 },
1141 { 0x00009a58, 0x00000191, 0x00000090 },
1142 { 0x00009a5c, 0x000001d1, 0x00000151 },
1143 { 0x00009a60, 0x00000011, 0x00000191 },
1144 { 0x00009a64, 0x00000051, 0x000001d1 },
1145 { 0x00009a68, 0x00000091, 0x00000011 },
1146 { 0x00009a6c, 0x000001b8, 0x00000051 },
1147 { 0x00009a70, 0x000001f8, 0x00000198 },
1148 { 0x00009a74, 0x00000038, 0x000001d8 },
1149 { 0x00009a78, 0x00000078, 0x00000018 },
1150 { 0x00009a7c, 0x00000199, 0x00000058 },
1151 { 0x00009a80, 0x000001d9, 0x00000098 },
1152 { 0x00009a84, 0x00000019, 0x00000159 },
1153 { 0x00009a88, 0x00000059, 0x00000199 },
1154 { 0x00009a8c, 0x00000099, 0x000001d9 },
1155 { 0x00009a90, 0x000000d9, 0x00000019 },
1156 { 0x00009a94, 0x000000f9, 0x00000059 },
1157 { 0x00009a98, 0x000000f9, 0x00000099 },
1158 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1159 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1160 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1161 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1162 { 0x00009aac, 0x000000f9, 0x000000f9 },
1163 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1164 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1165 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1166 { 0x00009abc, 0x000000f9, 0x000000f9 },
1167 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1168 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1169 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1170 { 0x00009acc, 0x000000f9, 0x000000f9 },
1171 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1172 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1173 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1174 { 0x00009adc, 0x000000f9, 0x000000f9 },
1175 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1176 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1177 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1178 { 0x00009aec, 0x000000f9, 0x000000f9 },
1179 { 0x00009af0, 0x000000f9, 0x000000f9 },
1180 { 0x00009af4, 0x000000f9, 0x000000f9 },
1181 { 0x00009af8, 0x000000f9, 0x000000f9 },
1182 { 0x00009afc, 0x000000f9, 0x000000f9 },
1183};
1184
1185static const u32 ar5416Bank1_9100[][2] = {
1186 { 0x000098b0, 0x02108421},
1187 { 0x000098ec, 0x00000008},
1188};
1189
1190static const u32 ar5416Bank2_9100[][2] = {
1191 { 0x000098b0, 0x0e73ff17},
1192 { 0x000098e0, 0x00000420},
1193};
1194
1195static const u32 ar5416Bank3_9100[][3] = {
1196 { 0x000098f0, 0x01400018, 0x01c00018 },
1197};
1198
1199static const u32 ar5416Bank6_9100[][3] = {
1200
1201 { 0x0000989c, 0x00000000, 0x00000000 },
1202 { 0x0000989c, 0x00000000, 0x00000000 },
1203 { 0x0000989c, 0x00000000, 0x00000000 },
1204 { 0x0000989c, 0x00e00000, 0x00e00000 },
1205 { 0x0000989c, 0x005e0000, 0x005e0000 },
1206 { 0x0000989c, 0x00120000, 0x00120000 },
1207 { 0x0000989c, 0x00620000, 0x00620000 },
1208 { 0x0000989c, 0x00020000, 0x00020000 },
1209 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1210 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1211 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1212 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1213 { 0x0000989c, 0x005f0000, 0x005f0000 },
1214 { 0x0000989c, 0x00870000, 0x00870000 },
1215 { 0x0000989c, 0x00f90000, 0x00f90000 },
1216 { 0x0000989c, 0x007b0000, 0x007b0000 },
1217 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1218 { 0x0000989c, 0x00f50000, 0x00f50000 },
1219 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1220 { 0x0000989c, 0x00110000, 0x00110000 },
1221 { 0x0000989c, 0x006100a8, 0x006100a8 },
1222 { 0x0000989c, 0x004210a2, 0x004210a2 },
1223 { 0x0000989c, 0x0014000f, 0x0014000f },
1224 { 0x0000989c, 0x00c40002, 0x00c40002 },
1225 { 0x0000989c, 0x003000f2, 0x003000f2 },
1226 { 0x0000989c, 0x00440016, 0x00440016 },
1227 { 0x0000989c, 0x00410040, 0x00410040 },
1228 { 0x0000989c, 0x000180d6, 0x000180d6 },
1229 { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
1230 { 0x0000989c, 0x000000b1, 0x000000b1 },
1231 { 0x0000989c, 0x00002000, 0x00002000 },
1232 { 0x0000989c, 0x000000d4, 0x000000d4 },
1233 { 0x000098d0, 0x0000000f, 0x0010000f },
1234};
1235
1236
1237static const u32 ar5416Bank6TPC_9100[][3] = {
1238
1239 { 0x0000989c, 0x00000000, 0x00000000 },
1240 { 0x0000989c, 0x00000000, 0x00000000 },
1241 { 0x0000989c, 0x00000000, 0x00000000 },
1242 { 0x0000989c, 0x00e00000, 0x00e00000 },
1243 { 0x0000989c, 0x005e0000, 0x005e0000 },
1244 { 0x0000989c, 0x00120000, 0x00120000 },
1245 { 0x0000989c, 0x00620000, 0x00620000 },
1246 { 0x0000989c, 0x00020000, 0x00020000 },
1247 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1248 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1249 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1250 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1251 { 0x0000989c, 0x005f0000, 0x005f0000 },
1252 { 0x0000989c, 0x00870000, 0x00870000 },
1253 { 0x0000989c, 0x00f90000, 0x00f90000 },
1254 { 0x0000989c, 0x007b0000, 0x007b0000 },
1255 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1256 { 0x0000989c, 0x00f50000, 0x00f50000 },
1257 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1258 { 0x0000989c, 0x00110000, 0x00110000 },
1259 { 0x0000989c, 0x006100a8, 0x006100a8 },
1260 { 0x0000989c, 0x00423022, 0x00423022 },
1261 { 0x0000989c, 0x2014008f, 0x2014008f },
1262 { 0x0000989c, 0x00c40002, 0x00c40002 },
1263 { 0x0000989c, 0x003000f2, 0x003000f2 },
1264 { 0x0000989c, 0x00440016, 0x00440016 },
1265 { 0x0000989c, 0x00410040, 0x00410040 },
1266 { 0x0000989c, 0x0001805e, 0x0001805e },
1267 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1268 { 0x0000989c, 0x000000e1, 0x000000e1 },
1269 { 0x0000989c, 0x00007080, 0x00007080 },
1270 { 0x0000989c, 0x000000d4, 0x000000d4 },
1271 { 0x000098d0, 0x0000000f, 0x0010000f },
1272};
1273
1274static const u32 ar5416Bank7_9100[][2] = {
1275 { 0x0000989c, 0x00000500 },
1276 { 0x0000989c, 0x00000800 },
1277 { 0x000098cc, 0x0000000e },
1278};
1279
1280static const u32 ar5416Addac_9100[][2] = {
1281 {0x0000989c, 0x00000000 },
1282 {0x0000989c, 0x00000000 },
1283 {0x0000989c, 0x00000000 },
1284 {0x0000989c, 0x00000000 },
1285 {0x0000989c, 0x00000000 },
1286 {0x0000989c, 0x00000000 },
1287 {0x0000989c, 0x00000000 },
1288 {0x0000989c, 0x00000010 },
1289 {0x0000989c, 0x00000000 },
1290 {0x0000989c, 0x00000000 },
1291 {0x0000989c, 0x00000000 },
1292 {0x0000989c, 0x00000000 },
1293 {0x0000989c, 0x00000000 },
1294 {0x0000989c, 0x00000000 },
1295 {0x0000989c, 0x00000000 },
1296 {0x0000989c, 0x00000000 },
1297 {0x0000989c, 0x00000000 },
1298 {0x0000989c, 0x00000000 },
1299 {0x0000989c, 0x00000000 },
1300 {0x0000989c, 0x00000000 },
1301 {0x0000989c, 0x00000000 },
1302 {0x0000989c, 0x000000c0 },
1303 {0x0000989c, 0x00000015 },
1304 {0x0000989c, 0x00000000 },
1305 {0x0000989c, 0x00000000 },
1306 {0x0000989c, 0x00000000 },
1307 {0x0000989c, 0x00000000 },
1308 {0x0000989c, 0x00000000 },
1309 {0x0000989c, 0x00000000 },
1310 {0x0000989c, 0x00000000 },
1311 {0x0000989c, 0x00000000 },
1312 {0x000098cc, 0x00000000 },
1313};
1314
1315static const u32 ar5416Modes_9160[][6] = {
1316 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1317 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
1318 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
1319 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
1320 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
1321 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
1322 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
1323 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
1324 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1325 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
1326 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1327 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
1328 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
1329 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1330 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1331 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1332 { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
1333 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
1334 { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
1335 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
1336 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
1337 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
1338 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
1339 { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
1340 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
1341 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
1342 { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
1343 { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1344 { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1345 { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1346 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
1347 { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
1348 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
1349 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
1350 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
1351 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
1352 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
1353 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
1354 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1355 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1356 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
1357 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
1358 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1359 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1360 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1361 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
1362 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
1363 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
1364 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
1365 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
1366 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
1367 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
1368 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
1369 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
1370 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
1371 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
1372 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
1373 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
1374 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
1375 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1376 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1377 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1378};
1379
1380static const u32 ar5416Common_9160[][2] = {
1381 { 0x0000000c, 0x00000000 },
1382 { 0x00000030, 0x00020015 },
1383 { 0x00000034, 0x00000005 },
1384 { 0x00000040, 0x00000000 },
1385 { 0x00000044, 0x00000008 },
1386 { 0x00000048, 0x00000008 },
1387 { 0x0000004c, 0x00000010 },
1388 { 0x00000050, 0x00000000 },
1389 { 0x00000054, 0x0000001f },
1390 { 0x00000800, 0x00000000 },
1391 { 0x00000804, 0x00000000 },
1392 { 0x00000808, 0x00000000 },
1393 { 0x0000080c, 0x00000000 },
1394 { 0x00000810, 0x00000000 },
1395 { 0x00000814, 0x00000000 },
1396 { 0x00000818, 0x00000000 },
1397 { 0x0000081c, 0x00000000 },
1398 { 0x00000820, 0x00000000 },
1399 { 0x00000824, 0x00000000 },
1400 { 0x00001040, 0x002ffc0f },
1401 { 0x00001044, 0x002ffc0f },
1402 { 0x00001048, 0x002ffc0f },
1403 { 0x0000104c, 0x002ffc0f },
1404 { 0x00001050, 0x002ffc0f },
1405 { 0x00001054, 0x002ffc0f },
1406 { 0x00001058, 0x002ffc0f },
1407 { 0x0000105c, 0x002ffc0f },
1408 { 0x00001060, 0x002ffc0f },
1409 { 0x00001064, 0x002ffc0f },
1410 { 0x00001230, 0x00000000 },
1411 { 0x00001270, 0x00000000 },
1412 { 0x00001038, 0x00000000 },
1413 { 0x00001078, 0x00000000 },
1414 { 0x000010b8, 0x00000000 },
1415 { 0x000010f8, 0x00000000 },
1416 { 0x00001138, 0x00000000 },
1417 { 0x00001178, 0x00000000 },
1418 { 0x000011b8, 0x00000000 },
1419 { 0x000011f8, 0x00000000 },
1420 { 0x00001238, 0x00000000 },
1421 { 0x00001278, 0x00000000 },
1422 { 0x000012b8, 0x00000000 },
1423 { 0x000012f8, 0x00000000 },
1424 { 0x00001338, 0x00000000 },
1425 { 0x00001378, 0x00000000 },
1426 { 0x000013b8, 0x00000000 },
1427 { 0x000013f8, 0x00000000 },
1428 { 0x00001438, 0x00000000 },
1429 { 0x00001478, 0x00000000 },
1430 { 0x000014b8, 0x00000000 },
1431 { 0x000014f8, 0x00000000 },
1432 { 0x00001538, 0x00000000 },
1433 { 0x00001578, 0x00000000 },
1434 { 0x000015b8, 0x00000000 },
1435 { 0x000015f8, 0x00000000 },
1436 { 0x00001638, 0x00000000 },
1437 { 0x00001678, 0x00000000 },
1438 { 0x000016b8, 0x00000000 },
1439 { 0x000016f8, 0x00000000 },
1440 { 0x00001738, 0x00000000 },
1441 { 0x00001778, 0x00000000 },
1442 { 0x000017b8, 0x00000000 },
1443 { 0x000017f8, 0x00000000 },
1444 { 0x0000103c, 0x00000000 },
1445 { 0x0000107c, 0x00000000 },
1446 { 0x000010bc, 0x00000000 },
1447 { 0x000010fc, 0x00000000 },
1448 { 0x0000113c, 0x00000000 },
1449 { 0x0000117c, 0x00000000 },
1450 { 0x000011bc, 0x00000000 },
1451 { 0x000011fc, 0x00000000 },
1452 { 0x0000123c, 0x00000000 },
1453 { 0x0000127c, 0x00000000 },
1454 { 0x000012bc, 0x00000000 },
1455 { 0x000012fc, 0x00000000 },
1456 { 0x0000133c, 0x00000000 },
1457 { 0x0000137c, 0x00000000 },
1458 { 0x000013bc, 0x00000000 },
1459 { 0x000013fc, 0x00000000 },
1460 { 0x0000143c, 0x00000000 },
1461 { 0x0000147c, 0x00000000 },
1462 { 0x00004030, 0x00000002 },
1463 { 0x0000403c, 0x00000002 },
1464 { 0x00007010, 0x00000020 },
1465 { 0x00007038, 0x000004c2 },
1466 { 0x00008004, 0x00000000 },
1467 { 0x00008008, 0x00000000 },
1468 { 0x0000800c, 0x00000000 },
1469 { 0x00008018, 0x00000700 },
1470 { 0x00008020, 0x00000000 },
1471 { 0x00008038, 0x00000000 },
1472 { 0x0000803c, 0x00000000 },
1473 { 0x00008048, 0x40000000 },
1474 { 0x00008054, 0x00000000 },
1475 { 0x00008058, 0x00000000 },
1476 { 0x0000805c, 0x000fc78f },
1477 { 0x00008060, 0x0000000f },
1478 { 0x00008064, 0x00000000 },
1479 { 0x000080c0, 0x2a82301a },
1480 { 0x000080c4, 0x05dc01e0 },
1481 { 0x000080c8, 0x1f402710 },
1482 { 0x000080cc, 0x01f40000 },
1483 { 0x000080d0, 0x00001e00 },
1484 { 0x000080d4, 0x00000000 },
1485 { 0x000080d8, 0x00400000 },
1486 { 0x000080e0, 0xffffffff },
1487 { 0x000080e4, 0x0000ffff },
1488 { 0x000080e8, 0x003f3f3f },
1489 { 0x000080ec, 0x00000000 },
1490 { 0x000080f0, 0x00000000 },
1491 { 0x000080f4, 0x00000000 },
1492 { 0x000080f8, 0x00000000 },
1493 { 0x000080fc, 0x00020000 },
1494 { 0x00008100, 0x00020000 },
1495 { 0x00008104, 0x00000001 },
1496 { 0x00008108, 0x00000052 },
1497 { 0x0000810c, 0x00000000 },
1498 { 0x00008110, 0x00000168 },
1499 { 0x00008118, 0x000100aa },
1500 { 0x0000811c, 0x00003210 },
1501 { 0x00008120, 0x08f04800 },
1502 { 0x00008124, 0x00000000 },
1503 { 0x00008128, 0x00000000 },
1504 { 0x0000812c, 0x00000000 },
1505 { 0x00008130, 0x00000000 },
1506 { 0x00008134, 0x00000000 },
1507 { 0x00008138, 0x00000000 },
1508 { 0x0000813c, 0x00000000 },
1509 { 0x00008144, 0xffffffff },
1510 { 0x00008168, 0x00000000 },
1511 { 0x0000816c, 0x00000000 },
1512 { 0x00008170, 0x32143320 },
1513 { 0x00008174, 0xfaa4fa50 },
1514 { 0x00008178, 0x00000100 },
1515 { 0x0000817c, 0x00000000 },
1516 { 0x000081c4, 0x00000000 },
1517 { 0x000081d0, 0x00003210 },
1518 { 0x000081ec, 0x00000000 },
1519 { 0x000081f0, 0x00000000 },
1520 { 0x000081f4, 0x00000000 },
1521 { 0x000081f8, 0x00000000 },
1522 { 0x000081fc, 0x00000000 },
1523 { 0x00008200, 0x00000000 },
1524 { 0x00008204, 0x00000000 },
1525 { 0x00008208, 0x00000000 },
1526 { 0x0000820c, 0x00000000 },
1527 { 0x00008210, 0x00000000 },
1528 { 0x00008214, 0x00000000 },
1529 { 0x00008218, 0x00000000 },
1530 { 0x0000821c, 0x00000000 },
1531 { 0x00008220, 0x00000000 },
1532 { 0x00008224, 0x00000000 },
1533 { 0x00008228, 0x00000000 },
1534 { 0x0000822c, 0x00000000 },
1535 { 0x00008230, 0x00000000 },
1536 { 0x00008234, 0x00000000 },
1537 { 0x00008238, 0x00000000 },
1538 { 0x0000823c, 0x00000000 },
1539 { 0x00008240, 0x00100000 },
1540 { 0x00008244, 0x0010f400 },
1541 { 0x00008248, 0x00000100 },
1542 { 0x0000824c, 0x0001e800 },
1543 { 0x00008250, 0x00000000 },
1544 { 0x00008254, 0x00000000 },
1545 { 0x00008258, 0x00000000 },
1546 { 0x0000825c, 0x400000ff },
1547 { 0x00008260, 0x00080922 },
1548 { 0x00008270, 0x00000000 },
1549 { 0x00008274, 0x40000000 },
1550 { 0x00008278, 0x003e4180 },
1551 { 0x0000827c, 0x00000000 },
1552 { 0x00008284, 0x0000002c },
1553 { 0x00008288, 0x0000002c },
1554 { 0x0000828c, 0x00000000 },
1555 { 0x00008294, 0x00000000 },
1556 { 0x00008298, 0x00000000 },
1557 { 0x00008300, 0x00000000 },
1558 { 0x00008304, 0x00000000 },
1559 { 0x00008308, 0x00000000 },
1560 { 0x0000830c, 0x00000000 },
1561 { 0x00008310, 0x00000000 },
1562 { 0x00008314, 0x00000000 },
1563 { 0x00008318, 0x00000000 },
1564 { 0x00008328, 0x00000000 },
1565 { 0x0000832c, 0x00000007 },
1566 { 0x00008330, 0x00000302 },
1567 { 0x00008334, 0x00000e00 },
1568 { 0x00008338, 0x00ff0000 },
1569 { 0x0000833c, 0x00000000 },
1570 { 0x00008340, 0x000107ff },
1571 { 0x00009808, 0x00000000 },
1572 { 0x0000980c, 0xad848e19 },
1573 { 0x00009810, 0x7d14e000 },
1574 { 0x00009814, 0x9c0a9f6b },
1575 { 0x0000981c, 0x00000000 },
1576 { 0x0000982c, 0x0000a000 },
1577 { 0x00009830, 0x00000000 },
1578 { 0x0000983c, 0x00200400 },
1579 { 0x00009840, 0x206a01ae },
1580 { 0x0000984c, 0x1284233c },
1581 { 0x00009854, 0x00000859 },
1582 { 0x00009900, 0x00000000 },
1583 { 0x00009904, 0x00000000 },
1584 { 0x00009908, 0x00000000 },
1585 { 0x0000990c, 0x00000000 },
1586 { 0x0000991c, 0x10000fff },
1587 { 0x00009920, 0x05100000 },
1588 { 0x0000a920, 0x05100000 },
1589 { 0x0000b920, 0x05100000 },
1590 { 0x00009928, 0x00000001 },
1591 { 0x0000992c, 0x00000004 },
1592 { 0x00009934, 0x1e1f2022 },
1593 { 0x00009938, 0x0a0b0c0d },
1594 { 0x0000993c, 0x00000000 },
1595 { 0x00009948, 0x9280b212 },
1596 { 0x0000994c, 0x00020028 },
1597 { 0x00009954, 0x5f3ca3de },
1598 { 0x00009958, 0x2108ecff },
1599 { 0x00009940, 0x00750604 },
1600 { 0x0000c95c, 0x004b6a8e },
1601 { 0x00009970, 0x190fb515 },
1602 { 0x00009974, 0x00000000 },
1603 { 0x00009978, 0x00000001 },
1604 { 0x0000997c, 0x00000000 },
1605 { 0x00009980, 0x00000000 },
1606 { 0x00009984, 0x00000000 },
1607 { 0x00009988, 0x00000000 },
1608 { 0x0000998c, 0x00000000 },
1609 { 0x00009990, 0x00000000 },
1610 { 0x00009994, 0x00000000 },
1611 { 0x00009998, 0x00000000 },
1612 { 0x0000999c, 0x00000000 },
1613 { 0x000099a0, 0x00000000 },
1614 { 0x000099a4, 0x00000001 },
1615 { 0x000099a8, 0x201fff00 },
1616 { 0x000099ac, 0x006f0000 },
1617 { 0x000099b0, 0x03051000 },
1618 { 0x000099dc, 0x00000000 },
1619 { 0x000099e0, 0x00000200 },
1620 { 0x000099e4, 0xaaaaaaaa },
1621 { 0x000099e8, 0x3c466478 },
1622 { 0x000099ec, 0x0cc80caa },
1623 { 0x000099fc, 0x00001042 },
1624 { 0x00009b00, 0x00000000 },
1625 { 0x00009b04, 0x00000001 },
1626 { 0x00009b08, 0x00000002 },
1627 { 0x00009b0c, 0x00000003 },
1628 { 0x00009b10, 0x00000004 },
1629 { 0x00009b14, 0x00000005 },
1630 { 0x00009b18, 0x00000008 },
1631 { 0x00009b1c, 0x00000009 },
1632 { 0x00009b20, 0x0000000a },
1633 { 0x00009b24, 0x0000000b },
1634 { 0x00009b28, 0x0000000c },
1635 { 0x00009b2c, 0x0000000d },
1636 { 0x00009b30, 0x00000010 },
1637 { 0x00009b34, 0x00000011 },
1638 { 0x00009b38, 0x00000012 },
1639 { 0x00009b3c, 0x00000013 },
1640 { 0x00009b40, 0x00000014 },
1641 { 0x00009b44, 0x00000015 },
1642 { 0x00009b48, 0x00000018 },
1643 { 0x00009b4c, 0x00000019 },
1644 { 0x00009b50, 0x0000001a },
1645 { 0x00009b54, 0x0000001b },
1646 { 0x00009b58, 0x0000001c },
1647 { 0x00009b5c, 0x0000001d },
1648 { 0x00009b60, 0x00000020 },
1649 { 0x00009b64, 0x00000021 },
1650 { 0x00009b68, 0x00000022 },
1651 { 0x00009b6c, 0x00000023 },
1652 { 0x00009b70, 0x00000024 },
1653 { 0x00009b74, 0x00000025 },
1654 { 0x00009b78, 0x00000028 },
1655 { 0x00009b7c, 0x00000029 },
1656 { 0x00009b80, 0x0000002a },
1657 { 0x00009b84, 0x0000002b },
1658 { 0x00009b88, 0x0000002c },
1659 { 0x00009b8c, 0x0000002d },
1660 { 0x00009b90, 0x00000030 },
1661 { 0x00009b94, 0x00000031 },
1662 { 0x00009b98, 0x00000032 },
1663 { 0x00009b9c, 0x00000033 },
1664 { 0x00009ba0, 0x00000034 },
1665 { 0x00009ba4, 0x00000035 },
1666 { 0x00009ba8, 0x00000035 },
1667 { 0x00009bac, 0x00000035 },
1668 { 0x00009bb0, 0x00000035 },
1669 { 0x00009bb4, 0x00000035 },
1670 { 0x00009bb8, 0x00000035 },
1671 { 0x00009bbc, 0x00000035 },
1672 { 0x00009bc0, 0x00000035 },
1673 { 0x00009bc4, 0x00000035 },
1674 { 0x00009bc8, 0x00000035 },
1675 { 0x00009bcc, 0x00000035 },
1676 { 0x00009bd0, 0x00000035 },
1677 { 0x00009bd4, 0x00000035 },
1678 { 0x00009bd8, 0x00000035 },
1679 { 0x00009bdc, 0x00000035 },
1680 { 0x00009be0, 0x00000035 },
1681 { 0x00009be4, 0x00000035 },
1682 { 0x00009be8, 0x00000035 },
1683 { 0x00009bec, 0x00000035 },
1684 { 0x00009bf0, 0x00000035 },
1685 { 0x00009bf4, 0x00000035 },
1686 { 0x00009bf8, 0x00000010 },
1687 { 0x00009bfc, 0x0000001a },
1688 { 0x0000a210, 0x40806333 },
1689 { 0x0000a214, 0x00106c10 },
1690 { 0x0000a218, 0x009c4060 },
1691 { 0x0000a220, 0x018830c6 },
1692 { 0x0000a224, 0x00000400 },
1693 { 0x0000a228, 0x001a0bb5 },
1694 { 0x0000a22c, 0x00000000 },
1695 { 0x0000a234, 0x20202020 },
1696 { 0x0000a238, 0x20202020 },
1697 { 0x0000a23c, 0x13c889af },
1698 { 0x0000a240, 0x38490a20 },
1699 { 0x0000a244, 0x00007bb6 },
1700 { 0x0000a248, 0x0fff3ffc },
1701 { 0x0000a24c, 0x00000001 },
1702 { 0x0000a250, 0x0000e000 },
1703 { 0x0000a254, 0x00000000 },
1704 { 0x0000a258, 0x0cc75380 },
1705 { 0x0000a25c, 0x0f0f0f01 },
1706 { 0x0000a260, 0xdfa91f01 },
1707 { 0x0000a268, 0x00000001 },
1708 { 0x0000a26c, 0x0ebae9c6 },
1709 { 0x0000b26c, 0x0ebae9c6 },
1710 { 0x0000c26c, 0x0ebae9c6 },
1711 { 0x0000d270, 0x00820820 },
1712 { 0x0000a278, 0x1ce739ce },
1713 { 0x0000a27c, 0x050701ce },
1714 { 0x0000a338, 0x00000000 },
1715 { 0x0000a33c, 0x00000000 },
1716 { 0x0000a340, 0x00000000 },
1717 { 0x0000a344, 0x00000000 },
1718 { 0x0000a348, 0x3fffffff },
1719 { 0x0000a34c, 0x3fffffff },
1720 { 0x0000a350, 0x3fffffff },
1721 { 0x0000a354, 0x0003ffff },
1722 { 0x0000a358, 0x79bfaa03 },
1723 { 0x0000d35c, 0x07ffffef },
1724 { 0x0000d360, 0x0fffffe7 },
1725 { 0x0000d364, 0x17ffffe5 },
1726 { 0x0000d368, 0x1fffffe4 },
1727 { 0x0000d36c, 0x37ffffe3 },
1728 { 0x0000d370, 0x3fffffe3 },
1729 { 0x0000d374, 0x57ffffe3 },
1730 { 0x0000d378, 0x5fffffe2 },
1731 { 0x0000d37c, 0x7fffffe2 },
1732 { 0x0000d380, 0x7f3c7bba },
1733 { 0x0000d384, 0xf3307ff0 },
1734 { 0x0000a388, 0x0c000000 },
1735 { 0x0000a38c, 0x20202020 },
1736 { 0x0000a390, 0x20202020 },
1737 { 0x0000a394, 0x1ce739ce },
1738 { 0x0000a398, 0x000001ce },
1739 { 0x0000a39c, 0x00000001 },
1740 { 0x0000a3a0, 0x00000000 },
1741 { 0x0000a3a4, 0x00000000 },
1742 { 0x0000a3a8, 0x00000000 },
1743 { 0x0000a3ac, 0x00000000 },
1744 { 0x0000a3b0, 0x00000000 },
1745 { 0x0000a3b4, 0x00000000 },
1746 { 0x0000a3b8, 0x00000000 },
1747 { 0x0000a3bc, 0x00000000 },
1748 { 0x0000a3c0, 0x00000000 },
1749 { 0x0000a3c4, 0x00000000 },
1750 { 0x0000a3c8, 0x00000246 },
1751 { 0x0000a3cc, 0x20202020 },
1752 { 0x0000a3d0, 0x20202020 },
1753 { 0x0000a3d4, 0x20202020 },
1754 { 0x0000a3dc, 0x1ce739ce },
1755 { 0x0000a3e0, 0x000001ce },
1756};
1757
1758static const u32 ar5416Bank0_9160[][2] = {
1759 { 0x000098b0, 0x1e5795e5 },
1760 { 0x000098e0, 0x02008020 },
1761};
1762
1763static const u32 ar5416BB_RfGain_9160[][3] = {
1764 { 0x00009a00, 0x00000000, 0x00000000 },
1765 { 0x00009a04, 0x00000040, 0x00000040 },
1766 { 0x00009a08, 0x00000080, 0x00000080 },
1767 { 0x00009a0c, 0x000001a1, 0x00000141 },
1768 { 0x00009a10, 0x000001e1, 0x00000181 },
1769 { 0x00009a14, 0x00000021, 0x000001c1 },
1770 { 0x00009a18, 0x00000061, 0x00000001 },
1771 { 0x00009a1c, 0x00000168, 0x00000041 },
1772 { 0x00009a20, 0x000001a8, 0x000001a8 },
1773 { 0x00009a24, 0x000001e8, 0x000001e8 },
1774 { 0x00009a28, 0x00000028, 0x00000028 },
1775 { 0x00009a2c, 0x00000068, 0x00000068 },
1776 { 0x00009a30, 0x00000189, 0x000000a8 },
1777 { 0x00009a34, 0x000001c9, 0x00000169 },
1778 { 0x00009a38, 0x00000009, 0x000001a9 },
1779 { 0x00009a3c, 0x00000049, 0x000001e9 },
1780 { 0x00009a40, 0x00000089, 0x00000029 },
1781 { 0x00009a44, 0x00000170, 0x00000069 },
1782 { 0x00009a48, 0x000001b0, 0x00000190 },
1783 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1784 { 0x00009a50, 0x00000030, 0x00000010 },
1785 { 0x00009a54, 0x00000070, 0x00000050 },
1786 { 0x00009a58, 0x00000191, 0x00000090 },
1787 { 0x00009a5c, 0x000001d1, 0x00000151 },
1788 { 0x00009a60, 0x00000011, 0x00000191 },
1789 { 0x00009a64, 0x00000051, 0x000001d1 },
1790 { 0x00009a68, 0x00000091, 0x00000011 },
1791 { 0x00009a6c, 0x000001b8, 0x00000051 },
1792 { 0x00009a70, 0x000001f8, 0x00000198 },
1793 { 0x00009a74, 0x00000038, 0x000001d8 },
1794 { 0x00009a78, 0x00000078, 0x00000018 },
1795 { 0x00009a7c, 0x00000199, 0x00000058 },
1796 { 0x00009a80, 0x000001d9, 0x00000098 },
1797 { 0x00009a84, 0x00000019, 0x00000159 },
1798 { 0x00009a88, 0x00000059, 0x00000199 },
1799 { 0x00009a8c, 0x00000099, 0x000001d9 },
1800 { 0x00009a90, 0x000000d9, 0x00000019 },
1801 { 0x00009a94, 0x000000f9, 0x00000059 },
1802 { 0x00009a98, 0x000000f9, 0x00000099 },
1803 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1804 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1805 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1806 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1807 { 0x00009aac, 0x000000f9, 0x000000f9 },
1808 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1809 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1810 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1811 { 0x00009abc, 0x000000f9, 0x000000f9 },
1812 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1813 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1814 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1815 { 0x00009acc, 0x000000f9, 0x000000f9 },
1816 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1817 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1818 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1819 { 0x00009adc, 0x000000f9, 0x000000f9 },
1820 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1821 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1822 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1823 { 0x00009aec, 0x000000f9, 0x000000f9 },
1824 { 0x00009af0, 0x000000f9, 0x000000f9 },
1825 { 0x00009af4, 0x000000f9, 0x000000f9 },
1826 { 0x00009af8, 0x000000f9, 0x000000f9 },
1827 { 0x00009afc, 0x000000f9, 0x000000f9 },
1828};
1829
1830static const u32 ar5416Bank1_9160[][2] = {
1831 { 0x000098b0, 0x02108421 },
1832 { 0x000098ec, 0x00000008 },
1833};
1834
1835static const u32 ar5416Bank2_9160[][2] = {
1836 { 0x000098b0, 0x0e73ff17 },
1837 { 0x000098e0, 0x00000420 },
1838};
1839
1840static const u32 ar5416Bank3_9160[][3] = {
1841 { 0x000098f0, 0x01400018, 0x01c00018 },
1842};
1843
1844static const u32 ar5416Bank6_9160[][3] = {
1845 { 0x0000989c, 0x00000000, 0x00000000 },
1846 { 0x0000989c, 0x00000000, 0x00000000 },
1847 { 0x0000989c, 0x00000000, 0x00000000 },
1848 { 0x0000989c, 0x00e00000, 0x00e00000 },
1849 { 0x0000989c, 0x005e0000, 0x005e0000 },
1850 { 0x0000989c, 0x00120000, 0x00120000 },
1851 { 0x0000989c, 0x00620000, 0x00620000 },
1852 { 0x0000989c, 0x00020000, 0x00020000 },
1853 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1854 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1855 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1856 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1857 { 0x0000989c, 0x005f0000, 0x005f0000 },
1858 { 0x0000989c, 0x00870000, 0x00870000 },
1859 { 0x0000989c, 0x00f90000, 0x00f90000 },
1860 { 0x0000989c, 0x007b0000, 0x007b0000 },
1861 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1862 { 0x0000989c, 0x00f50000, 0x00f50000 },
1863 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1864 { 0x0000989c, 0x00110000, 0x00110000 },
1865 { 0x0000989c, 0x006100a8, 0x006100a8 },
1866 { 0x0000989c, 0x004210a2, 0x004210a2 },
1867 { 0x0000989c, 0x0014008f, 0x0014008f },
1868 { 0x0000989c, 0x00c40003, 0x00c40003 },
1869 { 0x0000989c, 0x003000f2, 0x003000f2 },
1870 { 0x0000989c, 0x00440016, 0x00440016 },
1871 { 0x0000989c, 0x00410040, 0x00410040 },
1872 { 0x0000989c, 0x0001805e, 0x0001805e },
1873 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1874 { 0x0000989c, 0x000000f1, 0x000000f1 },
1875 { 0x0000989c, 0x00002081, 0x00002081 },
1876 { 0x0000989c, 0x000000d4, 0x000000d4 },
1877 { 0x000098d0, 0x0000000f, 0x0010000f },
1878};
1879
1880static const u32 ar5416Bank6TPC_9160[][3] = {
1881 { 0x0000989c, 0x00000000, 0x00000000 },
1882 { 0x0000989c, 0x00000000, 0x00000000 },
1883 { 0x0000989c, 0x00000000, 0x00000000 },
1884 { 0x0000989c, 0x00e00000, 0x00e00000 },
1885 { 0x0000989c, 0x005e0000, 0x005e0000 },
1886 { 0x0000989c, 0x00120000, 0x00120000 },
1887 { 0x0000989c, 0x00620000, 0x00620000 },
1888 { 0x0000989c, 0x00020000, 0x00020000 },
1889 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1890 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1891 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1892 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1893 { 0x0000989c, 0x005f0000, 0x005f0000 },
1894 { 0x0000989c, 0x00870000, 0x00870000 },
1895 { 0x0000989c, 0x00f90000, 0x00f90000 },
1896 { 0x0000989c, 0x007b0000, 0x007b0000 },
1897 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1898 { 0x0000989c, 0x00f50000, 0x00f50000 },
1899 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1900 { 0x0000989c, 0x00110000, 0x00110000 },
1901 { 0x0000989c, 0x006100a8, 0x006100a8 },
1902 { 0x0000989c, 0x00423022, 0x00423022 },
1903 { 0x0000989c, 0x2014008f, 0x2014008f },
1904 { 0x0000989c, 0x00c40002, 0x00c40002 },
1905 { 0x0000989c, 0x003000f2, 0x003000f2 },
1906 { 0x0000989c, 0x00440016, 0x00440016 },
1907 { 0x0000989c, 0x00410040, 0x00410040 },
1908 { 0x0000989c, 0x0001805e, 0x0001805e },
1909 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1910 { 0x0000989c, 0x000000e1, 0x000000e1 },
1911 { 0x0000989c, 0x00007080, 0x00007080 },
1912 { 0x0000989c, 0x000000d4, 0x000000d4 },
1913 { 0x000098d0, 0x0000000f, 0x0010000f },
1914};
1915
1916static const u32 ar5416Bank7_9160[][2] = {
1917 { 0x0000989c, 0x00000500 },
1918 { 0x0000989c, 0x00000800 },
1919 { 0x000098cc, 0x0000000e },
1920};
1921 19
1922static u32 ar5416Addac_9160[][2] = {
1923 {0x0000989c, 0x00000000 },
1924 {0x0000989c, 0x00000000 },
1925 {0x0000989c, 0x00000000 },
1926 {0x0000989c, 0x00000000 },
1927 {0x0000989c, 0x00000000 },
1928 {0x0000989c, 0x00000000 },
1929 {0x0000989c, 0x000000c0 },
1930 {0x0000989c, 0x00000018 },
1931 {0x0000989c, 0x00000004 },
1932 {0x0000989c, 0x00000000 },
1933 {0x0000989c, 0x00000000 },
1934 {0x0000989c, 0x00000000 },
1935 {0x0000989c, 0x00000000 },
1936 {0x0000989c, 0x00000000 },
1937 {0x0000989c, 0x00000000 },
1938 {0x0000989c, 0x00000000 },
1939 {0x0000989c, 0x00000000 },
1940 {0x0000989c, 0x00000000 },
1941 {0x0000989c, 0x00000000 },
1942 {0x0000989c, 0x00000000 },
1943 {0x0000989c, 0x00000000 },
1944 {0x0000989c, 0x000000c0 },
1945 {0x0000989c, 0x00000019 },
1946 {0x0000989c, 0x00000004 },
1947 {0x0000989c, 0x00000000 },
1948 {0x0000989c, 0x00000000 },
1949 {0x0000989c, 0x00000000 },
1950 {0x0000989c, 0x00000004 },
1951 {0x0000989c, 0x00000003 },
1952 {0x0000989c, 0x00000008 },
1953 {0x0000989c, 0x00000000 },
1954 {0x000098cc, 0x00000000 },
1955};
1956
1957static u32 ar5416Addac_91601_1[][2] = {
1958 {0x0000989c, 0x00000000 },
1959 {0x0000989c, 0x00000000 },
1960 {0x0000989c, 0x00000000 },
1961 {0x0000989c, 0x00000000 },
1962 {0x0000989c, 0x00000000 },
1963 {0x0000989c, 0x00000000 },
1964 {0x0000989c, 0x000000c0 },
1965 {0x0000989c, 0x00000018 },
1966 {0x0000989c, 0x00000004 },
1967 {0x0000989c, 0x00000000 },
1968 {0x0000989c, 0x00000000 },
1969 {0x0000989c, 0x00000000 },
1970 {0x0000989c, 0x00000000 },
1971 {0x0000989c, 0x00000000 },
1972 {0x0000989c, 0x00000000 },
1973 {0x0000989c, 0x00000000 },
1974 {0x0000989c, 0x00000000 },
1975 {0x0000989c, 0x00000000 },
1976 {0x0000989c, 0x00000000 },
1977 {0x0000989c, 0x00000000 },
1978 {0x0000989c, 0x00000000 },
1979 {0x0000989c, 0x000000c0 },
1980 {0x0000989c, 0x00000019 },
1981 {0x0000989c, 0x00000004 },
1982 {0x0000989c, 0x00000000 },
1983 {0x0000989c, 0x00000000 },
1984 {0x0000989c, 0x00000000 },
1985 {0x0000989c, 0x00000000 },
1986 {0x0000989c, 0x00000000 },
1987 {0x0000989c, 0x00000000 },
1988 {0x0000989c, 0x00000000 },
1989 {0x000098cc, 0x00000000 },
1990};
1991
1992/* XXX 9280 1 */
1993static const u32 ar9280Modes_9280[][6] = { 20static const u32 ar9280Modes_9280[][6] = {
1994 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 21 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1995 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 22 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -2766,7 +793,7 @@ static const u32 ar9280Common_9280_2[][2] = {
2766 { 0x00008258, 0x00000000 }, 793 { 0x00008258, 0x00000000 },
2767 { 0x0000825c, 0x400000ff }, 794 { 0x0000825c, 0x400000ff },
2768 { 0x00008260, 0x00080922 }, 795 { 0x00008260, 0x00080922 },
2769 { 0x00008264, 0xa8a00010 }, 796 { 0x00008264, 0x88a00010 },
2770 { 0x00008270, 0x00000000 }, 797 { 0x00008270, 0x00000000 },
2771 { 0x00008274, 0x40000000 }, 798 { 0x00008274, 0x40000000 },
2772 { 0x00008278, 0x003e4180 }, 799 { 0x00008278, 0x003e4180 },
@@ -3441,7 +1468,7 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
3441}; 1468};
3442 1469
3443/* AR9285 Revsion 10*/ 1470/* AR9285 Revsion 10*/
3444static const u_int32_t ar9285Modes_9285[][6] = { 1471static const u32 ar9285Modes_9285[][6] = {
3445 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 1472 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
3446 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 1473 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
3447 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, 1474 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -3763,7 +1790,7 @@ static const u_int32_t ar9285Modes_9285[][6] = {
3763 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 1790 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
3764}; 1791};
3765 1792
3766static const u_int32_t ar9285Common_9285[][2] = { 1793static const u32 ar9285Common_9285[][2] = {
3767 { 0x0000000c, 0x00000000 }, 1794 { 0x0000000c, 0x00000000 },
3768 { 0x00000030, 0x00020045 }, 1795 { 0x00000030, 0x00020045 },
3769 { 0x00000034, 0x00000005 }, 1796 { 0x00000034, 0x00000005 },
@@ -3936,7 +1963,7 @@ static const u_int32_t ar9285Common_9285[][2] = {
3936 { 0x00008258, 0x00000000 }, 1963 { 0x00008258, 0x00000000 },
3937 { 0x0000825c, 0x400000ff }, 1964 { 0x0000825c, 0x400000ff },
3938 { 0x00008260, 0x00080922 }, 1965 { 0x00008260, 0x00080922 },
3939 { 0x00008264, 0xa8a00010 }, 1966 { 0x00008264, 0x88a00010 },
3940 { 0x00008270, 0x00000000 }, 1967 { 0x00008270, 0x00000000 },
3941 { 0x00008274, 0x40000000 }, 1968 { 0x00008274, 0x40000000 },
3942 { 0x00008278, 0x003e4180 }, 1969 { 0x00008278, 0x003e4180 },
@@ -4096,7 +2123,7 @@ static const u_int32_t ar9285Common_9285[][2] = {
4096 { 0x00007870, 0x10142c00 }, 2123 { 0x00007870, 0x10142c00 },
4097}; 2124};
4098 2125
4099static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { 2126static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
4100 {0x00004040, 0x9248fd00 }, 2127 {0x00004040, 0x9248fd00 },
4101 {0x00004040, 0x24924924 }, 2128 {0x00004040, 0x24924924 },
4102 {0x00004040, 0xa8000019 }, 2129 {0x00004040, 0xa8000019 },
@@ -4109,7 +2136,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
4109 {0x00004044, 0x00000000 }, 2136 {0x00004044, 0x00000000 },
4110}; 2137};
4111 2138
4112static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = { 2139static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
4113 {0x00004040, 0x9248fd00 }, 2140 {0x00004040, 0x9248fd00 },
4114 {0x00004040, 0x24924924 }, 2141 {0x00004040, 0x24924924 },
4115 {0x00004040, 0xa8000019 }, 2142 {0x00004040, 0xa8000019 },
@@ -4123,7 +2150,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
4123}; 2150};
4124 2151
4125/* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */ 2152/* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */
4126static const u_int32_t ar9285Modes_9285_1_2[][6] = { 2153static const u32 ar9285Modes_9285_1_2[][6] = {
4127 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 2154 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4128 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 2155 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
4129 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 2156 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4184,7 +2211,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4184 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 2211 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
4185 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 2212 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
4186 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 2213 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
4187 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 2214 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
4188 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 2215 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
4189 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 2216 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
4190 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 2217 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -4198,8 +2225,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4198 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 2225 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
4199 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 2226 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
4200 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 2227 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
4201 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 2228 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
4202 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 2229 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
4203 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 2230 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
4204 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 2231 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
4205 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 2232 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -4312,7 +2339,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4312 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 2339 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
4313 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 2340 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
4314 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 2341 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
4315 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 2342 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
4316 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 2343 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
4317 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 2344 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
4318 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 2345 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -4326,8 +2353,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4326 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 2353 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
4327 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 2354 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
4328 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 2355 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
4329 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 2356 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
4330 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 2357 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
4331 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 2358 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
4332 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 2359 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
4333 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 2360 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -4429,7 +2456,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4429 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 2456 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
4430}; 2457};
4431 2458
4432static const u_int32_t ar9285Common_9285_1_2[][2] = { 2459static const u32 ar9285Common_9285_1_2[][2] = {
4433 { 0x0000000c, 0x00000000 }, 2460 { 0x0000000c, 0x00000000 },
4434 { 0x00000030, 0x00020045 }, 2461 { 0x00000030, 0x00020045 },
4435 { 0x00000034, 0x00000005 }, 2462 { 0x00000034, 0x00000005 },
@@ -4731,17 +2758,12 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
4731 { 0x00007808, 0x54214514 }, 2758 { 0x00007808, 0x54214514 },
4732 { 0x0000780c, 0x02025830 }, 2759 { 0x0000780c, 0x02025830 },
4733 { 0x00007810, 0x71c0d388 }, 2760 { 0x00007810, 0x71c0d388 },
4734 { 0x00007814, 0x924934a8 },
4735 { 0x0000781c, 0x00000000 }, 2761 { 0x0000781c, 0x00000000 },
4736 { 0x00007824, 0x00d86fff }, 2762 { 0x00007824, 0x00d86fff },
4737 { 0x00007828, 0x26d2491b },
4738 { 0x0000782c, 0x6e36d97b }, 2763 { 0x0000782c, 0x6e36d97b },
4739 { 0x00007830, 0xedb6d96e },
4740 { 0x00007834, 0x71400087 }, 2764 { 0x00007834, 0x71400087 },
4741 { 0x0000783c, 0x0001fffe },
4742 { 0x00007840, 0xffeb1a20 },
4743 { 0x00007844, 0x000c0db6 }, 2765 { 0x00007844, 0x000c0db6 },
4744 { 0x00007848, 0x6db61b6f }, 2766 { 0x00007848, 0x6db6246f },
4745 { 0x0000784c, 0x6d9b66db }, 2767 { 0x0000784c, 0x6d9b66db },
4746 { 0x00007850, 0x6d8c6dba }, 2768 { 0x00007850, 0x6d8c6dba },
4747 { 0x00007854, 0x00040000 }, 2769 { 0x00007854, 0x00040000 },
@@ -4753,7 +2775,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
4753 { 0x00007870, 0x10142c00 }, 2775 { 0x00007870, 0x10142c00 },
4754}; 2776};
4755 2777
4756static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { 2778static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4757 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 2779 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4758 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 2780 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4759 { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, 2781 { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
@@ -4777,7 +2799,12 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4777 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2799 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4778 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2800 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4779 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2801 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2802 { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 },
2803 { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b },
2804 { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e },
4780 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, 2805 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
2806 { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe },
2807 { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 },
4781 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, 2808 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
4782 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, 2809 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
4783 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, 2810 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
@@ -4789,7 +2816,7 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4789 { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, 2816 { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
4790}; 2817};
4791 2818
4792static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { 2819static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = {
4793 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 2820 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4794 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 2821 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4795 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, 2822 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
@@ -4813,7 +2840,52 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
4813 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2840 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4814 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2841 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
4815 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, 2842 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2843 { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 },
2844 { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b },
2845 { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e },
4816 { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, 2846 { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
2847 { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe },
2848 { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 },
2849 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
2850 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
2851 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
2852 { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
2853 { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
2854 { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
2855 { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
2856 { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
2857 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
2858};
2859
2860static const u32 ar9285Modes_XE2_0_normal_power[][6] = {
2861 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2862 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
2863 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
2864 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
2865 { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
2866 { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
2867 { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
2868 { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
2869 { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
2870 { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
2871 { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
2872 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
2873 { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
2874 { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
2875 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
2876 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
2877 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2878 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2879 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2880 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2881 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2882 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2883 { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 },
2884 { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b },
2885 { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae },
2886 { 0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441 },
2887 { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe },
2888 { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c },
4817 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, 2889 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
4818 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, 2890 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
4819 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, 2891 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
@@ -4825,7 +2897,47 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
4825 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, 2897 { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
4826}; 2898};
4827 2899
4828static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { 2900static const u32 ar9285Modes_XE2_0_high_power[][6] = {
2901 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2902 { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
2903 { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
2904 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
2905 { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
2906 { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 },
2907 { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 },
2908 { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 },
2909 { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 },
2910 { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 },
2911 { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 },
2912 { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
2913 { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 },
2914 { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
2915 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
2916 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
2917 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2918 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2919 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2920 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2921 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2922 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
2923 { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 },
2924 { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b },
2925 { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e },
2926 { 0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443 },
2927 { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe },
2928 { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c },
2929 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
2930 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
2931 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
2932 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
2933 { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 },
2934 { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
2935 { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
2936 { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
2937 { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
2938};
2939
2940static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
4829 {0x00004040, 0x9248fd00 }, 2941 {0x00004040, 0x9248fd00 },
4830 {0x00004040, 0x24924924 }, 2942 {0x00004040, 0x24924924 },
4831 {0x00004040, 0xa8000019 }, 2943 {0x00004040, 0xa8000019 },
@@ -4838,7 +2950,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
4838 {0x00004044, 0x00000000 }, 2950 {0x00004044, 0x00000000 },
4839}; 2951};
4840 2952
4841static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { 2953static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
4842 {0x00004040, 0x9248fd00 }, 2954 {0x00004040, 0x9248fd00 },
4843 {0x00004040, 0x24924924 }, 2955 {0x00004040, 0x24924924 },
4844 {0x00004040, 0xa8000019 }, 2956 {0x00004040, 0xa8000019 },
@@ -4852,7 +2964,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
4852}; 2964};
4853 2965
4854/* AR9287 Revision 10 */ 2966/* AR9287 Revision 10 */
4855static const u_int32_t ar9287Modes_9287_1_0[][6] = { 2967static const u32 ar9287Modes_9287_1_0[][6] = {
4856 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 2968 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4857 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, 2969 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
4858 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, 2970 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4899,7 +3011,7 @@ static const u_int32_t ar9287Modes_9287_1_0[][6] = {
4899 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 3011 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4900}; 3012};
4901 3013
4902static const u_int32_t ar9287Common_9287_1_0[][2] = { 3014static const u32 ar9287Common_9287_1_0[][2] = {
4903 { 0x0000000c, 0x00000000 }, 3015 { 0x0000000c, 0x00000000 },
4904 { 0x00000030, 0x00020015 }, 3016 { 0x00000030, 0x00020015 },
4905 { 0x00000034, 0x00000005 }, 3017 { 0x00000034, 0x00000005 },
@@ -5073,7 +3185,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = {
5073 { 0x00008258, 0x00000000 }, 3185 { 0x00008258, 0x00000000 },
5074 { 0x0000825c, 0x400000ff }, 3186 { 0x0000825c, 0x400000ff },
5075 { 0x00008260, 0x00080922 }, 3187 { 0x00008260, 0x00080922 },
5076 { 0x00008264, 0xa8a00010 }, 3188 { 0x00008264, 0x88a00010 },
5077 { 0x00008270, 0x00000000 }, 3189 { 0x00008270, 0x00000000 },
5078 { 0x00008274, 0x40000000 }, 3190 { 0x00008274, 0x40000000 },
5079 { 0x00008278, 0x003e4180 }, 3191 { 0x00008278, 0x003e4180 },
@@ -5270,7 +3382,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = {
5270 { 0x000078b8, 0x2a850160 }, 3382 { 0x000078b8, 0x2a850160 },
5271}; 3383};
5272 3384
5273static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = { 3385static const u32 ar9287Modes_tx_gain_9287_1_0[][6] = {
5274 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 3386 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5275 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 3387 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5276 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, 3388 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
@@ -5320,7 +3432,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = {
5320}; 3432};
5321 3433
5322 3434
5323static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = { 3435static const u32 ar9287Modes_rx_gain_9287_1_0[][6] = {
5324 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 3436 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5325 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, 3437 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
5326 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, 3438 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
@@ -5582,7 +3694,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = {
5582 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, 3694 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
5583}; 3695};
5584 3696
5585static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { 3697static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
5586 {0x00004040, 0x9248fd00 }, 3698 {0x00004040, 0x9248fd00 },
5587 {0x00004040, 0x24924924 }, 3699 {0x00004040, 0x24924924 },
5588 {0x00004040, 0xa8000019 }, 3700 {0x00004040, 0xa8000019 },
@@ -5595,7 +3707,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
5595 {0x00004044, 0x00000000 }, 3707 {0x00004044, 0x00000000 },
5596}; 3708};
5597 3709
5598static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { 3710static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
5599 {0x00004040, 0x9248fd00 }, 3711 {0x00004040, 0x9248fd00 },
5600 {0x00004040, 0x24924924 }, 3712 {0x00004040, 0x24924924 },
5601 {0x00004040, 0xa8000019 }, 3713 {0x00004040, 0xa8000019 },
@@ -5610,7 +3722,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
5610 3722
5611/* AR9287 Revision 11 */ 3723/* AR9287 Revision 11 */
5612 3724
5613static const u_int32_t ar9287Modes_9287_1_1[][6] = { 3725static const u32 ar9287Modes_9287_1_1[][6] = {
5614 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 3726 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5615 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, 3727 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
5616 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, 3728 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -5657,7 +3769,7 @@ static const u_int32_t ar9287Modes_9287_1_1[][6] = {
5657 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 3769 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5658}; 3770};
5659 3771
5660static const u_int32_t ar9287Common_9287_1_1[][2] = { 3772static const u32 ar9287Common_9287_1_1[][2] = {
5661 { 0x0000000c, 0x00000000 }, 3773 { 0x0000000c, 0x00000000 },
5662 { 0x00000030, 0x00020015 }, 3774 { 0x00000030, 0x00020015 },
5663 { 0x00000034, 0x00000005 }, 3775 { 0x00000034, 0x00000005 },
@@ -6027,21 +4139,22 @@ static const u_int32_t ar9287Common_9287_1_1[][2] = {
6027 4139
6028/* 4140/*
6029 * For Japanese regulatory requirements, 2484 MHz requires the following three 4141 * For Japanese regulatory requirements, 2484 MHz requires the following three
6030 * registers be programmed differently from the channel between 2412 and 2472 MHz. 4142 * registers be programmed differently from the channel between 2412 and
4143 * 2472 MHz.
6031 */ 4144 */
6032static const u_int32_t ar9287Common_normal_cck_fir_coeff_92871_1[][2] = { 4145static const u32 ar9287Common_normal_cck_fir_coeff_92871_1[][2] = {
6033 { 0x0000a1f4, 0x00fffeff }, 4146 { 0x0000a1f4, 0x00fffeff },
6034 { 0x0000a1f8, 0x00f5f9ff }, 4147 { 0x0000a1f8, 0x00f5f9ff },
6035 { 0x0000a1fc, 0xb79f6427 }, 4148 { 0x0000a1fc, 0xb79f6427 },
6036}; 4149};
6037 4150
6038static const u_int32_t ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = { 4151static const u32 ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = {
6039 { 0x0000a1f4, 0x00000000 }, 4152 { 0x0000a1f4, 0x00000000 },
6040 { 0x0000a1f8, 0xefff0301 }, 4153 { 0x0000a1f8, 0xefff0301 },
6041 { 0x0000a1fc, 0xca9228ee }, 4154 { 0x0000a1fc, 0xca9228ee },
6042}; 4155};
6043 4156
6044static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = { 4157static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = {
6045 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 4158 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
6046 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 4159 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6047 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, 4160 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
@@ -6090,7 +4203,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
6090 { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 }, 4203 { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
6091}; 4204};
6092 4205
6093static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = { 4206static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = {
6094 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 4207 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
6095 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, 4208 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
6096 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, 4209 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
@@ -6352,7 +4465,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
6352 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, 4465 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
6353}; 4466};
6354 4467
6355static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { 4468static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
6356 {0x00004040, 0x9248fd00 }, 4469 {0x00004040, 0x9248fd00 },
6357 {0x00004040, 0x24924924 }, 4470 {0x00004040, 0x24924924 },
6358 {0x00004040, 0xa8000019 }, 4471 {0x00004040, 0xa8000019 },
@@ -6365,7 +4478,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
6365 {0x00004044, 0x00000000 }, 4478 {0x00004044, 0x00000000 },
6366}; 4479};
6367 4480
6368static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { 4481static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
6369 {0x00004040, 0x9248fd00 }, 4482 {0x00004040, 0x9248fd00 },
6370 {0x00004040, 0x24924924 }, 4483 {0x00004040, 0x24924924 },
6371 {0x00004040, 0xa8000019 }, 4484 {0x00004040, 0xa8000019 },
@@ -6380,7 +4493,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
6380 4493
6381 4494
6382/* AR9271 initialization values automaticaly created: 06/04/09 */ 4495/* AR9271 initialization values automaticaly created: 06/04/09 */
6383static const u_int32_t ar9271Modes_9271[][6] = { 4496static const u32 ar9271Modes_9271[][6] = {
6384 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 4497 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
6385 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 4498 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
6386 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, 4499 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -6441,7 +4554,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 4554 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 4555 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 4556 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 4557 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 4558 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 4559 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 4560 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6455,8 +4568,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 4568 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 4569 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 4570 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 4571 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4572 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4573 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 4574 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 4575 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6569,7 +4682,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 4682 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 4683 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 4684 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 4685 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 4686 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 4687 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 4688 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6583,8 +4696,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 4696 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 4697 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 4698 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 4699 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4700 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 4701 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 4702 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 4703 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6683,29 +4796,10 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, 4796 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, 4797 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, 4798 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
6686 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
6687 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6688 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
6689 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
6690 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
6691 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
6692 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
6693 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
6694 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
6695 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
6696 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
6697 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
6698 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
6699 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
6700 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
6701 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
6702 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
6703 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6704 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6705 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 4799 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
6706}; 4800};
6707 4801
6708static const u_int32_t ar9271Common_9271[][2] = { 4802static const u32 ar9271Common_9271[][2] = {
6709 { 0x0000000c, 0x00000000 }, 4803 { 0x0000000c, 0x00000000 },
6710 { 0x00000030, 0x00020045 }, 4804 { 0x00000030, 0x00020045 },
6711 { 0x00000034, 0x00000005 }, 4805 { 0x00000034, 0x00000005 },
@@ -6910,13 +5004,10 @@ static const u_int32_t ar9271Common_9271[][2] = {
6910 { 0x00007810, 0x71c0d388 }, 5004 { 0x00007810, 0x71c0d388 },
6911 { 0x00007814, 0x924934a8 }, 5005 { 0x00007814, 0x924934a8 },
6912 { 0x0000781c, 0x00000000 }, 5006 { 0x0000781c, 0x00000000 },
6913 { 0x00007820, 0x00000c04 },
6914 { 0x00007824, 0x00d8abff },
6915 { 0x00007828, 0x66964300 }, 5007 { 0x00007828, 0x66964300 },
6916 { 0x0000782c, 0x8db6d961 }, 5008 { 0x0000782c, 0x8db6d961 },
6917 { 0x00007830, 0x8db6d96c }, 5009 { 0x00007830, 0x8db6d96c },
6918 { 0x00007834, 0x6140008b }, 5010 { 0x00007834, 0x6140008b },
6919 { 0x00007838, 0x00000029 },
6920 { 0x0000783c, 0x72ee0a72 }, 5011 { 0x0000783c, 0x72ee0a72 },
6921 { 0x00007840, 0xbbfffffc }, 5012 { 0x00007840, 0xbbfffffc },
6922 { 0x00007844, 0x000c0db6 }, 5013 { 0x00007844, 0x000c0db6 },
@@ -6929,7 +5020,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6929 { 0x00007860, 0x21084210 }, 5020 { 0x00007860, 0x21084210 },
6930 { 0x00007864, 0xf7d7ffde }, 5021 { 0x00007864, 0xf7d7ffde },
6931 { 0x00007868, 0xc2034080 }, 5022 { 0x00007868, 0xc2034080 },
6932 { 0x0000786c, 0x48609eb4 },
6933 { 0x00007870, 0x10142c00 }, 5023 { 0x00007870, 0x10142c00 },
6934 { 0x00009808, 0x00000000 }, 5024 { 0x00009808, 0x00000000 },
6935 { 0x0000980c, 0xafe68e30 }, 5025 { 0x0000980c, 0xafe68e30 },
@@ -6982,9 +5072,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6982 { 0x000099e8, 0x3c466478 }, 5072 { 0x000099e8, 0x3c466478 },
6983 { 0x000099ec, 0x0cc80caa }, 5073 { 0x000099ec, 0x0cc80caa },
6984 { 0x000099f0, 0x00000000 }, 5074 { 0x000099f0, 0x00000000 },
6985 { 0x0000a1f4, 0x00000000 },
6986 { 0x0000a1f8, 0x71733d01 },
6987 { 0x0000a1fc, 0xd0ad5c12 },
6988 { 0x0000a208, 0x803e68c8 }, 5075 { 0x0000a208, 0x803e68c8 },
6989 { 0x0000a210, 0x4080a333 }, 5076 { 0x0000a210, 0x4080a333 },
6990 { 0x0000a214, 0x00206c10 }, 5077 { 0x0000a214, 0x00206c10 },
@@ -7004,13 +5091,9 @@ static const u_int32_t ar9271Common_9271[][2] = {
7004 { 0x0000a260, 0xdfa90f01 }, 5091 { 0x0000a260, 0xdfa90f01 },
7005 { 0x0000a268, 0x00000000 }, 5092 { 0x0000a268, 0x00000000 },
7006 { 0x0000a26c, 0x0ebae9e6 }, 5093 { 0x0000a26c, 0x0ebae9e6 },
7007 { 0x0000a278, 0x3bdef7bd },
7008 { 0x0000a27c, 0x050e83bd },
7009 { 0x0000a388, 0x0c000000 }, 5094 { 0x0000a388, 0x0c000000 },
7010 { 0x0000a38c, 0x20202020 }, 5095 { 0x0000a38c, 0x20202020 },
7011 { 0x0000a390, 0x20202020 }, 5096 { 0x0000a390, 0x20202020 },
7012 { 0x0000a394, 0x3bdef7bd },
7013 { 0x0000a398, 0x000003bd },
7014 { 0x0000a39c, 0x00000001 }, 5097 { 0x0000a39c, 0x00000001 },
7015 { 0x0000a3a0, 0x00000000 }, 5098 { 0x0000a3a0, 0x00000000 },
7016 { 0x0000a3a4, 0x00000000 }, 5099 { 0x0000a3a4, 0x00000000 },
@@ -7025,8 +5108,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
7025 { 0x0000a3cc, 0x20202020 }, 5108 { 0x0000a3cc, 0x20202020 },
7026 { 0x0000a3d0, 0x20202020 }, 5109 { 0x0000a3d0, 0x20202020 },
7027 { 0x0000a3d4, 0x20202020 }, 5110 { 0x0000a3d4, 0x20202020 },
7028 { 0x0000a3dc, 0x3bdef7bd },
7029 { 0x0000a3e0, 0x000003bd },
7030 { 0x0000a3e4, 0x00000000 }, 5111 { 0x0000a3e4, 0x00000000 },
7031 { 0x0000a3e8, 0x18c43433 }, 5112 { 0x0000a3e8, 0x18c43433 },
7032 { 0x0000a3ec, 0x00f70081 }, 5113 { 0x0000a3ec, 0x00f70081 },
@@ -7046,7 +5127,104 @@ static const u_int32_t ar9271Common_9271[][2] = {
7046 { 0x0000d384, 0xf3307ff0 }, 5127 { 0x0000d384, 0xf3307ff0 },
7047}; 5128};
7048 5129
7049static const u_int32_t ar9271Modes_9271_1_0_only[][6] = { 5130static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
5131 { 0x0000a1f4, 0x00fffeff },
5132 { 0x0000a1f8, 0x00f5f9ff },
5133 { 0x0000a1fc, 0xb79f6427 },
5134};
5135
5136static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
5137 { 0x0000a1f4, 0x00000000 },
5138 { 0x0000a1f8, 0xefff0301 },
5139 { 0x0000a1fc, 0xca9228ee },
5140};
5141
5142static const u32 ar9271Modes_9271_1_0_only[][6] = {
7050 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, 5143 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
7051 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, 5144 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
7052}; 5145};
5146
5147static const u32 ar9271Modes_9271_ANI_reg[][6] = {
5148 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
5149 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
5150 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
5151 { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 },
5152 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
5153 { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 },
5154 { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
5155 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
5156};
5157
5158static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = {
5159 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5160 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
5161 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
5162 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
5163 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
5164 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
5165 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
5166 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
5167 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
5168 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
5169 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
5170 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
5171 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
5172 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
5173 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
5174 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
5175 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5176 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5177 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5178 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5179 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5180 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5181 { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 },
5182 { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff },
5183 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
5184 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
5185 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
5186 { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
5187 { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd },
5188 { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
5189 { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
5190 { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
5191 { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
5192};
5193
5194static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
5195 { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 },
5196 { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 },
5197 { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 },
5198 { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 },
5199 { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 },
5200 { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 },
5201 { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 },
5202 { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 },
5203 { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 },
5204 { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 },
5205 { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 },
5206 { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 },
5207 { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 },
5208 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
5209 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
5210 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
5211 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5212 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5213 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5214 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5215 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5216 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
5217 { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b },
5218 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
5219 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
5220 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
5221 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 },
5222 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
5223 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
5224 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
5225 { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
5226 { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
5227 { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
5228};
5229
5230#endif /* INITVALS_9002_10_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
new file mode 100644
index 000000000000..2be20d2070c4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -0,0 +1,480 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18
19#define AR_BufLen 0x00000fff
20
21static void ar9002_hw_rx_enable(struct ath_hw *ah)
22{
23 REG_WRITE(ah, AR_CR, AR_CR_RXE);
24}
25
26static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
27{
28 ((struct ath_desc*) ds)->ds_link = ds_link;
29}
30
31static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
32{
33 *ds_link = &((struct ath_desc *)ds)->ds_link;
34}
35
36static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
37{
38 u32 isr = 0;
39 u32 mask2 = 0;
40 struct ath9k_hw_capabilities *pCap = &ah->caps;
41 u32 sync_cause = 0;
42 bool fatal_int = false;
43 struct ath_common *common = ath9k_hw_common(ah);
44
45 if (!AR_SREV_9100(ah)) {
46 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
47 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
48 == AR_RTC_STATUS_ON) {
49 isr = REG_READ(ah, AR_ISR);
50 }
51 }
52
53 sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
54 AR_INTR_SYNC_DEFAULT;
55
56 *masked = 0;
57
58 if (!isr && !sync_cause)
59 return false;
60 } else {
61 *masked = 0;
62 isr = REG_READ(ah, AR_ISR);
63 }
64
65 if (isr) {
66 if (isr & AR_ISR_BCNMISC) {
67 u32 isr2;
68 isr2 = REG_READ(ah, AR_ISR_S2);
69 if (isr2 & AR_ISR_S2_TIM)
70 mask2 |= ATH9K_INT_TIM;
71 if (isr2 & AR_ISR_S2_DTIM)
72 mask2 |= ATH9K_INT_DTIM;
73 if (isr2 & AR_ISR_S2_DTIMSYNC)
74 mask2 |= ATH9K_INT_DTIMSYNC;
75 if (isr2 & (AR_ISR_S2_CABEND))
76 mask2 |= ATH9K_INT_CABEND;
77 if (isr2 & AR_ISR_S2_GTT)
78 mask2 |= ATH9K_INT_GTT;
79 if (isr2 & AR_ISR_S2_CST)
80 mask2 |= ATH9K_INT_CST;
81 if (isr2 & AR_ISR_S2_TSFOOR)
82 mask2 |= ATH9K_INT_TSFOOR;
83 }
84
85 isr = REG_READ(ah, AR_ISR_RAC);
86 if (isr == 0xffffffff) {
87 *masked = 0;
88 return false;
89 }
90
91 *masked = isr & ATH9K_INT_COMMON;
92
93 if (ah->config.rx_intr_mitigation) {
94 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
95 *masked |= ATH9K_INT_RX;
96 }
97
98 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
99 *masked |= ATH9K_INT_RX;
100 if (isr &
101 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
102 AR_ISR_TXEOL)) {
103 u32 s0_s, s1_s;
104
105 *masked |= ATH9K_INT_TX;
106
107 s0_s = REG_READ(ah, AR_ISR_S0_S);
108 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
109 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
110
111 s1_s = REG_READ(ah, AR_ISR_S1_S);
112 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
113 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
114 }
115
116 if (isr & AR_ISR_RXORN) {
117 ath_print(common, ATH_DBG_INTERRUPT,
118 "receive FIFO overrun interrupt\n");
119 }
120
121 if (!AR_SREV_9100(ah)) {
122 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
123 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
124 if (isr5 & AR_ISR_S5_TIM_TIMER)
125 *masked |= ATH9K_INT_TIM_TIMER;
126 }
127 }
128
129 *masked |= mask2;
130 }
131
132 if (AR_SREV_9100(ah))
133 return true;
134
135 if (isr & AR_ISR_GENTMR) {
136 u32 s5_s;
137
138 s5_s = REG_READ(ah, AR_ISR_S5_S);
139 if (isr & AR_ISR_GENTMR) {
140 ah->intr_gen_timer_trigger =
141 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
142
143 ah->intr_gen_timer_thresh =
144 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
145
146 if (ah->intr_gen_timer_trigger)
147 *masked |= ATH9K_INT_GENTIMER;
148
149 }
150 }
151
152 if (sync_cause) {
153 fatal_int =
154 (sync_cause &
155 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
156 ? true : false;
157
158 if (fatal_int) {
159 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
160 ath_print(common, ATH_DBG_ANY,
161 "received PCI FATAL interrupt\n");
162 }
163 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
164 ath_print(common, ATH_DBG_ANY,
165 "received PCI PERR interrupt\n");
166 }
167 *masked |= ATH9K_INT_FATAL;
168 }
169 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
170 ath_print(common, ATH_DBG_INTERRUPT,
171 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
172 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
173 REG_WRITE(ah, AR_RC, 0);
174 *masked |= ATH9K_INT_FATAL;
175 }
176 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
177 ath_print(common, ATH_DBG_INTERRUPT,
178 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
179 }
180
181 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
182 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
183 }
184
185 return true;
186}
187
188static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
189 bool is_firstseg, bool is_lastseg,
190 const void *ds0, dma_addr_t buf_addr,
191 unsigned int qcu)
192{
193 struct ar5416_desc *ads = AR5416DESC(ds);
194
195 ads->ds_data = buf_addr;
196
197 if (is_firstseg) {
198 ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
199 } else if (is_lastseg) {
200 ads->ds_ctl0 = 0;
201 ads->ds_ctl1 = seglen;
202 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
203 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
204 } else {
205 ads->ds_ctl0 = 0;
206 ads->ds_ctl1 = seglen | AR_TxMore;
207 ads->ds_ctl2 = 0;
208 ads->ds_ctl3 = 0;
209 }
210 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
211 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
212 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
213 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
214 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
215}
216
217static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
218 struct ath_tx_status *ts)
219{
220 struct ar5416_desc *ads = AR5416DESC(ds);
221
222 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
223 return -EINPROGRESS;
224
225 ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
226 ts->ts_tstamp = ads->AR_SendTimestamp;
227 ts->ts_status = 0;
228 ts->ts_flags = 0;
229
230 if (ads->ds_txstatus1 & AR_FrmXmitOK)
231 ts->ts_status |= ATH9K_TX_ACKED;
232 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
233 ts->ts_status |= ATH9K_TXERR_XRETRY;
234 if (ads->ds_txstatus1 & AR_Filtered)
235 ts->ts_status |= ATH9K_TXERR_FILT;
236 if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
237 ts->ts_status |= ATH9K_TXERR_FIFO;
238 ath9k_hw_updatetxtriglevel(ah, true);
239 }
240 if (ads->ds_txstatus9 & AR_TxOpExceeded)
241 ts->ts_status |= ATH9K_TXERR_XTXOP;
242 if (ads->ds_txstatus1 & AR_TxTimerExpired)
243 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
244
245 if (ads->ds_txstatus1 & AR_DescCfgErr)
246 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
247 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
248 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
249 ath9k_hw_updatetxtriglevel(ah, true);
250 }
251 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
252 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
253 ath9k_hw_updatetxtriglevel(ah, true);
254 }
255 if (ads->ds_txstatus0 & AR_TxBaStatus) {
256 ts->ts_flags |= ATH9K_TX_BA;
257 ts->ba_low = ads->AR_BaBitmapLow;
258 ts->ba_high = ads->AR_BaBitmapHigh;
259 }
260
261 ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
262 switch (ts->ts_rateindex) {
263 case 0:
264 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
265 break;
266 case 1:
267 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
268 break;
269 case 2:
270 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
271 break;
272 case 3:
273 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
274 break;
275 }
276
277 ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
278 ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
279 ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
280 ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
281 ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
282 ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
283 ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
284 ts->evm0 = ads->AR_TxEVM0;
285 ts->evm1 = ads->AR_TxEVM1;
286 ts->evm2 = ads->AR_TxEVM2;
287 ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
288 ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
289 ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
290 ts->ts_antenna = 0;
291
292 return 0;
293}
294
295static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
296 u32 pktLen, enum ath9k_pkt_type type,
297 u32 txPower, u32 keyIx,
298 enum ath9k_key_type keyType, u32 flags)
299{
300 struct ar5416_desc *ads = AR5416DESC(ds);
301
302 txPower += ah->txpower_indexoffset;
303 if (txPower > 63)
304 txPower = 63;
305
306 ads->ds_ctl0 = (pktLen & AR_FrameLen)
307 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
308 | SM(txPower, AR_XmitPower)
309 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
310 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
311 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
312 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
313
314 ads->ds_ctl1 =
315 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
316 | SM(type, AR_FrameType)
317 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
318 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
319 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
320
321 ads->ds_ctl6 = SM(keyType, AR_EncrType);
322
323 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
324 ads->ds_ctl8 = 0;
325 ads->ds_ctl9 = 0;
326 ads->ds_ctl10 = 0;
327 ads->ds_ctl11 = 0;
328 }
329}
330
331static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
332 void *lastds,
333 u32 durUpdateEn, u32 rtsctsRate,
334 u32 rtsctsDuration,
335 struct ath9k_11n_rate_series series[],
336 u32 nseries, u32 flags)
337{
338 struct ar5416_desc *ads = AR5416DESC(ds);
339 struct ar5416_desc *last_ads = AR5416DESC(lastds);
340 u32 ds_ctl0;
341
342 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
343 ds_ctl0 = ads->ds_ctl0;
344
345 if (flags & ATH9K_TXDESC_RTSENA) {
346 ds_ctl0 &= ~AR_CTSEnable;
347 ds_ctl0 |= AR_RTSEnable;
348 } else {
349 ds_ctl0 &= ~AR_RTSEnable;
350 ds_ctl0 |= AR_CTSEnable;
351 }
352
353 ads->ds_ctl0 = ds_ctl0;
354 } else {
355 ads->ds_ctl0 =
356 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
357 }
358
359 ads->ds_ctl2 = set11nTries(series, 0)
360 | set11nTries(series, 1)
361 | set11nTries(series, 2)
362 | set11nTries(series, 3)
363 | (durUpdateEn ? AR_DurUpdateEna : 0)
364 | SM(0, AR_BurstDur);
365
366 ads->ds_ctl3 = set11nRate(series, 0)
367 | set11nRate(series, 1)
368 | set11nRate(series, 2)
369 | set11nRate(series, 3);
370
371 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
372 | set11nPktDurRTSCTS(series, 1);
373
374 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
375 | set11nPktDurRTSCTS(series, 3);
376
377 ads->ds_ctl7 = set11nRateFlags(series, 0)
378 | set11nRateFlags(series, 1)
379 | set11nRateFlags(series, 2)
380 | set11nRateFlags(series, 3)
381 | SM(rtsctsRate, AR_RTSCTSRate);
382 last_ads->ds_ctl2 = ads->ds_ctl2;
383 last_ads->ds_ctl3 = ads->ds_ctl3;
384}
385
386static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
387 u32 aggrLen)
388{
389 struct ar5416_desc *ads = AR5416DESC(ds);
390
391 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
392 ads->ds_ctl6 &= ~AR_AggrLen;
393 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
394}
395
396static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
397 u32 numDelims)
398{
399 struct ar5416_desc *ads = AR5416DESC(ds);
400 unsigned int ctl6;
401
402 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
403
404 ctl6 = ads->ds_ctl6;
405 ctl6 &= ~AR_PadDelim;
406 ctl6 |= SM(numDelims, AR_PadDelim);
407 ads->ds_ctl6 = ctl6;
408}
409
410static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
411{
412 struct ar5416_desc *ads = AR5416DESC(ds);
413
414 ads->ds_ctl1 |= AR_IsAggr;
415 ads->ds_ctl1 &= ~AR_MoreAggr;
416 ads->ds_ctl6 &= ~AR_PadDelim;
417}
418
419static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
420{
421 struct ar5416_desc *ads = AR5416DESC(ds);
422
423 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
424}
425
426static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
427 u32 burstDuration)
428{
429 struct ar5416_desc *ads = AR5416DESC(ds);
430
431 ads->ds_ctl2 &= ~AR_BurstDur;
432 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
433}
434
435static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
436 u32 vmf)
437{
438 struct ar5416_desc *ads = AR5416DESC(ds);
439
440 if (vmf)
441 ads->ds_ctl0 |= AR_VirtMoreFrag;
442 else
443 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
444}
445
446void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
447 u32 size, u32 flags)
448{
449 struct ar5416_desc *ads = AR5416DESC(ds);
450 struct ath9k_hw_capabilities *pCap = &ah->caps;
451
452 ads->ds_ctl1 = size & AR_BufLen;
453 if (flags & ATH9K_RXDESC_INTREQ)
454 ads->ds_ctl1 |= AR_RxIntrReq;
455
456 ads->ds_rxstatus8 &= ~AR_RxDone;
457 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
458 memset(&(ads->u), 0, sizeof(ads->u));
459}
460EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
461
462void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
463{
464 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
465
466 ops->rx_enable = ar9002_hw_rx_enable;
467 ops->set_desc_link = ar9002_hw_set_desc_link;
468 ops->get_desc_link = ar9002_hw_get_desc_link;
469 ops->get_isr = ar9002_hw_get_isr;
470 ops->fill_txdesc = ar9002_hw_fill_txdesc;
471 ops->proc_txdesc = ar9002_hw_proc_txdesc;
472 ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
473 ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
474 ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
475 ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
476 ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
477 ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
478 ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
479 ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
480}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
new file mode 100644
index 000000000000..ed314e89bfe1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -0,0 +1,535 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/**
18 * DOC: Programming Atheros 802.11n analog front end radios
19 *
20 * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
21 * devices have either an external AR2133 analog front end radio for single
22 * band 2.4 GHz communication or an AR5133 analog front end radio for dual
23 * band 2.4 GHz / 5 GHz communication.
24 *
25 * All devices after the AR5416 and AR5418 family starting with the AR9280
26 * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
27 * into a single-chip and require less programming.
28 *
29 * The following single-chips exist with a respective embedded radio:
30 *
31 * AR9280 - 11n dual-band 2x2 MIMO for PCIe
32 * AR9281 - 11n single-band 1x2 MIMO for PCIe
33 * AR9285 - 11n single-band 1x1 for PCIe
34 * AR9287 - 11n single-band 2x2 MIMO for PCIe
35 *
36 * AR9220 - 11n dual-band 2x2 MIMO for PCI
37 * AR9223 - 11n single-band 2x2 MIMO for PCI
38 *
39 * AR9287 - 11n single-band 1x1 MIMO for USB
40 */
41
42#include "hw.h"
43#include "ar9002_phy.h"
44
45/**
46 * ar9002_hw_set_channel - set channel on single-chip device
47 * @ah: atheros hardware structure
48 * @chan:
49 *
50 * This is the function to change channel on single-chip devices, that is
51 * all devices after ar9280.
52 *
53 * This function takes the channel value in MHz and sets
54 * hardware channel value. Assumes writes have been enabled to analog bus.
55 *
56 * Actual Expression,
57 *
58 * For 2GHz channel,
59 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
60 * (freq_ref = 40MHz)
61 *
62 * For 5GHz channel,
63 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
64 * (freq_ref = 40MHz/(24>>amodeRefSel))
65 */
66static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
67{
68 u16 bMode, fracMode, aModeRefSel = 0;
69 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
70 struct chan_centers centers;
71 u32 refDivA = 24;
72
73 ath9k_hw_get_channel_centers(ah, chan, &centers);
74 freq = centers.synth_center;
75
76 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
77 reg32 &= 0xc0000000;
78
79 if (freq < 4800) { /* 2 GHz, fractional mode */
80 u32 txctl;
81 int regWrites = 0;
82
83 bMode = 1;
84 fracMode = 1;
85 aModeRefSel = 0;
86 channelSel = CHANSEL_2G(freq);
87
88 if (AR_SREV_9287_11_OR_LATER(ah)) {
89 if (freq == 2484) {
90 /* Enable channel spreading for channel 14 */
91 REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
92 1, regWrites);
93 } else {
94 REG_WRITE_ARRAY(&ah->iniCckfirNormal,
95 1, regWrites);
96 }
97 } else {
98 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
99 if (freq == 2484) {
100 /* Enable channel spreading for channel 14 */
101 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
102 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
103 } else {
104 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
105 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
106 }
107 }
108 } else {
109 bMode = 0;
110 fracMode = 0;
111
112 switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
113 case 0:
114 if ((freq % 20) == 0)
115 aModeRefSel = 3;
116 else if ((freq % 10) == 0)
117 aModeRefSel = 2;
118 if (aModeRefSel)
119 break;
120 case 1:
121 default:
122 aModeRefSel = 0;
123 /*
124 * Enable 2G (fractional) mode for channels
125 * which are 5MHz spaced.
126 */
127 fracMode = 1;
128 refDivA = 1;
129 channelSel = CHANSEL_5G(freq);
130
131 /* RefDivA setting */
132 REG_RMW_FIELD(ah, AR_AN_SYNTH9,
133 AR_AN_SYNTH9_REFDIVA, refDivA);
134
135 }
136
137 if (!fracMode) {
138 ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
139 channelSel = ndiv & 0x1ff;
140 channelFrac = (ndiv & 0xfffffe00) * 2;
141 channelSel = (channelSel << 17) | channelFrac;
142 }
143 }
144
145 reg32 = reg32 |
146 (bMode << 29) |
147 (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
148
149 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
150
151 ah->curchan = chan;
152 ah->curchan_rad_index = -1;
153
154 return 0;
155}
156
157/**
158 * ar9002_hw_spur_mitigate - convert baseband spur frequency
159 * @ah: atheros hardware structure
160 * @chan:
161 *
162 * For single-chip solutions. Converts to baseband spur frequency given the
163 * input channel frequency and compute register settings below.
164 */
165static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
166 struct ath9k_channel *chan)
167{
168 int bb_spur = AR_NO_SPUR;
169 int freq;
170 int bin, cur_bin;
171 int bb_spur_off, spur_subchannel_sd;
172 int spur_freq_sd;
173 int spur_delta_phase;
174 int denominator;
175 int upper, lower, cur_vit_mask;
176 int tmp, newVal;
177 int i;
178 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
179 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
180 };
181 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
182 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
183 };
184 int inc[4] = { 0, 100, 0, 0 };
185 struct chan_centers centers;
186
187 int8_t mask_m[123];
188 int8_t mask_p[123];
189 int8_t mask_amt;
190 int tmp_mask;
191 int cur_bb_spur;
192 bool is2GHz = IS_CHAN_2GHZ(chan);
193
194 memset(&mask_m, 0, sizeof(int8_t) * 123);
195 memset(&mask_p, 0, sizeof(int8_t) * 123);
196
197 ath9k_hw_get_channel_centers(ah, chan, &centers);
198 freq = centers.synth_center;
199
200 ah->config.spurmode = SPUR_ENABLE_EEPROM;
201 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
202 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
203
204 if (is2GHz)
205 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
206 else
207 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
208
209 if (AR_NO_SPUR == cur_bb_spur)
210 break;
211 cur_bb_spur = cur_bb_spur - freq;
212
213 if (IS_CHAN_HT40(chan)) {
214 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
215 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
216 bb_spur = cur_bb_spur;
217 break;
218 }
219 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
220 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
221 bb_spur = cur_bb_spur;
222 break;
223 }
224 }
225
226 if (AR_NO_SPUR == bb_spur) {
227 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
228 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
229 return;
230 } else {
231 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
232 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
233 }
234
235 bin = bb_spur * 320;
236
237 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
238
239 ENABLE_REGWRITE_BUFFER(ah);
240
241 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
242 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
243 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
244 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
245 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
246
247 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
248 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
249 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
250 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
251 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
252 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
253
254 if (IS_CHAN_HT40(chan)) {
255 if (bb_spur < 0) {
256 spur_subchannel_sd = 1;
257 bb_spur_off = bb_spur + 10;
258 } else {
259 spur_subchannel_sd = 0;
260 bb_spur_off = bb_spur - 10;
261 }
262 } else {
263 spur_subchannel_sd = 0;
264 bb_spur_off = bb_spur;
265 }
266
267 if (IS_CHAN_HT40(chan))
268 spur_delta_phase =
269 ((bb_spur * 262144) /
270 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
271 else
272 spur_delta_phase =
273 ((bb_spur * 524288) /
274 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
275
276 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
277 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
278
279 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
280 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
281 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
282 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
283
284 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
285 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
286
287 cur_bin = -6000;
288 upper = bin + 100;
289 lower = bin - 100;
290
291 for (i = 0; i < 4; i++) {
292 int pilot_mask = 0;
293 int chan_mask = 0;
294 int bp = 0;
295 for (bp = 0; bp < 30; bp++) {
296 if ((cur_bin > lower) && (cur_bin < upper)) {
297 pilot_mask = pilot_mask | 0x1 << bp;
298 chan_mask = chan_mask | 0x1 << bp;
299 }
300 cur_bin += 100;
301 }
302 cur_bin += inc[i];
303 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
304 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
305 }
306
307 cur_vit_mask = 6100;
308 upper = bin + 120;
309 lower = bin - 120;
310
311 for (i = 0; i < 123; i++) {
312 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
313
314 /* workaround for gcc bug #37014 */
315 volatile int tmp_v = abs(cur_vit_mask - bin);
316
317 if (tmp_v < 75)
318 mask_amt = 1;
319 else
320 mask_amt = 0;
321 if (cur_vit_mask < 0)
322 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
323 else
324 mask_p[cur_vit_mask / 100] = mask_amt;
325 }
326 cur_vit_mask -= 100;
327 }
328
329 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
330 | (mask_m[48] << 26) | (mask_m[49] << 24)
331 | (mask_m[50] << 22) | (mask_m[51] << 20)
332 | (mask_m[52] << 18) | (mask_m[53] << 16)
333 | (mask_m[54] << 14) | (mask_m[55] << 12)
334 | (mask_m[56] << 10) | (mask_m[57] << 8)
335 | (mask_m[58] << 6) | (mask_m[59] << 4)
336 | (mask_m[60] << 2) | (mask_m[61] << 0);
337 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
338 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
339
340 tmp_mask = (mask_m[31] << 28)
341 | (mask_m[32] << 26) | (mask_m[33] << 24)
342 | (mask_m[34] << 22) | (mask_m[35] << 20)
343 | (mask_m[36] << 18) | (mask_m[37] << 16)
344 | (mask_m[48] << 14) | (mask_m[39] << 12)
345 | (mask_m[40] << 10) | (mask_m[41] << 8)
346 | (mask_m[42] << 6) | (mask_m[43] << 4)
347 | (mask_m[44] << 2) | (mask_m[45] << 0);
348 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
349 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
350
351 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
352 | (mask_m[18] << 26) | (mask_m[18] << 24)
353 | (mask_m[20] << 22) | (mask_m[20] << 20)
354 | (mask_m[22] << 18) | (mask_m[22] << 16)
355 | (mask_m[24] << 14) | (mask_m[24] << 12)
356 | (mask_m[25] << 10) | (mask_m[26] << 8)
357 | (mask_m[27] << 6) | (mask_m[28] << 4)
358 | (mask_m[29] << 2) | (mask_m[30] << 0);
359 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
360 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
361
362 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
363 | (mask_m[2] << 26) | (mask_m[3] << 24)
364 | (mask_m[4] << 22) | (mask_m[5] << 20)
365 | (mask_m[6] << 18) | (mask_m[7] << 16)
366 | (mask_m[8] << 14) | (mask_m[9] << 12)
367 | (mask_m[10] << 10) | (mask_m[11] << 8)
368 | (mask_m[12] << 6) | (mask_m[13] << 4)
369 | (mask_m[14] << 2) | (mask_m[15] << 0);
370 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
371 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
372
373 tmp_mask = (mask_p[15] << 28)
374 | (mask_p[14] << 26) | (mask_p[13] << 24)
375 | (mask_p[12] << 22) | (mask_p[11] << 20)
376 | (mask_p[10] << 18) | (mask_p[9] << 16)
377 | (mask_p[8] << 14) | (mask_p[7] << 12)
378 | (mask_p[6] << 10) | (mask_p[5] << 8)
379 | (mask_p[4] << 6) | (mask_p[3] << 4)
380 | (mask_p[2] << 2) | (mask_p[1] << 0);
381 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
382 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
383
384 tmp_mask = (mask_p[30] << 28)
385 | (mask_p[29] << 26) | (mask_p[28] << 24)
386 | (mask_p[27] << 22) | (mask_p[26] << 20)
387 | (mask_p[25] << 18) | (mask_p[24] << 16)
388 | (mask_p[23] << 14) | (mask_p[22] << 12)
389 | (mask_p[21] << 10) | (mask_p[20] << 8)
390 | (mask_p[19] << 6) | (mask_p[18] << 4)
391 | (mask_p[17] << 2) | (mask_p[16] << 0);
392 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
393 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
394
395 tmp_mask = (mask_p[45] << 28)
396 | (mask_p[44] << 26) | (mask_p[43] << 24)
397 | (mask_p[42] << 22) | (mask_p[41] << 20)
398 | (mask_p[40] << 18) | (mask_p[39] << 16)
399 | (mask_p[38] << 14) | (mask_p[37] << 12)
400 | (mask_p[36] << 10) | (mask_p[35] << 8)
401 | (mask_p[34] << 6) | (mask_p[33] << 4)
402 | (mask_p[32] << 2) | (mask_p[31] << 0);
403 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
404 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
405
406 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
407 | (mask_p[59] << 26) | (mask_p[58] << 24)
408 | (mask_p[57] << 22) | (mask_p[56] << 20)
409 | (mask_p[55] << 18) | (mask_p[54] << 16)
410 | (mask_p[53] << 14) | (mask_p[52] << 12)
411 | (mask_p[51] << 10) | (mask_p[50] << 8)
412 | (mask_p[49] << 6) | (mask_p[48] << 4)
413 | (mask_p[47] << 2) | (mask_p[46] << 0);
414 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
415 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
416
417 REGWRITE_BUFFER_FLUSH(ah);
418 DISABLE_REGWRITE_BUFFER(ah);
419}
420
421static void ar9002_olc_init(struct ath_hw *ah)
422{
423 u32 i;
424
425 if (!OLC_FOR_AR9280_20_LATER)
426 return;
427
428 if (OLC_FOR_AR9287_10_LATER) {
429 REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
430 AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
431 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
432 AR9287_AN_TXPC0_TXPCMODE,
433 AR9287_AN_TXPC0_TXPCMODE_S,
434 AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
435 udelay(100);
436 } else {
437 for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
438 ah->originalGain[i] =
439 MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
440 AR_PHY_TX_GAIN);
441 ah->PDADCdelta = 0;
442 }
443}
444
445static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
446 struct ath9k_channel *chan)
447{
448 u32 pll;
449
450 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
451
452 if (chan && IS_CHAN_HALF_RATE(chan))
453 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
454 else if (chan && IS_CHAN_QUARTER_RATE(chan))
455 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
456
457 if (chan && IS_CHAN_5GHZ(chan)) {
458 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
459 pll = 0x142c;
460 else if (AR_SREV_9280_20(ah))
461 pll = 0x2850;
462 else
463 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
464 } else {
465 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
466 }
467
468 return pll;
469}
470
471static void ar9002_hw_do_getnf(struct ath_hw *ah,
472 int16_t nfarray[NUM_NF_READINGS])
473{
474 struct ath_common *common = ath9k_hw_common(ah);
475 int16_t nf;
476
477 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
478
479 if (nf & 0x100)
480 nf = 0 - ((nf ^ 0x1ff) + 1);
481 ath_print(common, ATH_DBG_CALIBRATE,
482 "NF calibrated [ctl] [chain 0] is %d\n", nf);
483
484 if (AR_SREV_9271(ah) && (nf >= -114))
485 nf = -116;
486
487 nfarray[0] = nf;
488
489 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
490 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
491 AR9280_PHY_CH1_MINCCA_PWR);
492
493 if (nf & 0x100)
494 nf = 0 - ((nf ^ 0x1ff) + 1);
495 ath_print(common, ATH_DBG_CALIBRATE,
496 "NF calibrated [ctl] [chain 1] is %d\n", nf);
497 nfarray[1] = nf;
498 }
499
500 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
501 if (nf & 0x100)
502 nf = 0 - ((nf ^ 0x1ff) + 1);
503 ath_print(common, ATH_DBG_CALIBRATE,
504 "NF calibrated [ext] [chain 0] is %d\n", nf);
505
506 if (AR_SREV_9271(ah) && (nf >= -114))
507 nf = -116;
508
509 nfarray[3] = nf;
510
511 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
512 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
513 AR9280_PHY_CH1_EXT_MINCCA_PWR);
514
515 if (nf & 0x100)
516 nf = 0 - ((nf ^ 0x1ff) + 1);
517 ath_print(common, ATH_DBG_CALIBRATE,
518 "NF calibrated [ext] [chain 1] is %d\n", nf);
519 nfarray[4] = nf;
520 }
521}
522
523void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
524{
525 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
526
527 priv_ops->set_rf_regs = NULL;
528 priv_ops->rf_alloc_ext_banks = NULL;
529 priv_ops->rf_free_ext_banks = NULL;
530 priv_ops->rf_set_freq = ar9002_hw_set_channel;
531 priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
532 priv_ops->olc_init = ar9002_olc_init;
533 priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
534 priv_ops->do_getnf = ar9002_hw_do_getnf;
535}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
new file mode 100644
index 000000000000..81bf6e5840e1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -0,0 +1,572 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef AR9002_PHY_H
17#define AR9002_PHY_H
18
19#define AR_PHY_TEST 0x9800
20#define PHY_AGC_CLR 0x10000000
21#define RFSILENT_BB 0x00002000
22
23#define AR_PHY_TURBO 0x9804
24#define AR_PHY_FC_TURBO_MODE 0x00000001
25#define AR_PHY_FC_TURBO_SHORT 0x00000002
26#define AR_PHY_FC_DYN2040_EN 0x00000004
27#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
28#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
29/* For 25 MHz channel spacing -- not used but supported by hw */
30#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
31#define AR_PHY_FC_HT_EN 0x00000040
32#define AR_PHY_FC_SHORT_GI_40 0x00000080
33#define AR_PHY_FC_WALSH 0x00000100
34#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
35#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
36
37#define AR_PHY_TEST2 0x9808
38
39#define AR_PHY_TIMING2 0x9810
40#define AR_PHY_TIMING3 0x9814
41#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
42#define AR_PHY_TIMING3_DSC_MAN_S 17
43#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
44#define AR_PHY_TIMING3_DSC_EXP_S 13
45
46#define AR_PHY_CHIP_ID_REV_0 0x80
47#define AR_PHY_CHIP_ID_REV_1 0x81
48#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
49
50#define AR_PHY_ACTIVE 0x981C
51#define AR_PHY_ACTIVE_EN 0x00000001
52#define AR_PHY_ACTIVE_DIS 0x00000000
53
54#define AR_PHY_RF_CTL2 0x9824
55#define AR_PHY_TX_END_DATA_START 0x000000FF
56#define AR_PHY_TX_END_DATA_START_S 0
57#define AR_PHY_TX_END_PA_ON 0x0000FF00
58#define AR_PHY_TX_END_PA_ON_S 8
59
60#define AR_PHY_RF_CTL3 0x9828
61#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
62#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
63
64#define AR_PHY_ADC_CTL 0x982C
65#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
66#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
67#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
68#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
69#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
70#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
71#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
72
73#define AR_PHY_ADC_SERIAL_CTL 0x9830
74#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
75#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
76
77#define AR_PHY_RF_CTL4 0x9834
78#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
79#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
80#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
81#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
82#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
83#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
84#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
85#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
86
87#define AR_PHY_TSTDAC_CONST 0x983c
88
89#define AR_PHY_SETTLING 0x9844
90#define AR_PHY_SETTLING_SWITCH 0x00003F80
91#define AR_PHY_SETTLING_SWITCH_S 7
92
93#define AR_PHY_RXGAIN 0x9848
94#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
95#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
96#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
97#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
98#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
99#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
100#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
101#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
102
103#define AR_PHY_DESIRED_SZ 0x9850
104#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
105#define AR_PHY_DESIRED_SZ_ADC_S 0
106#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
107#define AR_PHY_DESIRED_SZ_PGA_S 8
108#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
109#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
110
111#define AR_PHY_FIND_SIG 0x9858
112#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
113#define AR_PHY_FIND_SIG_FIRSTEP_S 12
114#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
115#define AR_PHY_FIND_SIG_FIRPWR_S 18
116
117#define AR_PHY_AGC_CTL1 0x985C
118#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
119#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
120#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
121#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
122
123#define AR_PHY_CCA 0x9864
124#define AR_PHY_MINCCA_PWR 0x0FF80000
125#define AR_PHY_MINCCA_PWR_S 19
126#define AR_PHY_CCA_THRESH62 0x0007F000
127#define AR_PHY_CCA_THRESH62_S 12
128#define AR9280_PHY_MINCCA_PWR 0x1FF00000
129#define AR9280_PHY_MINCCA_PWR_S 20
130#define AR9280_PHY_CCA_THRESH62 0x000FF000
131#define AR9280_PHY_CCA_THRESH62_S 12
132
133#define AR_PHY_SFCORR_LOW 0x986C
134#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
135#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
136#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
137#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
138#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
139#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
140#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
141
142#define AR_PHY_SFCORR 0x9868
143#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
144#define AR_PHY_SFCORR_M2COUNT_THR_S 0
145#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
146#define AR_PHY_SFCORR_M1_THRESH_S 17
147#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
148#define AR_PHY_SFCORR_M2_THRESH_S 24
149
150#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
151#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
152#define AR_PHY_SYNTH_CONTROL 0x9874
153#define AR_PHY_SLEEP_SCAL 0x9878
154
155#define AR_PHY_PLL_CTL 0x987c
156#define AR_PHY_PLL_CTL_40 0xaa
157#define AR_PHY_PLL_CTL_40_5413 0x04
158#define AR_PHY_PLL_CTL_44 0xab
159#define AR_PHY_PLL_CTL_44_2133 0xeb
160#define AR_PHY_PLL_CTL_40_2133 0xea
161
162#define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */
163#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1
164#define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */
165#define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */
166#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/
167#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/
168#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/
169#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
170#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/
171#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
172#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
173#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
174#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
175#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/
176
177#define AR_PHY_RX_DELAY 0x9914
178#define AR_PHY_SEARCH_START_DELAY 0x9918
179#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
180
181#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
182#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
183#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
184#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
185#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
186#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
187#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
188#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
189#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
190
191#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
192#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
193#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
194#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
195
196#define AR_PHY_TIMING5 0x9924
197#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
198#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
199
200#define AR_PHY_POWER_TX_RATE1 0x9934
201#define AR_PHY_POWER_TX_RATE2 0x9938
202#define AR_PHY_POWER_TX_RATE_MAX 0x993c
203#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
204
205#define AR_PHY_FRAME_CTL 0x9944
206#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
207#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
208
209#define AR_PHY_TXPWRADJ 0x994C
210#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
211#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
212#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
213#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
214
215#define AR_PHY_RADAR_EXT 0x9940
216#define AR_PHY_RADAR_EXT_ENA 0x00004000
217
218#define AR_PHY_RADAR_0 0x9954
219#define AR_PHY_RADAR_0_ENA 0x00000001
220#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
221#define AR_PHY_RADAR_0_INBAND 0x0000003e
222#define AR_PHY_RADAR_0_INBAND_S 1
223#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
224#define AR_PHY_RADAR_0_PRSSI_S 6
225#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
226#define AR_PHY_RADAR_0_HEIGHT_S 12
227#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
228#define AR_PHY_RADAR_0_RRSSI_S 18
229#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
230#define AR_PHY_RADAR_0_FIRPWR_S 24
231
232#define AR_PHY_RADAR_1 0x9958
233#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
234#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
235#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
236#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
237#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
238#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
239#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
240#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
241#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
242#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
243#define AR_PHY_RADAR_1_MAXLEN_S 0
244
245#define AR_PHY_SWITCH_CHAIN_0 0x9960
246#define AR_PHY_SWITCH_COM 0x9964
247
248#define AR_PHY_SIGMA_DELTA 0x996C
249#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
250#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
251#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
252#define AR_PHY_SIGMA_DELTA_FILT2_S 3
253#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
254#define AR_PHY_SIGMA_DELTA_FILT1_S 8
255#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
256#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
257
258#define AR_PHY_RESTART 0x9970
259#define AR_PHY_RESTART_DIV_GC 0x001C0000
260#define AR_PHY_RESTART_DIV_GC_S 18
261
262#define AR_PHY_RFBUS_REQ 0x997C
263#define AR_PHY_RFBUS_REQ_EN 0x00000001
264
265#define AR_PHY_TIMING7 0x9980
266#define AR_PHY_TIMING8 0x9984
267#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
268#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
269
270#define AR_PHY_BIN_MASK2_1 0x9988
271#define AR_PHY_BIN_MASK2_2 0x998c
272#define AR_PHY_BIN_MASK2_3 0x9990
273#define AR_PHY_BIN_MASK2_4 0x9994
274
275#define AR_PHY_BIN_MASK_1 0x9900
276#define AR_PHY_BIN_MASK_2 0x9904
277#define AR_PHY_BIN_MASK_3 0x9908
278
279#define AR_PHY_MASK_CTL 0x990c
280
281#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
282#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
283
284#define AR_PHY_TIMING9 0x9998
285#define AR_PHY_TIMING10 0x999c
286#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
287#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
288
289#define AR_PHY_TIMING11 0x99a0
290#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
291#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
292#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
293#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
294
295#define AR_PHY_RX_CHAINMASK 0x99a4
296#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
297#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
298#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
299
300#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
301#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
302#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
303#define AR_PHY_9285_ANT_DIV_CTL_S 24
304#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
305#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
306#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
307#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
308#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
309#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
310#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
311#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
312#define AR_PHY_9285_ANT_DIV_LNA1 2
313#define AR_PHY_9285_ANT_DIV_LNA2 1
314#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
315#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
316#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
317#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
318
319#define AR_PHY_EXT_CCA0 0x99b8
320#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
321#define AR_PHY_EXT_CCA0_THRESH62_S 0
322
323#define AR_PHY_EXT_CCA 0x99bc
324#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
325#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
326#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
327#define AR_PHY_EXT_CCA_THRESH62_S 16
328#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
329#define AR_PHY_EXT_MINCCA_PWR_S 23
330#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
331#define AR9280_PHY_EXT_MINCCA_PWR_S 16
332
333#define AR_PHY_SFCORR_EXT 0x99c0
334#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
335#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
336#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
337#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
338#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
339#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
340#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
341#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
342#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
343
344#define AR_PHY_HALFGI 0x99D0
345#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
346#define AR_PHY_HALFGI_DSC_MAN_S 4
347#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
348#define AR_PHY_HALFGI_DSC_EXP_S 0
349
350#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
351#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
352
353#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
354
355#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC
356#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000
357
358#define AR_PHY_M_SLEEP 0x99f0
359#define AR_PHY_REFCLKDLY 0x99f4
360#define AR_PHY_REFCLKPD 0x99f8
361
362#define AR_PHY_CALMODE 0x99f0
363
364#define AR_PHY_CALMODE_IQ 0x00000000
365#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
366#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
367#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
368
369#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
370#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
371#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
372#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
373
374#define AR_PHY_CURRENT_RSSI 0x9c1c
375#define AR9280_PHY_CURRENT_RSSI 0x9c3c
376
377#define AR_PHY_RFBUS_GRANT 0x9C20
378#define AR_PHY_RFBUS_GRANT_EN 0x00000001
379
380#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
381#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
382
383#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
384
385#define AR_PHY_MODE 0xA200
386#define AR_PHY_MODE_ASYNCFIFO 0x80
387#define AR_PHY_MODE_AR2133 0x08
388#define AR_PHY_MODE_AR5111 0x00
389#define AR_PHY_MODE_AR5112 0x08
390#define AR_PHY_MODE_DYNAMIC 0x04
391#define AR_PHY_MODE_RF2GHZ 0x02
392#define AR_PHY_MODE_RF5GHZ 0x00
393#define AR_PHY_MODE_CCK 0x01
394#define AR_PHY_MODE_OFDM 0x00
395#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
396
397#define AR_PHY_CCK_TX_CTRL 0xA204
398#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
399#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
400#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
401
402#define AR_PHY_CCK_DETECT 0xA208
403#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
404#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
405/* [12:6] settling time for antenna switch */
406#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
407#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
408#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
409#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
410
411#define AR_PHY_GAIN_2GHZ 0xA20C
412#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
413#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
414#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
415#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
416#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
417#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
418
419#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
420#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
421#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
422#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
423#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
424#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
425#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
426#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
427
428#define AR_PHY_CCK_RXCTRL4 0xA21C
429#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
430#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
431
432#define AR_PHY_DAG_CTRLCCK 0xA228
433#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
434#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
435#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
436
437#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
438#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
439
440#define AR_PHY_POWER_TX_RATE3 0xA234
441#define AR_PHY_POWER_TX_RATE4 0xA238
442
443#define AR_PHY_SCRM_SEQ_XR 0xA23C
444#define AR_PHY_HEADER_DETECT_XR 0xA240
445#define AR_PHY_CHIRP_DETECTED_XR 0xA244
446#define AR_PHY_BLUETOOTH 0xA254
447
448#define AR_PHY_TPCRG1 0xA258
449#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
450#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
451
452#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
453#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
454#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
455#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
456#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
457#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
458
459#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
460#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
461
462#define AR_PHY_TX_PWRCTRL4 0xa264
463#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
464#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
465#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
466#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
467
468#define AR_PHY_TX_PWRCTRL6_0 0xa270
469#define AR_PHY_TX_PWRCTRL6_1 0xb270
470#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
471#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
472
473#define AR_PHY_TX_PWRCTRL7 0xa274
474#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
475#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
476
477#define AR_PHY_TX_PWRCTRL9 0xa27C
478#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
479#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
480#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
481#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
482
483#define AR_PHY_TX_GAIN_TBL1 0xa300
484#define AR_PHY_TX_GAIN 0x0007F000
485#define AR_PHY_TX_GAIN_S 12
486
487#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
488#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
489#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
490#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
491
492#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
493#define AR_PHY_MASK2_M_31_45 0xa3a4
494#define AR_PHY_MASK2_M_16_30 0xa3a8
495#define AR_PHY_MASK2_M_00_15 0xa3ac
496#define AR_PHY_MASK2_P_15_01 0xa3b8
497#define AR_PHY_MASK2_P_30_16 0xa3bc
498#define AR_PHY_MASK2_P_45_31 0xa3c0
499#define AR_PHY_MASK2_P_61_45 0xa3c4
500#define AR_PHY_SPUR_REG 0x994c
501
502#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
503#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
504
505#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
506#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
507#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
508#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
509#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
510#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
511
512#define AR_PHY_PILOT_MASK_01_30 0xa3b0
513#define AR_PHY_PILOT_MASK_31_60 0xa3b4
514
515#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
516#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
517
518#define AR_PHY_ANALOG_SWAP 0xa268
519#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
520
521#define AR_PHY_TPCRG5 0xA26C
522#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
523#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
524#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
525#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
526#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
527#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
528#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
529#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
530#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
531#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
532
533/* Carrier leak calibration control, do it after AGC calibration */
534#define AR_PHY_CL_CAL_CTL 0xA358
535#define AR_PHY_CL_CAL_ENABLE 0x00000002
536#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
537
538#define AR_PHY_POWER_TX_RATE5 0xA38C
539#define AR_PHY_POWER_TX_RATE6 0xA390
540
541#define AR_PHY_CAL_CHAINMASK 0xA39C
542
543#define AR_PHY_POWER_TX_SUB 0xA3C8
544#define AR_PHY_POWER_TX_RATE7 0xA3CC
545#define AR_PHY_POWER_TX_RATE8 0xA3D0
546#define AR_PHY_POWER_TX_RATE9 0xA3D4
547
548#define AR_PHY_XPA_CFG 0xA3D8
549#define AR_PHY_FORCE_XPA_CFG 0x000000001
550#define AR_PHY_FORCE_XPA_CFG_S 0
551
552#define AR_PHY_CH1_CCA 0xa864
553#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
554#define AR_PHY_CH1_MINCCA_PWR_S 19
555#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
556#define AR9280_PHY_CH1_MINCCA_PWR_S 20
557
558#define AR_PHY_CH2_CCA 0xb864
559#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
560#define AR_PHY_CH2_MINCCA_PWR_S 19
561
562#define AR_PHY_CH1_EXT_CCA 0xa9bc
563#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
564#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
565#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
566#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
567
568#define AR_PHY_CH2_EXT_CCA 0xb9bc
569#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
570#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
571
572#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
new file mode 100644
index 000000000000..56a9e5fa6d66
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -0,0 +1,802 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "hw-ops.h"
19#include "ar9003_phy.h"
20
21static void ar9003_hw_setup_calibration(struct ath_hw *ah,
22 struct ath9k_cal_list *currCal)
23{
24 struct ath_common *common = ath9k_hw_common(ah);
25
26 /* Select calibration to run */
27 switch (currCal->calData->calType) {
28 case IQ_MISMATCH_CAL:
29 /*
30 * Start calibration with
31 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
32 */
33 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
34 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
35 currCal->calData->calCountMax);
36 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
37
38 ath_print(common, ATH_DBG_CALIBRATE,
39 "starting IQ Mismatch Calibration\n");
40
41 /* Kick-off cal */
42 REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
43 break;
44 case TEMP_COMP_CAL:
45 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
46 AR_PHY_65NM_CH0_THERM_LOCAL, 1);
47 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
48 AR_PHY_65NM_CH0_THERM_START, 1);
49
50 ath_print(common, ATH_DBG_CALIBRATE,
51 "starting Temperature Compensation Calibration\n");
52 break;
53 case ADC_DC_INIT_CAL:
54 case ADC_GAIN_CAL:
55 case ADC_DC_CAL:
56 /* Not yet */
57 break;
58 }
59}
60
61/*
62 * Generic calibration routine.
63 * Recalibrate the lower PHY chips to account for temperature/environment
64 * changes.
65 */
66static bool ar9003_hw_per_calibration(struct ath_hw *ah,
67 struct ath9k_channel *ichan,
68 u8 rxchainmask,
69 struct ath9k_cal_list *currCal)
70{
71 /* Cal is assumed not done until explicitly set below */
72 bool iscaldone = false;
73
74 /* Calibration in progress. */
75 if (currCal->calState == CAL_RUNNING) {
76 /* Check to see if it has finished. */
77 if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
78 /*
79 * Accumulate cal measures for active chains
80 */
81 currCal->calData->calCollect(ah);
82 ah->cal_samples++;
83
84 if (ah->cal_samples >=
85 currCal->calData->calNumSamples) {
86 unsigned int i, numChains = 0;
87 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
88 if (rxchainmask & (1 << i))
89 numChains++;
90 }
91
92 /*
93 * Process accumulated data
94 */
95 currCal->calData->calPostProc(ah, numChains);
96
97 /* Calibration has finished. */
98 ichan->CalValid |= currCal->calData->calType;
99 currCal->calState = CAL_DONE;
100 iscaldone = true;
101 } else {
102 /*
103 * Set-up collection of another sub-sample until we
104 * get desired number
105 */
106 ar9003_hw_setup_calibration(ah, currCal);
107 }
108 }
109 } else if (!(ichan->CalValid & currCal->calData->calType)) {
110 /* If current cal is marked invalid in channel, kick it off */
111 ath9k_hw_reset_calibration(ah, currCal);
112 }
113
114 return iscaldone;
115}
116
117static bool ar9003_hw_calibrate(struct ath_hw *ah,
118 struct ath9k_channel *chan,
119 u8 rxchainmask,
120 bool longcal)
121{
122 bool iscaldone = true;
123 struct ath9k_cal_list *currCal = ah->cal_list_curr;
124
125 /*
126 * For given calibration:
127 * 1. Call generic cal routine
128 * 2. When this cal is done (isCalDone) if we have more cals waiting
129 * (eg after reset), mask this to upper layers by not propagating
130 * isCalDone if it is set to TRUE.
131 * Instead, change isCalDone to FALSE and setup the waiting cal(s)
132 * to be run.
133 */
134 if (currCal &&
135 (currCal->calState == CAL_RUNNING ||
136 currCal->calState == CAL_WAITING)) {
137 iscaldone = ar9003_hw_per_calibration(ah, chan,
138 rxchainmask, currCal);
139 if (iscaldone) {
140 ah->cal_list_curr = currCal = currCal->calNext;
141
142 if (currCal->calState == CAL_WAITING) {
143 iscaldone = false;
144 ath9k_hw_reset_calibration(ah, currCal);
145 }
146 }
147 }
148
149 /* Do NF cal only at longer intervals */
150 if (longcal) {
151 /*
152 * Load the NF from history buffer of the current channel.
153 * NF is slow time-variant, so it is OK to use a historical
154 * value.
155 */
156 ath9k_hw_loadnf(ah, ah->curchan);
157
158 /* start NF calibration, without updating BB NF register */
159 ath9k_hw_start_nfcal(ah);
160 }
161
162 return iscaldone;
163}
164
165static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
166{
167 int i;
168
169 /* Accumulate IQ cal measures for active chains */
170 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
171 ah->totalPowerMeasI[i] +=
172 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
173 ah->totalPowerMeasQ[i] +=
174 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
175 ah->totalIqCorrMeas[i] +=
176 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
177 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
178 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
179 ah->cal_samples, i, ah->totalPowerMeasI[i],
180 ah->totalPowerMeasQ[i],
181 ah->totalIqCorrMeas[i]);
182 }
183}
184
185static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
186{
187 struct ath_common *common = ath9k_hw_common(ah);
188 u32 powerMeasQ, powerMeasI, iqCorrMeas;
189 u32 qCoffDenom, iCoffDenom;
190 int32_t qCoff, iCoff;
191 int iqCorrNeg, i;
192 const u_int32_t offset_array[3] = {
193 AR_PHY_RX_IQCAL_CORR_B0,
194 AR_PHY_RX_IQCAL_CORR_B1,
195 AR_PHY_RX_IQCAL_CORR_B2,
196 };
197
198 for (i = 0; i < numChains; i++) {
199 powerMeasI = ah->totalPowerMeasI[i];
200 powerMeasQ = ah->totalPowerMeasQ[i];
201 iqCorrMeas = ah->totalIqCorrMeas[i];
202
203 ath_print(common, ATH_DBG_CALIBRATE,
204 "Starting IQ Cal and Correction for Chain %d\n",
205 i);
206
207 ath_print(common, ATH_DBG_CALIBRATE,
208 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
209 i, ah->totalIqCorrMeas[i]);
210
211 iqCorrNeg = 0;
212
213 if (iqCorrMeas > 0x80000000) {
214 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
215 iqCorrNeg = 1;
216 }
217
218 ath_print(common, ATH_DBG_CALIBRATE,
219 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
220 ath_print(common, ATH_DBG_CALIBRATE,
221 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
222 ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
223 iqCorrNeg);
224
225 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
226 qCoffDenom = powerMeasQ / 64;
227
228 if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
229 iCoff = iqCorrMeas / iCoffDenom;
230 qCoff = powerMeasI / qCoffDenom - 64;
231 ath_print(common, ATH_DBG_CALIBRATE,
232 "Chn %d iCoff = 0x%08x\n", i, iCoff);
233 ath_print(common, ATH_DBG_CALIBRATE,
234 "Chn %d qCoff = 0x%08x\n", i, qCoff);
235
236 /* Force bounds on iCoff */
237 if (iCoff >= 63)
238 iCoff = 63;
239 else if (iCoff <= -63)
240 iCoff = -63;
241
242 /* Negate iCoff if iqCorrNeg == 0 */
243 if (iqCorrNeg == 0x0)
244 iCoff = -iCoff;
245
246 /* Force bounds on qCoff */
247 if (qCoff >= 63)
248 qCoff = 63;
249 else if (qCoff <= -63)
250 qCoff = -63;
251
252 iCoff = iCoff & 0x7f;
253 qCoff = qCoff & 0x7f;
254
255 ath_print(common, ATH_DBG_CALIBRATE,
256 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
257 i, iCoff, qCoff);
258 ath_print(common, ATH_DBG_CALIBRATE,
259 "Register offset (0x%04x) "
260 "before update = 0x%x\n",
261 offset_array[i],
262 REG_READ(ah, offset_array[i]));
263
264 REG_RMW_FIELD(ah, offset_array[i],
265 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
266 iCoff);
267 REG_RMW_FIELD(ah, offset_array[i],
268 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
269 qCoff);
270 ath_print(common, ATH_DBG_CALIBRATE,
271 "Register offset (0x%04x) QI COFF "
272 "(bitfields 0x%08x) after update = 0x%x\n",
273 offset_array[i],
274 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
275 REG_READ(ah, offset_array[i]));
276 ath_print(common, ATH_DBG_CALIBRATE,
277 "Register offset (0x%04x) QQ COFF "
278 "(bitfields 0x%08x) after update = 0x%x\n",
279 offset_array[i],
280 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
281 REG_READ(ah, offset_array[i]));
282
283 ath_print(common, ATH_DBG_CALIBRATE,
284 "IQ Cal and Correction done for Chain %d\n",
285 i);
286 }
287 }
288
289 REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
290 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
291 ath_print(common, ATH_DBG_CALIBRATE,
292 "IQ Cal and Correction (offset 0x%04x) enabled "
293 "(bit position 0x%08x). New Value 0x%08x\n",
294 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
295 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
296 REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
297}
298
299static const struct ath9k_percal_data iq_cal_single_sample = {
300 IQ_MISMATCH_CAL,
301 MIN_CAL_SAMPLES,
302 PER_MAX_LOG_COUNT,
303 ar9003_hw_iqcal_collect,
304 ar9003_hw_iqcalibrate
305};
306
307static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
308{
309 ah->iq_caldata.calData = &iq_cal_single_sample;
310 ah->supp_cals = IQ_MISMATCH_CAL;
311}
312
313static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
314 enum ath9k_cal_types calType)
315{
316 switch (calType & ah->supp_cals) {
317 case IQ_MISMATCH_CAL:
318 /*
319 * XXX: Run IQ Mismatch for non-CCK only
320 * Note that CHANNEL_B is never set though.
321 */
322 return true;
323 case ADC_GAIN_CAL:
324 case ADC_DC_CAL:
325 return false;
326 case TEMP_COMP_CAL:
327 return true;
328 }
329
330 return false;
331}
332
333/*
334 * solve 4x4 linear equation used in loopback iq cal.
335 */
336static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
337 s32 sin_2phi_1,
338 s32 cos_2phi_1,
339 s32 sin_2phi_2,
340 s32 cos_2phi_2,
341 s32 mag_a0_d0,
342 s32 phs_a0_d0,
343 s32 mag_a1_d0,
344 s32 phs_a1_d0,
345 s32 solved_eq[])
346{
347 s32 f1 = cos_2phi_1 - cos_2phi_2,
348 f3 = sin_2phi_1 - sin_2phi_2,
349 f2;
350 s32 mag_tx, phs_tx, mag_rx, phs_rx;
351 const s32 result_shift = 1 << 15;
352 struct ath_common *common = ath9k_hw_common(ah);
353
354 f2 = (f1 * f1 + f3 * f3) / result_shift;
355
356 if (!f2) {
357 ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n");
358 return false;
359 }
360
361 /* mag mismatch, tx */
362 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
363 /* phs mismatch, tx */
364 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
365
366 mag_tx = (mag_tx / f2);
367 phs_tx = (phs_tx / f2);
368
369 /* mag mismatch, rx */
370 mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
371 result_shift;
372 /* phs mismatch, rx */
373 phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
374 result_shift;
375
376 solved_eq[0] = mag_tx;
377 solved_eq[1] = phs_tx;
378 solved_eq[2] = mag_rx;
379 solved_eq[3] = phs_rx;
380
381 return true;
382}
383
384static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
385{
386 s32 abs_i = abs(in_re),
387 abs_q = abs(in_im),
388 max_abs, min_abs;
389
390 if (abs_i > abs_q) {
391 max_abs = abs_i;
392 min_abs = abs_q;
393 } else {
394 max_abs = abs_q;
395 min_abs = abs_i;
396 }
397
398 return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
399}
400
401#define DELPT 32
402
403static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
404 s32 chain_idx,
405 const s32 iq_res[],
406 s32 iqc_coeff[])
407{
408 s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
409 i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
410 i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
411 i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
412 s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
413 phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
414 sin_2phi_1, cos_2phi_1,
415 sin_2phi_2, cos_2phi_2;
416 s32 mag_tx, phs_tx, mag_rx, phs_rx;
417 s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
418 q_q_coff, q_i_coff;
419 const s32 res_scale = 1 << 15;
420 const s32 delpt_shift = 1 << 8;
421 s32 mag1, mag2;
422 struct ath_common *common = ath9k_hw_common(ah);
423
424 i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
425 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
426 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
427
428 if (i2_m_q2_a0_d0 > 0x800)
429 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
430
431 if (i2_p_q2_a0_d0 > 0x800)
432 i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
433
434 if (iq_corr_a0_d0 > 0x800)
435 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
436
437 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
438 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
439 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
440
441 if (i2_m_q2_a0_d1 > 0x800)
442 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
443
444 if (i2_p_q2_a0_d1 > 0x800)
445 i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
446
447 if (iq_corr_a0_d1 > 0x800)
448 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
449
450 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
451 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
452 iq_corr_a1_d0 = iq_res[4] & 0xfff;
453
454 if (i2_m_q2_a1_d0 > 0x800)
455 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
456
457 if (i2_p_q2_a1_d0 > 0x800)
458 i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
459
460 if (iq_corr_a1_d0 > 0x800)
461 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
462
463 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
464 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
465 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
466
467 if (i2_m_q2_a1_d1 > 0x800)
468 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
469
470 if (i2_p_q2_a1_d1 > 0x800)
471 i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
472
473 if (iq_corr_a1_d1 > 0x800)
474 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
475
476 if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
477 (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
478 ath_print(common, ATH_DBG_CALIBRATE,
479 "Divide by 0:\na0_d0=%d\n"
480 "a0_d1=%d\na2_d0=%d\na1_d1=%d\n",
481 i2_p_q2_a0_d0, i2_p_q2_a0_d1,
482 i2_p_q2_a1_d0, i2_p_q2_a1_d1);
483 return false;
484 }
485
486 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
487 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
488
489 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
490 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
491
492 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
493 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
494
495 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
496 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
497
498 /* w/o analog phase shift */
499 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
500 /* w/o analog phase shift */
501 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
502 /* w/ analog phase shift */
503 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
504 /* w/ analog phase shift */
505 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
506
507 /*
508 * force sin^2 + cos^2 = 1;
509 * find magnitude by approximation
510 */
511 mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
512 mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
513
514 if ((mag1 == 0) || (mag2 == 0)) {
515 ath_print(common, ATH_DBG_CALIBRATE,
516 "Divide by 0: mag1=%d, mag2=%d\n",
517 mag1, mag2);
518 return false;
519 }
520
521 /* normalization sin and cos by mag */
522 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
523 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
524 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
525 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
526
527 /* calculate IQ mismatch */
528 if (!ar9003_hw_solve_iq_cal(ah,
529 sin_2phi_1, cos_2phi_1,
530 sin_2phi_2, cos_2phi_2,
531 mag_a0_d0, phs_a0_d0,
532 mag_a1_d0,
533 phs_a1_d0, solved_eq)) {
534 ath_print(common, ATH_DBG_CALIBRATE,
535 "Call to ar9003_hw_solve_iq_cal() failed.\n");
536 return false;
537 }
538
539 mag_tx = solved_eq[0];
540 phs_tx = solved_eq[1];
541 mag_rx = solved_eq[2];
542 phs_rx = solved_eq[3];
543
544 ath_print(common, ATH_DBG_CALIBRATE,
545 "chain %d: mag mismatch=%d phase mismatch=%d\n",
546 chain_idx, mag_tx/res_scale, phs_tx/res_scale);
547
548 if (res_scale == mag_tx) {
549 ath_print(common, ATH_DBG_CALIBRATE,
550 "Divide by 0: mag_tx=%d, res_scale=%d\n",
551 mag_tx, res_scale);
552 return false;
553 }
554
555 /* calculate and quantize Tx IQ correction factor */
556 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
557 phs_corr_tx = -phs_tx;
558
559 q_q_coff = (mag_corr_tx * 128 / res_scale);
560 q_i_coff = (phs_corr_tx * 256 / res_scale);
561
562 ath_print(common, ATH_DBG_CALIBRATE,
563 "tx chain %d: mag corr=%d phase corr=%d\n",
564 chain_idx, q_q_coff, q_i_coff);
565
566 if (q_i_coff < -63)
567 q_i_coff = -63;
568 if (q_i_coff > 63)
569 q_i_coff = 63;
570 if (q_q_coff < -63)
571 q_q_coff = -63;
572 if (q_q_coff > 63)
573 q_q_coff = 63;
574
575 iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
576
577 ath_print(common, ATH_DBG_CALIBRATE,
578 "tx chain %d: iq corr coeff=%x\n",
579 chain_idx, iqc_coeff[0]);
580
581 if (-mag_rx == res_scale) {
582 ath_print(common, ATH_DBG_CALIBRATE,
583 "Divide by 0: mag_rx=%d, res_scale=%d\n",
584 mag_rx, res_scale);
585 return false;
586 }
587
588 /* calculate and quantize Rx IQ correction factors */
589 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
590 phs_corr_rx = -phs_rx;
591
592 q_q_coff = (mag_corr_rx * 128 / res_scale);
593 q_i_coff = (phs_corr_rx * 256 / res_scale);
594
595 ath_print(common, ATH_DBG_CALIBRATE,
596 "rx chain %d: mag corr=%d phase corr=%d\n",
597 chain_idx, q_q_coff, q_i_coff);
598
599 if (q_i_coff < -63)
600 q_i_coff = -63;
601 if (q_i_coff > 63)
602 q_i_coff = 63;
603 if (q_q_coff < -63)
604 q_q_coff = -63;
605 if (q_q_coff > 63)
606 q_q_coff = 63;
607
608 iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
609
610 ath_print(common, ATH_DBG_CALIBRATE,
611 "rx chain %d: iq corr coeff=%x\n",
612 chain_idx, iqc_coeff[1]);
613
614 return true;
615}
616
617static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
618{
619 struct ath_common *common = ath9k_hw_common(ah);
620 const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
621 AR_PHY_TX_IQCAL_STATUS_B0,
622 AR_PHY_TX_IQCAL_STATUS_B1,
623 AR_PHY_TX_IQCAL_STATUS_B2,
624 };
625 const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = {
626 AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
627 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
628 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2,
629 };
630 const u32 rx_corr[AR9300_MAX_CHAINS] = {
631 AR_PHY_RX_IQCAL_CORR_B0,
632 AR_PHY_RX_IQCAL_CORR_B1,
633 AR_PHY_RX_IQCAL_CORR_B2,
634 };
635 const u_int32_t chan_info_tab[] = {
636 AR_PHY_CHAN_INFO_TAB_0,
637 AR_PHY_CHAN_INFO_TAB_1,
638 AR_PHY_CHAN_INFO_TAB_2,
639 };
640 s32 iq_res[6];
641 s32 iqc_coeff[2];
642 s32 i, j;
643 u32 num_chains = 0;
644
645 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
646 if (ah->txchainmask & (1 << i))
647 num_chains++;
648 }
649
650 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
651 AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
652 DELPT);
653 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
654 AR_PHY_TX_IQCAL_START_DO_CAL,
655 AR_PHY_TX_IQCAL_START_DO_CAL);
656
657 if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
658 AR_PHY_TX_IQCAL_START_DO_CAL,
659 0, AH_WAIT_TIMEOUT)) {
660 ath_print(common, ATH_DBG_CALIBRATE,
661 "Tx IQ Cal not complete.\n");
662 goto TX_IQ_CAL_FAILED;
663 }
664
665 for (i = 0; i < num_chains; i++) {
666 ath_print(common, ATH_DBG_CALIBRATE,
667 "Doing Tx IQ Cal for chain %d.\n", i);
668
669 if (REG_READ(ah, txiqcal_status[i]) &
670 AR_PHY_TX_IQCAL_STATUS_FAILED) {
671 ath_print(common, ATH_DBG_CALIBRATE,
672 "Tx IQ Cal failed for chain %d.\n", i);
673 goto TX_IQ_CAL_FAILED;
674 }
675
676 for (j = 0; j < 3; j++) {
677 u_int8_t idx = 2 * j,
678 offset = 4 * j;
679
680 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
681 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
682
683 /* 32 bits */
684 iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
685
686 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
687 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
688
689 /* 16 bits */
690 iq_res[idx+1] = 0xffff & REG_READ(ah,
691 chan_info_tab[i] +
692 offset);
693
694 ath_print(common, ATH_DBG_CALIBRATE,
695 "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
696 idx, iq_res[idx], idx+1, iq_res[idx+1]);
697 }
698
699 if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
700 ath_print(common, ATH_DBG_CALIBRATE,
701 "Failed in calculation of IQ correction.\n");
702 goto TX_IQ_CAL_FAILED;
703 }
704
705 ath_print(common, ATH_DBG_CALIBRATE,
706 "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
707 iqc_coeff[0], iqc_coeff[1]);
708
709 REG_RMW_FIELD(ah, tx_corr_coeff[i],
710 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
711 iqc_coeff[0]);
712 REG_RMW_FIELD(ah, rx_corr[i],
713 AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
714 iqc_coeff[1] >> 7);
715 REG_RMW_FIELD(ah, rx_corr[i],
716 AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
717 iqc_coeff[1]);
718 }
719
720 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
721 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
722 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
723 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
724
725 return;
726
727TX_IQ_CAL_FAILED:
728 ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
729}
730
731static bool ar9003_hw_init_cal(struct ath_hw *ah,
732 struct ath9k_channel *chan)
733{
734 struct ath_common *common = ath9k_hw_common(ah);
735
736 /*
737 * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before
738 * running AGC/TxIQ cals
739 */
740 ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
741
742 /* Calibrate the AGC */
743 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
744 REG_READ(ah, AR_PHY_AGC_CONTROL) |
745 AR_PHY_AGC_CONTROL_CAL);
746
747 /* Poll for offset calibration complete */
748 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
749 0, AH_WAIT_TIMEOUT)) {
750 ath_print(common, ATH_DBG_CALIBRATE,
751 "offset calibration failed to "
752 "complete in 1ms; noisy environment?\n");
753 return false;
754 }
755
756 /* Do Tx IQ Calibration */
757 if (ah->config.tx_iq_calibration)
758 ar9003_hw_tx_iq_cal(ah);
759
760 /* Revert chainmasks to their original values before NF cal */
761 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
762
763 /* Initialize list pointers */
764 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
765
766 if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
767 INIT_CAL(&ah->iq_caldata);
768 INSERT_CAL(ah, &ah->iq_caldata);
769 ath_print(common, ATH_DBG_CALIBRATE,
770 "enabling IQ Calibration.\n");
771 }
772
773 if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
774 INIT_CAL(&ah->tempCompCalData);
775 INSERT_CAL(ah, &ah->tempCompCalData);
776 ath_print(common, ATH_DBG_CALIBRATE,
777 "enabling Temperature Compensation Calibration.\n");
778 }
779
780 /* Initialize current pointer to first element in list */
781 ah->cal_list_curr = ah->cal_list;
782
783 if (ah->cal_list_curr)
784 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
785
786 chan->CalValid = 0;
787
788 return true;
789}
790
791void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
792{
793 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
794 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
795
796 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
797 priv_ops->init_cal = ar9003_hw_init_cal;
798 priv_ops->setup_calibration = ar9003_hw_setup_calibration;
799 priv_ops->iscal_supported = ar9003_hw_iscal_supported;
800
801 ops->calibrate = ar9003_hw_calibrate;
802}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
new file mode 100644
index 000000000000..23eb60ea5455
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -0,0 +1,1838 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar9003_phy.h"
19#include "ar9003_eeprom.h"
20
21#define COMP_HDR_LEN 4
22#define COMP_CKSUM_LEN 2
23
24#define AR_CH0_TOP (0x00016288)
25#define AR_CH0_TOP_XPABIASLVL (0x3)
26#define AR_CH0_TOP_XPABIASLVL_S (8)
27
28#define AR_CH0_THERM (0x00016290)
29#define AR_CH0_THERM_SPARE (0x3f)
30#define AR_CH0_THERM_SPARE_S (0)
31
32#define AR_SWITCH_TABLE_COM_ALL (0xffff)
33#define AR_SWITCH_TABLE_COM_ALL_S (0)
34
35#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
36#define AR_SWITCH_TABLE_COM2_ALL_S (0)
37
38#define AR_SWITCH_TABLE_ALL (0xfff)
39#define AR_SWITCH_TABLE_ALL_S (0)
40
41#define LE16(x) __constant_cpu_to_le16(x)
42#define LE32(x) __constant_cpu_to_le32(x)
43
44static const struct ar9300_eeprom ar9300_default = {
45 .eepromVersion = 2,
46 .templateVersion = 2,
47 .macAddr = {1, 2, 3, 4, 5, 6},
48 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
50 .baseEepHeader = {
51 .regDmn = { LE16(0), LE16(0x1f) },
52 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
53 .opCapFlags = {
54 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
55 .eepMisc = 0,
56 },
57 .rfSilent = 0,
58 .blueToothOptions = 0,
59 .deviceCap = 0,
60 .deviceType = 5, /* takes lower byte in eeprom location */
61 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
62 .params_for_tuning_caps = {0, 0},
63 .featureEnable = 0x0c,
64 /*
65 * bit0 - enable tx temp comp - disabled
66 * bit1 - enable tx volt comp - disabled
67 * bit2 - enable fastClock - enabled
68 * bit3 - enable doubling - enabled
69 * bit4 - enable internal regulator - disabled
70 */
71 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
72 .eepromWriteEnableGpio = 3,
73 .wlanDisableGpio = 0,
74 .wlanLedGpio = 8,
75 .rxBandSelectGpio = 0xff,
76 .txrxgain = 0,
77 .swreg = 0,
78 },
79 .modalHeader2G = {
80 /* ar9300_modal_eep_header 2g */
81 /* 4 idle,t1,t2,b(4 bits per setting) */
82 .antCtrlCommon = LE32(0x110),
83 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
84 .antCtrlCommon2 = LE32(0x22222),
85
86 /*
87 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
88 * rx1, rx12, b (2 bits each)
89 */
90 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
91
92 /*
93 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
94 * for ar9280 (0xa20c/b20c 5:0)
95 */
96 .xatten1DB = {0, 0, 0},
97
98 /*
99 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
100 * for ar9280 (0xa20c/b20c 16:12
101 */
102 .xatten1Margin = {0, 0, 0},
103 .tempSlope = 36,
104 .voltSlope = 0,
105
106 /*
107 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
108 * channels in usual fbin coding format
109 */
110 .spurChans = {0, 0, 0, 0, 0},
111
112 /*
113 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
114 * if the register is per chain
115 */
116 .noiseFloorThreshCh = {-1, 0, 0},
117 .ob = {1, 1, 1},/* 3 chain */
118 .db_stage2 = {1, 1, 1}, /* 3 chain */
119 .db_stage3 = {0, 0, 0},
120 .db_stage4 = {0, 0, 0},
121 .xpaBiasLvl = 0,
122 .txFrameToDataStart = 0x0e,
123 .txFrameToPaOn = 0x0e,
124 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
125 .antennaGain = 0,
126 .switchSettling = 0x2c,
127 .adcDesiredSize = -30,
128 .txEndToXpaOff = 0,
129 .txEndToRxOn = 0x2,
130 .txFrameToXpaOn = 0xe,
131 .thresh62 = 28,
132 .futureModal = { /* [32] */
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
135 },
136 },
137 .calFreqPier2G = {
138 FREQ2FBIN(2412, 1),
139 FREQ2FBIN(2437, 1),
140 FREQ2FBIN(2472, 1),
141 },
142 /* ar9300_cal_data_per_freq_op_loop 2g */
143 .calPierData2G = {
144 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
145 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
146 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
147 },
148 .calTarget_freqbin_Cck = {
149 FREQ2FBIN(2412, 1),
150 FREQ2FBIN(2484, 1),
151 },
152 .calTarget_freqbin_2G = {
153 FREQ2FBIN(2412, 1),
154 FREQ2FBIN(2437, 1),
155 FREQ2FBIN(2472, 1)
156 },
157 .calTarget_freqbin_2GHT20 = {
158 FREQ2FBIN(2412, 1),
159 FREQ2FBIN(2437, 1),
160 FREQ2FBIN(2472, 1)
161 },
162 .calTarget_freqbin_2GHT40 = {
163 FREQ2FBIN(2412, 1),
164 FREQ2FBIN(2437, 1),
165 FREQ2FBIN(2472, 1)
166 },
167 .calTargetPowerCck = {
168 /* 1L-5L,5S,11L,11S */
169 { {36, 36, 36, 36} },
170 { {36, 36, 36, 36} },
171 },
172 .calTargetPower2G = {
173 /* 6-24,36,48,54 */
174 { {32, 32, 28, 24} },
175 { {32, 32, 28, 24} },
176 { {32, 32, 28, 24} },
177 },
178 .calTargetPower2GHT20 = {
179 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
180 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
181 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
182 },
183 .calTargetPower2GHT40 = {
184 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
185 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
186 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
187 },
188 .ctlIndex_2G = {
189 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
190 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
191 },
192 .ctl_freqbin_2G = {
193 {
194 FREQ2FBIN(2412, 1),
195 FREQ2FBIN(2417, 1),
196 FREQ2FBIN(2457, 1),
197 FREQ2FBIN(2462, 1)
198 },
199 {
200 FREQ2FBIN(2412, 1),
201 FREQ2FBIN(2417, 1),
202 FREQ2FBIN(2462, 1),
203 0xFF,
204 },
205
206 {
207 FREQ2FBIN(2412, 1),
208 FREQ2FBIN(2417, 1),
209 FREQ2FBIN(2462, 1),
210 0xFF,
211 },
212 {
213 FREQ2FBIN(2422, 1),
214 FREQ2FBIN(2427, 1),
215 FREQ2FBIN(2447, 1),
216 FREQ2FBIN(2452, 1)
217 },
218
219 {
220 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
221 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
222 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
223 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
224 },
225
226 {
227 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
228 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
229 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
230 0,
231 },
232
233 {
234 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
235 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
236 FREQ2FBIN(2472, 1),
237 0,
238 },
239
240 {
241 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
242 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
243 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
244 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
245 },
246
247 {
248 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
249 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
250 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
251 },
252
253 {
254 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
255 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
256 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
257 0
258 },
259
260 {
261 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
262 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
263 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
264 0
265 },
266
267 {
268 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
269 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
270 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
271 /* Data[11].ctlEdges[3].bChannel */
272 FREQ2FBIN(2462, 1),
273 }
274 },
275 .ctlPowerData_2G = {
276 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
277 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
278 { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
279
280 { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
281 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
282 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
283
284 { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
285 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
286 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
287
288 { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
289 { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
290 },
291 .modalHeader5G = {
292 /* 4 idle,t1,t2,b (4 bits per setting) */
293 .antCtrlCommon = LE32(0x110),
294 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
295 .antCtrlCommon2 = LE32(0x22222),
296 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
297 .antCtrlChain = {
298 LE16(0x000), LE16(0x000), LE16(0x000),
299 },
300 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
301 .xatten1DB = {0, 0, 0},
302
303 /*
304 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
305 * for merlin (0xa20c/b20c 16:12
306 */
307 .xatten1Margin = {0, 0, 0},
308 .tempSlope = 68,
309 .voltSlope = 0,
310 /* spurChans spur channels in usual fbin coding format */
311 .spurChans = {0, 0, 0, 0, 0},
312 /* noiseFloorThreshCh Check if the register is per chain */
313 .noiseFloorThreshCh = {-1, 0, 0},
314 .ob = {3, 3, 3}, /* 3 chain */
315 .db_stage2 = {3, 3, 3}, /* 3 chain */
316 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
317 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
318 .xpaBiasLvl = 0,
319 .txFrameToDataStart = 0x0e,
320 .txFrameToPaOn = 0x0e,
321 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
322 .antennaGain = 0,
323 .switchSettling = 0x2d,
324 .adcDesiredSize = -30,
325 .txEndToXpaOff = 0,
326 .txEndToRxOn = 0x2,
327 .txFrameToXpaOn = 0xe,
328 .thresh62 = 28,
329 .futureModal = {
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
332 },
333 },
334 .calFreqPier5G = {
335 FREQ2FBIN(5180, 0),
336 FREQ2FBIN(5220, 0),
337 FREQ2FBIN(5320, 0),
338 FREQ2FBIN(5400, 0),
339 FREQ2FBIN(5500, 0),
340 FREQ2FBIN(5600, 0),
341 FREQ2FBIN(5725, 0),
342 FREQ2FBIN(5825, 0)
343 },
344 .calPierData5G = {
345 {
346 {0, 0, 0, 0, 0},
347 {0, 0, 0, 0, 0},
348 {0, 0, 0, 0, 0},
349 {0, 0, 0, 0, 0},
350 {0, 0, 0, 0, 0},
351 {0, 0, 0, 0, 0},
352 {0, 0, 0, 0, 0},
353 {0, 0, 0, 0, 0},
354 },
355 {
356 {0, 0, 0, 0, 0},
357 {0, 0, 0, 0, 0},
358 {0, 0, 0, 0, 0},
359 {0, 0, 0, 0, 0},
360 {0, 0, 0, 0, 0},
361 {0, 0, 0, 0, 0},
362 {0, 0, 0, 0, 0},
363 {0, 0, 0, 0, 0},
364 },
365 {
366 {0, 0, 0, 0, 0},
367 {0, 0, 0, 0, 0},
368 {0, 0, 0, 0, 0},
369 {0, 0, 0, 0, 0},
370 {0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0},
372 {0, 0, 0, 0, 0},
373 {0, 0, 0, 0, 0},
374 },
375
376 },
377 .calTarget_freqbin_5G = {
378 FREQ2FBIN(5180, 0),
379 FREQ2FBIN(5220, 0),
380 FREQ2FBIN(5320, 0),
381 FREQ2FBIN(5400, 0),
382 FREQ2FBIN(5500, 0),
383 FREQ2FBIN(5600, 0),
384 FREQ2FBIN(5725, 0),
385 FREQ2FBIN(5825, 0)
386 },
387 .calTarget_freqbin_5GHT20 = {
388 FREQ2FBIN(5180, 0),
389 FREQ2FBIN(5240, 0),
390 FREQ2FBIN(5320, 0),
391 FREQ2FBIN(5500, 0),
392 FREQ2FBIN(5700, 0),
393 FREQ2FBIN(5745, 0),
394 FREQ2FBIN(5725, 0),
395 FREQ2FBIN(5825, 0)
396 },
397 .calTarget_freqbin_5GHT40 = {
398 FREQ2FBIN(5180, 0),
399 FREQ2FBIN(5240, 0),
400 FREQ2FBIN(5320, 0),
401 FREQ2FBIN(5500, 0),
402 FREQ2FBIN(5700, 0),
403 FREQ2FBIN(5745, 0),
404 FREQ2FBIN(5725, 0),
405 FREQ2FBIN(5825, 0)
406 },
407 .calTargetPower5G = {
408 /* 6-24,36,48,54 */
409 { {20, 20, 20, 10} },
410 { {20, 20, 20, 10} },
411 { {20, 20, 20, 10} },
412 { {20, 20, 20, 10} },
413 { {20, 20, 20, 10} },
414 { {20, 20, 20, 10} },
415 { {20, 20, 20, 10} },
416 { {20, 20, 20, 10} },
417 },
418 .calTargetPower5GHT20 = {
419 /*
420 * 0_8_16,1-3_9-11_17-19,
421 * 4,5,6,7,12,13,14,15,20,21,22,23
422 */
423 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
424 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
425 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
426 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
427 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
428 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
429 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
430 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
431 },
432 .calTargetPower5GHT40 = {
433 /*
434 * 0_8_16,1-3_9-11_17-19,
435 * 4,5,6,7,12,13,14,15,20,21,22,23
436 */
437 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
438 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
439 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
440 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
441 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
442 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
443 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
444 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
445 },
446 .ctlIndex_5G = {
447 0x10, 0x16, 0x18, 0x40, 0x46,
448 0x48, 0x30, 0x36, 0x38
449 },
450 .ctl_freqbin_5G = {
451 {
452 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
453 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
454 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
455 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
456 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
457 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
458 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
459 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
460 },
461 {
462 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
463 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
464 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
465 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
466 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
467 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
468 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
469 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
470 },
471
472 {
473 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
474 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
475 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
476 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
477 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
478 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
479 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
480 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
481 },
482
483 {
484 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
485 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
486 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
487 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
488 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
489 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
490 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
491 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
492 },
493
494 {
495 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
496 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
497 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
498 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
499 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
500 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
501 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
502 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
503 },
504
505 {
506 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
507 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
508 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
509 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
510 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
511 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
512 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
513 /* Data[5].ctlEdges[7].bChannel */ 0xFF
514 },
515
516 {
517 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
518 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
519 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
520 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
521 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
522 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
523 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
524 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
525 },
526
527 {
528 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
529 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
530 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
531 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
532 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
533 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
534 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
535 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
536 },
537
538 {
539 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
540 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
541 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
542 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
543 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
544 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
545 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
546 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
547 }
548 },
549 .ctlPowerData_5G = {
550 {
551 {
552 {60, 1}, {60, 1}, {60, 1}, {60, 1},
553 {60, 1}, {60, 1}, {60, 1}, {60, 0},
554 }
555 },
556 {
557 {
558 {60, 1}, {60, 1}, {60, 1}, {60, 1},
559 {60, 1}, {60, 1}, {60, 1}, {60, 0},
560 }
561 },
562 {
563 {
564 {60, 0}, {60, 1}, {60, 0}, {60, 1},
565 {60, 1}, {60, 1}, {60, 1}, {60, 1},
566 }
567 },
568 {
569 {
570 {60, 0}, {60, 1}, {60, 1}, {60, 0},
571 {60, 1}, {60, 0}, {60, 0}, {60, 0},
572 }
573 },
574 {
575 {
576 {60, 1}, {60, 1}, {60, 1}, {60, 0},
577 {60, 0}, {60, 0}, {60, 0}, {60, 0},
578 }
579 },
580 {
581 {
582 {60, 1}, {60, 1}, {60, 1}, {60, 1},
583 {60, 1}, {60, 0}, {60, 0}, {60, 0},
584 }
585 },
586 {
587 {
588 {60, 1}, {60, 1}, {60, 1}, {60, 1},
589 {60, 1}, {60, 1}, {60, 1}, {60, 1},
590 }
591 },
592 {
593 {
594 {60, 1}, {60, 1}, {60, 0}, {60, 1},
595 {60, 1}, {60, 1}, {60, 1}, {60, 0},
596 }
597 },
598 {
599 {
600 {60, 1}, {60, 0}, {60, 1}, {60, 1},
601 {60, 1}, {60, 1}, {60, 0}, {60, 1},
602 }
603 },
604 }
605};
606
607static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
608{
609 return 0;
610}
611
612static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
613 enum eeprom_param param)
614{
615 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
616 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
617
618 switch (param) {
619 case EEP_MAC_LSW:
620 return eep->macAddr[0] << 8 | eep->macAddr[1];
621 case EEP_MAC_MID:
622 return eep->macAddr[2] << 8 | eep->macAddr[3];
623 case EEP_MAC_MSW:
624 return eep->macAddr[4] << 8 | eep->macAddr[5];
625 case EEP_REG_0:
626 return le16_to_cpu(pBase->regDmn[0]);
627 case EEP_REG_1:
628 return le16_to_cpu(pBase->regDmn[1]);
629 case EEP_OP_CAP:
630 return pBase->deviceCap;
631 case EEP_OP_MODE:
632 return pBase->opCapFlags.opFlags;
633 case EEP_RF_SILENT:
634 return pBase->rfSilent;
635 case EEP_TX_MASK:
636 return (pBase->txrxMask >> 4) & 0xf;
637 case EEP_RX_MASK:
638 return pBase->txrxMask & 0xf;
639 case EEP_DRIVE_STRENGTH:
640#define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
641 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
642 case EEP_INTERNAL_REGULATOR:
643 /* Bit 4 is internal regulator flag */
644 return (pBase->featureEnable & 0x10) >> 4;
645 case EEP_SWREG:
646 return le32_to_cpu(pBase->swreg);
647 default:
648 return 0;
649 }
650}
651
652static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
653 u8 *buffer)
654{
655 u16 val;
656
657 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
658 return false;
659
660 *buffer = (val >> (8 * (address % 2))) & 0xff;
661 return true;
662}
663
664static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
665 u8 *buffer)
666{
667 u16 val;
668
669 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
670 return false;
671
672 buffer[0] = val >> 8;
673 buffer[1] = val & 0xff;
674
675 return true;
676}
677
678static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
679 int count)
680{
681 struct ath_common *common = ath9k_hw_common(ah);
682 int i;
683
684 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
685 ath_print(common, ATH_DBG_EEPROM,
686 "eeprom address not in range\n");
687 return false;
688 }
689
690 /*
691 * Since we're reading the bytes in reverse order from a little-endian
692 * word stream, an even address means we only use the lower half of
693 * the 16-bit word at that address
694 */
695 if (address % 2 == 0) {
696 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
697 goto error;
698
699 count--;
700 }
701
702 for (i = 0; i < count / 2; i++) {
703 if (!ar9300_eeprom_read_word(common, address, buffer))
704 goto error;
705
706 address -= 2;
707 buffer += 2;
708 }
709
710 if (count % 2)
711 if (!ar9300_eeprom_read_byte(common, address, buffer))
712 goto error;
713
714 return true;
715
716error:
717 ath_print(common, ATH_DBG_EEPROM,
718 "unable to read eeprom region at offset %d\n", address);
719 return false;
720}
721
722static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
723 int *length, int *major, int *minor)
724{
725 unsigned long value[4];
726
727 value[0] = best[0];
728 value[1] = best[1];
729 value[2] = best[2];
730 value[3] = best[3];
731 *code = ((value[0] >> 5) & 0x0007);
732 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
733 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
734 *major = (value[2] & 0x000f);
735 *minor = (value[3] & 0x00ff);
736}
737
738static u16 ar9300_comp_cksum(u8 *data, int dsize)
739{
740 int it, checksum = 0;
741
742 for (it = 0; it < dsize; it++) {
743 checksum += data[it];
744 checksum &= 0xffff;
745 }
746
747 return checksum;
748}
749
750static bool ar9300_uncompress_block(struct ath_hw *ah,
751 u8 *mptr,
752 int mdataSize,
753 u8 *block,
754 int size)
755{
756 int it;
757 int spot;
758 int offset;
759 int length;
760 struct ath_common *common = ath9k_hw_common(ah);
761
762 spot = 0;
763
764 for (it = 0; it < size; it += (length+2)) {
765 offset = block[it];
766 offset &= 0xff;
767 spot += offset;
768 length = block[it+1];
769 length &= 0xff;
770
771 if (length > 0 && spot >= 0 && spot+length < mdataSize) {
772 ath_print(common, ATH_DBG_EEPROM,
773 "Restore at %d: spot=%d "
774 "offset=%d length=%d\n",
775 it, spot, offset, length);
776 memcpy(&mptr[spot], &block[it+2], length);
777 spot += length;
778 } else if (length > 0) {
779 ath_print(common, ATH_DBG_EEPROM,
780 "Bad restore at %d: spot=%d "
781 "offset=%d length=%d\n",
782 it, spot, offset, length);
783 return false;
784 }
785 }
786 return true;
787}
788
789static int ar9300_compress_decision(struct ath_hw *ah,
790 int it,
791 int code,
792 int reference,
793 u8 *mptr,
794 u8 *word, int length, int mdata_size)
795{
796 struct ath_common *common = ath9k_hw_common(ah);
797 u8 *dptr;
798
799 switch (code) {
800 case _CompressNone:
801 if (length != mdata_size) {
802 ath_print(common, ATH_DBG_EEPROM,
803 "EEPROM structure size mismatch"
804 "memory=%d eeprom=%d\n", mdata_size, length);
805 return -1;
806 }
807 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
808 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
809 " uncompressed, length %d\n", it, length);
810 break;
811 case _CompressBlock:
812 if (reference == 0) {
813 dptr = mptr;
814 } else {
815 if (reference != 2) {
816 ath_print(common, ATH_DBG_EEPROM,
817 "cant find reference eeprom"
818 "struct %d\n", reference);
819 return -1;
820 }
821 memcpy(mptr, &ar9300_default, mdata_size);
822 }
823 ath_print(common, ATH_DBG_EEPROM,
824 "restore eeprom %d: block, reference %d,"
825 " length %d\n", it, reference, length);
826 ar9300_uncompress_block(ah, mptr, mdata_size,
827 (u8 *) (word + COMP_HDR_LEN), length);
828 break;
829 default:
830 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
831 " code %d\n", code);
832 return -1;
833 }
834 return 0;
835}
836
837/*
838 * Read the configuration data from the eeprom.
839 * The data can be put in any specified memory buffer.
840 *
841 * Returns -1 on error.
842 * Returns address of next memory location on success.
843 */
844static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
845 u8 *mptr, int mdata_size)
846{
847#define MDEFAULT 15
848#define MSTATE 100
849 int cptr;
850 u8 *word;
851 int code;
852 int reference, length, major, minor;
853 int osize;
854 int it;
855 u16 checksum, mchecksum;
856 struct ath_common *common = ath9k_hw_common(ah);
857
858 word = kzalloc(2048, GFP_KERNEL);
859 if (!word)
860 return -1;
861
862 memcpy(mptr, &ar9300_default, mdata_size);
863
864 cptr = AR9300_BASE_ADDR;
865 for (it = 0; it < MSTATE; it++) {
866 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
867 goto fail;
868
869 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
870 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
871 && word[2] == 0xff && word[3] == 0xff))
872 break;
873
874 ar9300_comp_hdr_unpack(word, &code, &reference,
875 &length, &major, &minor);
876 ath_print(common, ATH_DBG_EEPROM,
877 "Found block at %x: code=%d ref=%d"
878 "length=%d major=%d minor=%d\n", cptr, code,
879 reference, length, major, minor);
880 if (length >= 1024) {
881 ath_print(common, ATH_DBG_EEPROM,
882 "Skipping bad header\n");
883 cptr -= COMP_HDR_LEN;
884 continue;
885 }
886
887 osize = length;
888 ar9300_read_eeprom(ah, cptr, word,
889 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
890 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
891 mchecksum = word[COMP_HDR_LEN + osize] |
892 (word[COMP_HDR_LEN + osize + 1] << 8);
893 ath_print(common, ATH_DBG_EEPROM,
894 "checksum %x %x\n", checksum, mchecksum);
895 if (checksum == mchecksum) {
896 ar9300_compress_decision(ah, it, code, reference, mptr,
897 word, length, mdata_size);
898 } else {
899 ath_print(common, ATH_DBG_EEPROM,
900 "skipping block with bad checksum\n");
901 }
902 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
903 }
904
905 kfree(word);
906 return cptr;
907
908fail:
909 kfree(word);
910 return -1;
911}
912
913/*
914 * Restore the configuration structure by reading the eeprom.
915 * This function destroys any existing in-memory structure
916 * content.
917 */
918static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
919{
920 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
921
922 if (ar9300_eeprom_restore_internal(ah, mptr,
923 sizeof(struct ar9300_eeprom)) < 0)
924 return false;
925
926 return true;
927}
928
929/* XXX: review hardware docs */
930static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
931{
932 return ah->eeprom.ar9300_eep.eepromVersion;
933}
934
935/* XXX: could be read from the eepromVersion, not sure yet */
936static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
937{
938 return 0;
939}
940
941static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
942 enum ieee80211_band freq_band)
943{
944 return 1;
945}
946
947static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
948 struct ath9k_channel *chan)
949{
950 return -EINVAL;
951}
952
953static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
954{
955 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
956
957 if (is2ghz)
958 return eep->modalHeader2G.xpaBiasLvl;
959 else
960 return eep->modalHeader5G.xpaBiasLvl;
961}
962
963static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
964{
965 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
966 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
967 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
968 ((bias >> 2) & 0x3));
969}
970
971static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
972{
973 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
974 __le32 val;
975
976 if (is2ghz)
977 val = eep->modalHeader2G.antCtrlCommon;
978 else
979 val = eep->modalHeader5G.antCtrlCommon;
980 return le32_to_cpu(val);
981}
982
983static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
984{
985 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
986 __le32 val;
987
988 if (is2ghz)
989 val = eep->modalHeader2G.antCtrlCommon2;
990 else
991 val = eep->modalHeader5G.antCtrlCommon2;
992 return le32_to_cpu(val);
993}
994
995static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
996 int chain,
997 bool is2ghz)
998{
999 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1000 __le16 val = 0;
1001
1002 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1003 if (is2ghz)
1004 val = eep->modalHeader2G.antCtrlChain[chain];
1005 else
1006 val = eep->modalHeader5G.antCtrlChain[chain];
1007 }
1008
1009 return le16_to_cpu(val);
1010}
1011
1012static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
1013{
1014 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
1015 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
1016
1017 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
1018 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1019
1020 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
1021 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1022
1023 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
1024 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1025
1026 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
1027 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1028}
1029
1030static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
1031{
1032 int drive_strength;
1033 unsigned long reg;
1034
1035 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
1036
1037 if (!drive_strength)
1038 return;
1039
1040 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1041 reg &= ~0x00ffffc0;
1042 reg |= 0x5 << 21;
1043 reg |= 0x5 << 18;
1044 reg |= 0x5 << 15;
1045 reg |= 0x5 << 12;
1046 reg |= 0x5 << 9;
1047 reg |= 0x5 << 6;
1048 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1049
1050 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1051 reg &= ~0xffffffe0;
1052 reg |= 0x5 << 29;
1053 reg |= 0x5 << 26;
1054 reg |= 0x5 << 23;
1055 reg |= 0x5 << 20;
1056 reg |= 0x5 << 17;
1057 reg |= 0x5 << 14;
1058 reg |= 0x5 << 11;
1059 reg |= 0x5 << 8;
1060 reg |= 0x5 << 5;
1061 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1062
1063 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1064 reg &= ~0xff800000;
1065 reg |= 0x5 << 29;
1066 reg |= 0x5 << 26;
1067 reg |= 0x5 << 23;
1068 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1069}
1070
1071static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
1072{
1073 int internal_regulator =
1074 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
1075
1076 if (internal_regulator) {
1077 /* Internal regulator is ON. Write swreg register. */
1078 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
1079 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1080 REG_READ(ah, AR_RTC_REG_CONTROL1) &
1081 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1082 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1083 /* Set REG_CONTROL1.SWREG_PROGRAM */
1084 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1085 REG_READ(ah,
1086 AR_RTC_REG_CONTROL1) |
1087 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1088 } else {
1089 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1090 (REG_READ(ah,
1091 AR_RTC_SLEEP_CLK) |
1092 AR_RTC_FORCE_SWREG_PRD));
1093 }
1094}
1095
1096static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
1097 struct ath9k_channel *chan)
1098{
1099 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
1100 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
1101 ar9003_hw_drive_strength_apply(ah);
1102 ar9003_hw_internal_regulator_apply(ah);
1103}
1104
1105static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
1106 struct ath9k_channel *chan)
1107{
1108}
1109
1110/*
1111 * Returns the interpolated y value corresponding to the specified x value
1112 * from the np ordered pairs of data (px,py).
1113 * The pairs do not have to be in any order.
1114 * If the specified x value is less than any of the px,
1115 * the returned y value is equal to the py for the lowest px.
1116 * If the specified x value is greater than any of the px,
1117 * the returned y value is equal to the py for the highest px.
1118 */
1119static int ar9003_hw_power_interpolate(int32_t x,
1120 int32_t *px, int32_t *py, u_int16_t np)
1121{
1122 int ip = 0;
1123 int lx = 0, ly = 0, lhave = 0;
1124 int hx = 0, hy = 0, hhave = 0;
1125 int dx = 0;
1126 int y = 0;
1127
1128 lhave = 0;
1129 hhave = 0;
1130
1131 /* identify best lower and higher x calibration measurement */
1132 for (ip = 0; ip < np; ip++) {
1133 dx = x - px[ip];
1134
1135 /* this measurement is higher than our desired x */
1136 if (dx <= 0) {
1137 if (!hhave || dx > (x - hx)) {
1138 /* new best higher x measurement */
1139 hx = px[ip];
1140 hy = py[ip];
1141 hhave = 1;
1142 }
1143 }
1144 /* this measurement is lower than our desired x */
1145 if (dx >= 0) {
1146 if (!lhave || dx < (x - lx)) {
1147 /* new best lower x measurement */
1148 lx = px[ip];
1149 ly = py[ip];
1150 lhave = 1;
1151 }
1152 }
1153 }
1154
1155 /* the low x is good */
1156 if (lhave) {
1157 /* so is the high x */
1158 if (hhave) {
1159 /* they're the same, so just pick one */
1160 if (hx == lx)
1161 y = ly;
1162 else /* interpolate */
1163 y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
1164 } else /* only low is good, use it */
1165 y = ly;
1166 } else if (hhave) /* only high is good, use it */
1167 y = hy;
1168 else /* nothing is good,this should never happen unless np=0, ???? */
1169 y = -(1 << 30);
1170 return y;
1171}
1172
1173static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
1174 u16 rateIndex, u16 freq, bool is2GHz)
1175{
1176 u16 numPiers, i;
1177 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1178 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1179 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1180 struct cal_tgt_pow_legacy *pEepromTargetPwr;
1181 u8 *pFreqBin;
1182
1183 if (is2GHz) {
1184 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1185 pEepromTargetPwr = eep->calTargetPower2G;
1186 pFreqBin = eep->calTarget_freqbin_2G;
1187 } else {
1188 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1189 pEepromTargetPwr = eep->calTargetPower5G;
1190 pFreqBin = eep->calTarget_freqbin_5G;
1191 }
1192
1193 /*
1194 * create array of channels and targetpower from
1195 * targetpower piers stored on eeprom
1196 */
1197 for (i = 0; i < numPiers; i++) {
1198 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1199 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1200 }
1201
1202 /* interpolate to get target power for given frequency */
1203 return (u8) ar9003_hw_power_interpolate((s32) freq,
1204 freqArray,
1205 targetPowerArray, numPiers);
1206}
1207
1208static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
1209 u16 rateIndex,
1210 u16 freq, bool is2GHz)
1211{
1212 u16 numPiers, i;
1213 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1214 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1215 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1216 struct cal_tgt_pow_ht *pEepromTargetPwr;
1217 u8 *pFreqBin;
1218
1219 if (is2GHz) {
1220 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1221 pEepromTargetPwr = eep->calTargetPower2GHT20;
1222 pFreqBin = eep->calTarget_freqbin_2GHT20;
1223 } else {
1224 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1225 pEepromTargetPwr = eep->calTargetPower5GHT20;
1226 pFreqBin = eep->calTarget_freqbin_5GHT20;
1227 }
1228
1229 /*
1230 * create array of channels and targetpower
1231 * from targetpower piers stored on eeprom
1232 */
1233 for (i = 0; i < numPiers; i++) {
1234 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1235 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1236 }
1237
1238 /* interpolate to get target power for given frequency */
1239 return (u8) ar9003_hw_power_interpolate((s32) freq,
1240 freqArray,
1241 targetPowerArray, numPiers);
1242}
1243
1244static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
1245 u16 rateIndex,
1246 u16 freq, bool is2GHz)
1247{
1248 u16 numPiers, i;
1249 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
1250 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
1251 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1252 struct cal_tgt_pow_ht *pEepromTargetPwr;
1253 u8 *pFreqBin;
1254
1255 if (is2GHz) {
1256 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
1257 pEepromTargetPwr = eep->calTargetPower2GHT40;
1258 pFreqBin = eep->calTarget_freqbin_2GHT40;
1259 } else {
1260 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
1261 pEepromTargetPwr = eep->calTargetPower5GHT40;
1262 pFreqBin = eep->calTarget_freqbin_5GHT40;
1263 }
1264
1265 /*
1266 * create array of channels and targetpower from
1267 * targetpower piers stored on eeprom
1268 */
1269 for (i = 0; i < numPiers; i++) {
1270 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1271 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1272 }
1273
1274 /* interpolate to get target power for given frequency */
1275 return (u8) ar9003_hw_power_interpolate((s32) freq,
1276 freqArray,
1277 targetPowerArray, numPiers);
1278}
1279
1280static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
1281 u16 rateIndex, u16 freq)
1282{
1283 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
1284 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1285 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1286 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1287 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
1288 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
1289
1290 /*
1291 * create array of channels and targetpower from
1292 * targetpower piers stored on eeprom
1293 */
1294 for (i = 0; i < numPiers; i++) {
1295 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
1296 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1297 }
1298
1299 /* interpolate to get target power for given frequency */
1300 return (u8) ar9003_hw_power_interpolate((s32) freq,
1301 freqArray,
1302 targetPowerArray, numPiers);
1303}
1304
1305/* Set tx power registers to array of values passed in */
1306static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
1307{
1308#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
1309 /* make sure forced gain is not set */
1310 REG_WRITE(ah, 0xa458, 0);
1311
1312 /* Write the OFDM power per rate set */
1313
1314 /* 6 (LSB), 9, 12, 18 (MSB) */
1315 REG_WRITE(ah, 0xa3c0,
1316 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
1317 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
1318 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
1319 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1320
1321 /* 24 (LSB), 36, 48, 54 (MSB) */
1322 REG_WRITE(ah, 0xa3c4,
1323 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
1324 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
1325 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
1326 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1327
1328 /* Write the CCK power per rate set */
1329
1330 /* 1L (LSB), reserved, 2L, 2S (MSB) */
1331 REG_WRITE(ah, 0xa3c8,
1332 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
1333 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
1334 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
1335 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
1336
1337 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
1338 REG_WRITE(ah, 0xa3cc,
1339 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
1340 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
1341 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
1342 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
1343 );
1344
1345 /* Write the HT20 power per rate set */
1346
1347 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
1348 REG_WRITE(ah, 0xa3d0,
1349 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
1350 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
1351 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
1352 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
1353 );
1354
1355 /* 6 (LSB), 7, 12, 13 (MSB) */
1356 REG_WRITE(ah, 0xa3d4,
1357 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
1358 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
1359 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
1360 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
1361 );
1362
1363 /* 14 (LSB), 15, 20, 21 */
1364 REG_WRITE(ah, 0xa3e4,
1365 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
1366 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
1367 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
1368 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
1369 );
1370
1371 /* Mixed HT20 and HT40 rates */
1372
1373 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
1374 REG_WRITE(ah, 0xa3e8,
1375 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
1376 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
1377 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
1378 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
1379 );
1380
1381 /*
1382 * Write the HT40 power per rate set
1383 * correct PAR difference between HT40 and HT20/LEGACY
1384 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
1385 */
1386 REG_WRITE(ah, 0xa3d8,
1387 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
1388 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
1389 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
1390 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
1391 );
1392
1393 /* 6 (LSB), 7, 12, 13 (MSB) */
1394 REG_WRITE(ah, 0xa3dc,
1395 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
1396 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
1397 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
1398 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
1399 );
1400
1401 /* 14 (LSB), 15, 20, 21 */
1402 REG_WRITE(ah, 0xa3ec,
1403 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
1404 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
1405 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
1406 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
1407 );
1408
1409 return 0;
1410#undef POW_SM
1411}
1412
1413static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
1414{
1415 u8 targetPowerValT2[ar9300RateSize];
1416 /* XXX: hard code for now, need to get from eeprom struct */
1417 u8 ht40PowerIncForPdadc = 0;
1418 bool is2GHz = false;
1419 unsigned int i = 0;
1420 struct ath_common *common = ath9k_hw_common(ah);
1421
1422 if (freq < 4000)
1423 is2GHz = true;
1424
1425 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1426 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1427 is2GHz);
1428 targetPowerValT2[ALL_TARGET_LEGACY_36] =
1429 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1430 is2GHz);
1431 targetPowerValT2[ALL_TARGET_LEGACY_48] =
1432 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1433 is2GHz);
1434 targetPowerValT2[ALL_TARGET_LEGACY_54] =
1435 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1436 is2GHz);
1437 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1438 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1439 freq);
1440 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1441 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1442 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1443 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1444 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1445 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1446 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1447 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1448 is2GHz);
1449 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1450 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1451 freq, is2GHz);
1452 targetPowerValT2[ALL_TARGET_HT20_4] =
1453 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1454 is2GHz);
1455 targetPowerValT2[ALL_TARGET_HT20_5] =
1456 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1457 is2GHz);
1458 targetPowerValT2[ALL_TARGET_HT20_6] =
1459 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1460 is2GHz);
1461 targetPowerValT2[ALL_TARGET_HT20_7] =
1462 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1463 is2GHz);
1464 targetPowerValT2[ALL_TARGET_HT20_12] =
1465 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1466 is2GHz);
1467 targetPowerValT2[ALL_TARGET_HT20_13] =
1468 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1469 is2GHz);
1470 targetPowerValT2[ALL_TARGET_HT20_14] =
1471 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1472 is2GHz);
1473 targetPowerValT2[ALL_TARGET_HT20_15] =
1474 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1475 is2GHz);
1476 targetPowerValT2[ALL_TARGET_HT20_20] =
1477 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1478 is2GHz);
1479 targetPowerValT2[ALL_TARGET_HT20_21] =
1480 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1481 is2GHz);
1482 targetPowerValT2[ALL_TARGET_HT20_22] =
1483 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1484 is2GHz);
1485 targetPowerValT2[ALL_TARGET_HT20_23] =
1486 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1487 is2GHz);
1488 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1489 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1490 is2GHz) + ht40PowerIncForPdadc;
1491 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1492 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1493 freq,
1494 is2GHz) + ht40PowerIncForPdadc;
1495 targetPowerValT2[ALL_TARGET_HT40_4] =
1496 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1497 is2GHz) + ht40PowerIncForPdadc;
1498 targetPowerValT2[ALL_TARGET_HT40_5] =
1499 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1500 is2GHz) + ht40PowerIncForPdadc;
1501 targetPowerValT2[ALL_TARGET_HT40_6] =
1502 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1503 is2GHz) + ht40PowerIncForPdadc;
1504 targetPowerValT2[ALL_TARGET_HT40_7] =
1505 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1506 is2GHz) + ht40PowerIncForPdadc;
1507 targetPowerValT2[ALL_TARGET_HT40_12] =
1508 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1509 is2GHz) + ht40PowerIncForPdadc;
1510 targetPowerValT2[ALL_TARGET_HT40_13] =
1511 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1512 is2GHz) + ht40PowerIncForPdadc;
1513 targetPowerValT2[ALL_TARGET_HT40_14] =
1514 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1515 is2GHz) + ht40PowerIncForPdadc;
1516 targetPowerValT2[ALL_TARGET_HT40_15] =
1517 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1518 is2GHz) + ht40PowerIncForPdadc;
1519 targetPowerValT2[ALL_TARGET_HT40_20] =
1520 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1521 is2GHz) + ht40PowerIncForPdadc;
1522 targetPowerValT2[ALL_TARGET_HT40_21] =
1523 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1524 is2GHz) + ht40PowerIncForPdadc;
1525 targetPowerValT2[ALL_TARGET_HT40_22] =
1526 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1527 is2GHz) + ht40PowerIncForPdadc;
1528 targetPowerValT2[ALL_TARGET_HT40_23] =
1529 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1530 is2GHz) + ht40PowerIncForPdadc;
1531
1532 while (i < ar9300RateSize) {
1533 ath_print(common, ATH_DBG_EEPROM,
1534 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1535 i++;
1536
1537 ath_print(common, ATH_DBG_EEPROM,
1538 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1539 i++;
1540
1541 ath_print(common, ATH_DBG_EEPROM,
1542 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1543 i++;
1544
1545 ath_print(common, ATH_DBG_EEPROM,
1546 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1547 i++;
1548 }
1549
1550 /* Write target power array to registers */
1551 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
1552}
1553
1554static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1555 int mode,
1556 int ipier,
1557 int ichain,
1558 int *pfrequency,
1559 int *pcorrection,
1560 int *ptemperature, int *pvoltage)
1561{
1562 u8 *pCalPier;
1563 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1564 int is2GHz;
1565 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1566 struct ath_common *common = ath9k_hw_common(ah);
1567
1568 if (ichain >= AR9300_MAX_CHAINS) {
1569 ath_print(common, ATH_DBG_EEPROM,
1570 "Invalid chain index, must be less than %d\n",
1571 AR9300_MAX_CHAINS);
1572 return -1;
1573 }
1574
1575 if (mode) { /* 5GHz */
1576 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1577 ath_print(common, ATH_DBG_EEPROM,
1578 "Invalid 5GHz cal pier index, must "
1579 "be less than %d\n",
1580 AR9300_NUM_5G_CAL_PIERS);
1581 return -1;
1582 }
1583 pCalPier = &(eep->calFreqPier5G[ipier]);
1584 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1585 is2GHz = 0;
1586 } else {
1587 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1588 ath_print(common, ATH_DBG_EEPROM,
1589 "Invalid 2GHz cal pier index, must "
1590 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1591 return -1;
1592 }
1593
1594 pCalPier = &(eep->calFreqPier2G[ipier]);
1595 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1596 is2GHz = 1;
1597 }
1598
1599 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1600 *pcorrection = pCalPierStruct->refPower;
1601 *ptemperature = pCalPierStruct->tempMeas;
1602 *pvoltage = pCalPierStruct->voltMeas;
1603
1604 return 0;
1605}
1606
1607static int ar9003_hw_power_control_override(struct ath_hw *ah,
1608 int frequency,
1609 int *correction,
1610 int *voltage, int *temperature)
1611{
1612 int tempSlope = 0;
1613 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1614
1615 REG_RMW(ah, AR_PHY_TPC_11_B0,
1616 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1617 AR_PHY_TPC_OLPC_GAIN_DELTA);
1618 REG_RMW(ah, AR_PHY_TPC_11_B1,
1619 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1620 AR_PHY_TPC_OLPC_GAIN_DELTA);
1621 REG_RMW(ah, AR_PHY_TPC_11_B2,
1622 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1623 AR_PHY_TPC_OLPC_GAIN_DELTA);
1624
1625 /* enable open loop power control on chip */
1626 REG_RMW(ah, AR_PHY_TPC_6_B0,
1627 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1628 AR_PHY_TPC_6_ERROR_EST_MODE);
1629 REG_RMW(ah, AR_PHY_TPC_6_B1,
1630 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1631 AR_PHY_TPC_6_ERROR_EST_MODE);
1632 REG_RMW(ah, AR_PHY_TPC_6_B2,
1633 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1634 AR_PHY_TPC_6_ERROR_EST_MODE);
1635
1636 /*
1637 * enable temperature compensation
1638 * Need to use register names
1639 */
1640 if (frequency < 4000)
1641 tempSlope = eep->modalHeader2G.tempSlope;
1642 else
1643 tempSlope = eep->modalHeader5G.tempSlope;
1644
1645 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1646 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1647 temperature[0]);
1648
1649 return 0;
1650}
1651
1652/* Apply the recorded correction values. */
1653static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1654{
1655 int ichain, ipier, npier;
1656 int mode;
1657 int lfrequency[AR9300_MAX_CHAINS],
1658 lcorrection[AR9300_MAX_CHAINS],
1659 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1660 int hfrequency[AR9300_MAX_CHAINS],
1661 hcorrection[AR9300_MAX_CHAINS],
1662 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1663 int fdiff;
1664 int correction[AR9300_MAX_CHAINS],
1665 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1666 int pfrequency, pcorrection, ptemperature, pvoltage;
1667 struct ath_common *common = ath9k_hw_common(ah);
1668
1669 mode = (frequency >= 4000);
1670 if (mode)
1671 npier = AR9300_NUM_5G_CAL_PIERS;
1672 else
1673 npier = AR9300_NUM_2G_CAL_PIERS;
1674
1675 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1676 lfrequency[ichain] = 0;
1677 hfrequency[ichain] = 100000;
1678 }
1679 /* identify best lower and higher frequency calibration measurement */
1680 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1681 for (ipier = 0; ipier < npier; ipier++) {
1682 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1683 &pfrequency, &pcorrection,
1684 &ptemperature, &pvoltage)) {
1685 fdiff = frequency - pfrequency;
1686
1687 /*
1688 * this measurement is higher than
1689 * our desired frequency
1690 */
1691 if (fdiff <= 0) {
1692 if (hfrequency[ichain] <= 0 ||
1693 hfrequency[ichain] >= 100000 ||
1694 fdiff >
1695 (frequency - hfrequency[ichain])) {
1696 /*
1697 * new best higher
1698 * frequency measurement
1699 */
1700 hfrequency[ichain] = pfrequency;
1701 hcorrection[ichain] =
1702 pcorrection;
1703 htemperature[ichain] =
1704 ptemperature;
1705 hvoltage[ichain] = pvoltage;
1706 }
1707 }
1708 if (fdiff >= 0) {
1709 if (lfrequency[ichain] <= 0
1710 || fdiff <
1711 (frequency - lfrequency[ichain])) {
1712 /*
1713 * new best lower
1714 * frequency measurement
1715 */
1716 lfrequency[ichain] = pfrequency;
1717 lcorrection[ichain] =
1718 pcorrection;
1719 ltemperature[ichain] =
1720 ptemperature;
1721 lvoltage[ichain] = pvoltage;
1722 }
1723 }
1724 }
1725 }
1726 }
1727
1728 /* interpolate */
1729 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1730 ath_print(common, ATH_DBG_EEPROM,
1731 "ch=%d f=%d low=%d %d h=%d %d\n",
1732 ichain, frequency, lfrequency[ichain],
1733 lcorrection[ichain], hfrequency[ichain],
1734 hcorrection[ichain]);
1735 /* they're the same, so just pick one */
1736 if (hfrequency[ichain] == lfrequency[ichain]) {
1737 correction[ichain] = lcorrection[ichain];
1738 voltage[ichain] = lvoltage[ichain];
1739 temperature[ichain] = ltemperature[ichain];
1740 }
1741 /* the low frequency is good */
1742 else if (frequency - lfrequency[ichain] < 1000) {
1743 /* so is the high frequency, interpolate */
1744 if (hfrequency[ichain] - frequency < 1000) {
1745
1746 correction[ichain] = lcorrection[ichain] +
1747 (((frequency - lfrequency[ichain]) *
1748 (hcorrection[ichain] -
1749 lcorrection[ichain])) /
1750 (hfrequency[ichain] - lfrequency[ichain]));
1751
1752 temperature[ichain] = ltemperature[ichain] +
1753 (((frequency - lfrequency[ichain]) *
1754 (htemperature[ichain] -
1755 ltemperature[ichain])) /
1756 (hfrequency[ichain] - lfrequency[ichain]));
1757
1758 voltage[ichain] =
1759 lvoltage[ichain] +
1760 (((frequency -
1761 lfrequency[ichain]) * (hvoltage[ichain] -
1762 lvoltage[ichain]))
1763 / (hfrequency[ichain] -
1764 lfrequency[ichain]));
1765 }
1766 /* only low is good, use it */
1767 else {
1768 correction[ichain] = lcorrection[ichain];
1769 temperature[ichain] = ltemperature[ichain];
1770 voltage[ichain] = lvoltage[ichain];
1771 }
1772 }
1773 /* only high is good, use it */
1774 else if (hfrequency[ichain] - frequency < 1000) {
1775 correction[ichain] = hcorrection[ichain];
1776 temperature[ichain] = htemperature[ichain];
1777 voltage[ichain] = hvoltage[ichain];
1778 } else { /* nothing is good, presume 0???? */
1779 correction[ichain] = 0;
1780 temperature[ichain] = 0;
1781 voltage[ichain] = 0;
1782 }
1783 }
1784
1785 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1786 temperature);
1787
1788 ath_print(common, ATH_DBG_EEPROM,
1789 "for frequency=%d, calibration correction = %d %d %d\n",
1790 frequency, correction[0], correction[1], correction[2]);
1791
1792 return 0;
1793}
1794
1795static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
1796 struct ath9k_channel *chan, u16 cfgCtl,
1797 u8 twiceAntennaReduction,
1798 u8 twiceMaxRegulatoryPower,
1799 u8 powerLimit)
1800{
1801 ah->txpower_limit = powerLimit;
1802 ar9003_hw_set_target_power_eeprom(ah, chan->channel);
1803 ar9003_hw_calibration_apply(ah, chan->channel);
1804}
1805
1806static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
1807 u16 i, bool is2GHz)
1808{
1809 return AR_NO_SPUR;
1810}
1811
1812s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
1813{
1814 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1815
1816 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
1817}
1818
1819s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
1820{
1821 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1822
1823 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
1824}
1825
1826const struct eeprom_ops eep_ar9300_ops = {
1827 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
1828 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
1829 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
1830 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
1831 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
1832 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
1833 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
1834 .set_board_values = ath9k_hw_ar9300_set_board_values,
1835 .set_addac = ath9k_hw_ar9300_set_addac,
1836 .set_txpower = ath9k_hw_ar9300_set_txpower,
1837 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
1838};
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
new file mode 100644
index 000000000000..23fb353c3bba
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -0,0 +1,323 @@
1#ifndef AR9003_EEPROM_H
2#define AR9003_EEPROM_H
3
4#include <linux/types.h>
5
6#define AR9300_EEP_VER 0xD000
7#define AR9300_EEP_VER_MINOR_MASK 0xFFF
8#define AR9300_EEP_MINOR_VER_1 0x1
9#define AR9300_EEP_MINOR_VER AR9300_EEP_MINOR_VER_1
10
11/* 16-bit offset location start of calibration struct */
12#define AR9300_EEP_START_LOC 256
13#define AR9300_NUM_5G_CAL_PIERS 8
14#define AR9300_NUM_2G_CAL_PIERS 3
15#define AR9300_NUM_5G_20_TARGET_POWERS 8
16#define AR9300_NUM_5G_40_TARGET_POWERS 8
17#define AR9300_NUM_2G_CCK_TARGET_POWERS 2
18#define AR9300_NUM_2G_20_TARGET_POWERS 3
19#define AR9300_NUM_2G_40_TARGET_POWERS 3
20/* #define AR9300_NUM_CTLS 21 */
21#define AR9300_NUM_CTLS_5G 9
22#define AR9300_NUM_CTLS_2G 12
23#define AR9300_CTL_MODE_M 0xF
24#define AR9300_NUM_BAND_EDGES_5G 8
25#define AR9300_NUM_BAND_EDGES_2G 4
26#define AR9300_NUM_PD_GAINS 4
27#define AR9300_PD_GAINS_IN_MASK 4
28#define AR9300_PD_GAIN_ICEPTS 5
29#define AR9300_EEPROM_MODAL_SPURS 5
30#define AR9300_MAX_RATE_POWER 63
31#define AR9300_NUM_PDADC_VALUES 128
32#define AR9300_NUM_RATES 16
33#define AR9300_BCHAN_UNUSED 0xFF
34#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
35#define AR9300_OPFLAGS_11A 0x01
36#define AR9300_OPFLAGS_11G 0x02
37#define AR9300_OPFLAGS_5G_HT40 0x04
38#define AR9300_OPFLAGS_2G_HT40 0x08
39#define AR9300_OPFLAGS_5G_HT20 0x10
40#define AR9300_OPFLAGS_2G_HT20 0x20
41#define AR9300_EEPMISC_BIG_ENDIAN 0x01
42#define AR9300_EEPMISC_WOW 0x02
43#define AR9300_CUSTOMER_DATA_SIZE 20
44
45#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
46#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
47#define AR9300_MAX_CHAINS 3
48#define AR9300_ANT_16S 25
49#define AR9300_FUTURE_MODAL_SZ 6
50
51#define AR9300_NUM_ANT_CHAIN_FIELDS 7
52#define AR9300_NUM_ANT_COMMON_FIELDS 4
53#define AR9300_SIZE_ANT_CHAIN_FIELD 3
54#define AR9300_SIZE_ANT_COMMON_FIELD 4
55#define AR9300_ANT_CHAIN_MASK 0x7
56#define AR9300_ANT_COMMON_MASK 0xf
57#define AR9300_CHAIN_0_IDX 0
58#define AR9300_CHAIN_1_IDX 1
59#define AR9300_CHAIN_2_IDX 2
60
61#define AR928X_NUM_ANT_CHAIN_FIELDS 6
62#define AR928X_SIZE_ANT_CHAIN_FIELD 2
63#define AR928X_ANT_CHAIN_MASK 0x3
64
65/* Delta from which to start power to pdadc table */
66/* This offset is used in both open loop and closed loop power control
67 * schemes. In open loop power control, it is not really needed, but for
68 * the "sake of consistency" it was kept. For certain AP designs, this
69 * value is overwritten by the value in the flag "pwrTableOffset" just
70 * before writing the pdadc vs pwr into the chip registers.
71 */
72#define AR9300_PWR_TABLE_OFFSET 0
73
74/* enable flags for voltage and temp compensation */
75#define ENABLE_TEMP_COMPENSATION 0x01
76#define ENABLE_VOLT_COMPENSATION 0x02
77/* byte addressable */
78#define AR9300_EEPROM_SIZE (16*1024)
79#define FIXED_CCA_THRESHOLD 15
80
81#define AR9300_BASE_ADDR 0x3ff
82
83enum targetPowerHTRates {
84 HT_TARGET_RATE_0_8_16,
85 HT_TARGET_RATE_1_3_9_11_17_19,
86 HT_TARGET_RATE_4,
87 HT_TARGET_RATE_5,
88 HT_TARGET_RATE_6,
89 HT_TARGET_RATE_7,
90 HT_TARGET_RATE_12,
91 HT_TARGET_RATE_13,
92 HT_TARGET_RATE_14,
93 HT_TARGET_RATE_15,
94 HT_TARGET_RATE_20,
95 HT_TARGET_RATE_21,
96 HT_TARGET_RATE_22,
97 HT_TARGET_RATE_23
98};
99
100enum targetPowerLegacyRates {
101 LEGACY_TARGET_RATE_6_24,
102 LEGACY_TARGET_RATE_36,
103 LEGACY_TARGET_RATE_48,
104 LEGACY_TARGET_RATE_54
105};
106
107enum targetPowerCckRates {
108 LEGACY_TARGET_RATE_1L_5L,
109 LEGACY_TARGET_RATE_5S,
110 LEGACY_TARGET_RATE_11L,
111 LEGACY_TARGET_RATE_11S
112};
113
114enum ar9300_Rates {
115 ALL_TARGET_LEGACY_6_24,
116 ALL_TARGET_LEGACY_36,
117 ALL_TARGET_LEGACY_48,
118 ALL_TARGET_LEGACY_54,
119 ALL_TARGET_LEGACY_1L_5L,
120 ALL_TARGET_LEGACY_5S,
121 ALL_TARGET_LEGACY_11L,
122 ALL_TARGET_LEGACY_11S,
123 ALL_TARGET_HT20_0_8_16,
124 ALL_TARGET_HT20_1_3_9_11_17_19,
125 ALL_TARGET_HT20_4,
126 ALL_TARGET_HT20_5,
127 ALL_TARGET_HT20_6,
128 ALL_TARGET_HT20_7,
129 ALL_TARGET_HT20_12,
130 ALL_TARGET_HT20_13,
131 ALL_TARGET_HT20_14,
132 ALL_TARGET_HT20_15,
133 ALL_TARGET_HT20_20,
134 ALL_TARGET_HT20_21,
135 ALL_TARGET_HT20_22,
136 ALL_TARGET_HT20_23,
137 ALL_TARGET_HT40_0_8_16,
138 ALL_TARGET_HT40_1_3_9_11_17_19,
139 ALL_TARGET_HT40_4,
140 ALL_TARGET_HT40_5,
141 ALL_TARGET_HT40_6,
142 ALL_TARGET_HT40_7,
143 ALL_TARGET_HT40_12,
144 ALL_TARGET_HT40_13,
145 ALL_TARGET_HT40_14,
146 ALL_TARGET_HT40_15,
147 ALL_TARGET_HT40_20,
148 ALL_TARGET_HT40_21,
149 ALL_TARGET_HT40_22,
150 ALL_TARGET_HT40_23,
151 ar9300RateSize,
152};
153
154
155struct eepFlags {
156 u8 opFlags;
157 u8 eepMisc;
158} __packed;
159
160enum CompressAlgorithm {
161 _CompressNone = 0,
162 _CompressLzma,
163 _CompressPairs,
164 _CompressBlock,
165 _Compress4,
166 _Compress5,
167 _Compress6,
168 _Compress7,
169};
170
171struct ar9300_base_eep_hdr {
172 __le16 regDmn[2];
173 /* 4 bits tx and 4 bits rx */
174 u8 txrxMask;
175 struct eepFlags opCapFlags;
176 u8 rfSilent;
177 u8 blueToothOptions;
178 u8 deviceCap;
179 /* takes lower byte in eeprom location */
180 u8 deviceType;
181 /* offset in dB to be added to beginning
182 * of pdadc table in calibration
183 */
184 int8_t pwrTableOffset;
185 u8 params_for_tuning_caps[2];
186 /*
187 * bit0 - enable tx temp comp
188 * bit1 - enable tx volt comp
189 * bit2 - enable fastClock - default to 1
190 * bit3 - enable doubling - default to 1
191 * bit4 - enable internal regulator - default to 1
192 */
193 u8 featureEnable;
194 /* misc flags: bit0 - turn down drivestrength */
195 u8 miscConfiguration;
196 u8 eepromWriteEnableGpio;
197 u8 wlanDisableGpio;
198 u8 wlanLedGpio;
199 u8 rxBandSelectGpio;
200 u8 txrxgain;
201 /* SW controlled internal regulator fields */
202 __le32 swreg;
203} __packed;
204
205struct ar9300_modal_eep_header {
206 /* 4 idle, t1, t2, b (4 bits per setting) */
207 __le32 antCtrlCommon;
208 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
209 __le32 antCtrlCommon2;
210 /* 6 idle, t, r, rx1, rx12, b (2 bits each) */
211 __le16 antCtrlChain[AR9300_MAX_CHAINS];
212 /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
213 u8 xatten1DB[AR9300_MAX_CHAINS];
214 /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */
215 u8 xatten1Margin[AR9300_MAX_CHAINS];
216 int8_t tempSlope;
217 int8_t voltSlope;
218 /* spur channels in usual fbin coding format */
219 u8 spurChans[AR9300_EEPROM_MODAL_SPURS];
220 /* 3 Check if the register is per chain */
221 int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
222 u8 ob[AR9300_MAX_CHAINS];
223 u8 db_stage2[AR9300_MAX_CHAINS];
224 u8 db_stage3[AR9300_MAX_CHAINS];
225 u8 db_stage4[AR9300_MAX_CHAINS];
226 u8 xpaBiasLvl;
227 u8 txFrameToDataStart;
228 u8 txFrameToPaOn;
229 u8 txClip;
230 int8_t antennaGain;
231 u8 switchSettling;
232 int8_t adcDesiredSize;
233 u8 txEndToXpaOff;
234 u8 txEndToRxOn;
235 u8 txFrameToXpaOn;
236 u8 thresh62;
237 u8 futureModal[32];
238} __packed;
239
240struct ar9300_cal_data_per_freq_op_loop {
241 int8_t refPower;
242 /* pdadc voltage at power measurement */
243 u8 voltMeas;
244 /* pcdac used for power measurement */
245 u8 tempMeas;
246 /* range is -60 to -127 create a mapping equation 1db resolution */
247 int8_t rxNoisefloorCal;
248 /*range is same as noisefloor */
249 int8_t rxNoisefloorPower;
250 /* temp measured when noisefloor cal was performed */
251 u8 rxTempMeas;
252} __packed;
253
254struct cal_tgt_pow_legacy {
255 u8 tPow2x[4];
256} __packed;
257
258struct cal_tgt_pow_ht {
259 u8 tPow2x[14];
260} __packed;
261
262struct cal_ctl_edge_pwr {
263 u8 tPower:6,
264 flag:2;
265} __packed;
266
267struct cal_ctl_data_2g {
268 struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
269} __packed;
270
271struct cal_ctl_data_5g {
272 struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
273} __packed;
274
275struct ar9300_eeprom {
276 u8 eepromVersion;
277 u8 templateVersion;
278 u8 macAddr[6];
279 u8 custData[AR9300_CUSTOMER_DATA_SIZE];
280
281 struct ar9300_base_eep_hdr baseEepHeader;
282
283 struct ar9300_modal_eep_header modalHeader2G;
284 u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
285 struct ar9300_cal_data_per_freq_op_loop
286 calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
287 u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS];
288 u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS];
289 u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
290 u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
291 struct cal_tgt_pow_legacy
292 calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS];
293 struct cal_tgt_pow_legacy
294 calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS];
295 struct cal_tgt_pow_ht
296 calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
297 struct cal_tgt_pow_ht
298 calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
299 u8 ctlIndex_2G[AR9300_NUM_CTLS_2G];
300 u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
301 struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
302 struct ar9300_modal_eep_header modalHeader5G;
303 u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
304 struct ar9300_cal_data_per_freq_op_loop
305 calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
306 u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS];
307 u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
308 u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
309 struct cal_tgt_pow_legacy
310 calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS];
311 struct cal_tgt_pow_ht
312 calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
313 struct cal_tgt_pow_ht
314 calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
315 u8 ctlIndex_5G[AR9300_NUM_CTLS_5G];
316 u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
317 struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
318} __packed;
319
320s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
321s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
322
323#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
new file mode 100644
index 000000000000..b15309caf1da
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar9003_mac.h"
19#include "ar9003_initvals.h"
20
21/* General hardware code for the AR9003 hadware family */
22
23static bool ar9003_hw_macversion_supported(u32 macversion)
24{
25 switch (macversion) {
26 case AR_SREV_VERSION_9300:
27 return true;
28 default:
29 break;
30 }
31 return false;
32}
33
34/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
35/*
36 * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
37 * ensuring it does not affect hardware bring up
38 */
39static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
40{
41 /* mac */
42 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
43 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
44 ar9300_2p0_mac_core,
45 ARRAY_SIZE(ar9300_2p0_mac_core), 2);
46 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
47 ar9300_2p0_mac_postamble,
48 ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
49
50 /* bb */
51 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
52 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
53 ar9300_2p0_baseband_core,
54 ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
55 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
56 ar9300_2p0_baseband_postamble,
57 ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
58
59 /* radio */
60 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
61 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
62 ar9300_2p0_radio_core,
63 ARRAY_SIZE(ar9300_2p0_radio_core), 2);
64 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
65 ar9300_2p0_radio_postamble,
66 ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
67
68 /* soc */
69 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
70 ar9300_2p0_soc_preamble,
71 ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
72 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
73 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
74 ar9300_2p0_soc_postamble,
75 ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
76
77 /* rx/tx gain */
78 INIT_INI_ARRAY(&ah->iniModesRxGain,
79 ar9300Common_rx_gain_table_2p0,
80 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
81 INIT_INI_ARRAY(&ah->iniModesTxGain,
82 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
83 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
84 5);
85
86 /* Load PCIE SERDES settings from INI */
87
88 /* Awake Setting */
89
90 INIT_INI_ARRAY(&ah->iniPcieSerdes,
91 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
92 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
93 2);
94
95 /* Sleep Setting */
96
97 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
98 ar9300PciePhy_clkreq_enable_L1_2p0,
99 ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
100 2);
101
102 /* Fast clock modal settings */
103 INIT_INI_ARRAY(&ah->iniModesAdditional,
104 ar9300Modes_fast_clock_2p0,
105 ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
106 3);
107}
108
109static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
110{
111 switch (ar9003_hw_get_tx_gain_idx(ah)) {
112 case 0:
113 default:
114 INIT_INI_ARRAY(&ah->iniModesTxGain,
115 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
116 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
117 5);
118 break;
119 case 1:
120 INIT_INI_ARRAY(&ah->iniModesTxGain,
121 ar9300Modes_high_ob_db_tx_gain_table_2p0,
122 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
123 5);
124 break;
125 case 2:
126 INIT_INI_ARRAY(&ah->iniModesTxGain,
127 ar9300Modes_low_ob_db_tx_gain_table_2p0,
128 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
129 5);
130 break;
131 }
132}
133
134static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
135{
136 switch (ar9003_hw_get_rx_gain_idx(ah)) {
137 case 0:
138 default:
139 INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
140 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
141 2);
142 break;
143 case 1:
144 INIT_INI_ARRAY(&ah->iniModesRxGain,
145 ar9300Common_wo_xlna_rx_gain_table_2p0,
146 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
147 2);
148 break;
149 }
150}
151
152/* set gain table pointers according to values read from the eeprom */
153static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
154{
155 ar9003_tx_gain_table_apply(ah);
156 ar9003_rx_gain_table_apply(ah);
157}
158
159/*
160 * Helper for ASPM support.
161 *
162 * Disable PLL when in L0s as well as receiver clock when in L1.
163 * This power saving option must be enabled through the SerDes.
164 *
165 * Programming the SerDes must go through the same 288 bit serial shift
166 * register as the other analog registers. Hence the 9 writes.
167 */
168static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
169 int restore,
170 int power_off)
171{
172 if (ah->is_pciexpress != true)
173 return;
174
175 /* Do not touch SerDes registers */
176 if (ah->config.pcie_powersave_enable == 2)
177 return;
178
179 /* Nothing to do on restore for 11N */
180 if (!restore) {
181 /* set bit 19 to allow forcing of pcie core into L1 state */
182 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
183
184 /* Several PCIe massages to ensure proper behaviour */
185 if (ah->config.pcie_waen)
186 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
187 }
188}
189
190/* Sets up the AR9003 hardware familiy callbacks */
191void ar9003_hw_attach_ops(struct ath_hw *ah)
192{
193 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
194 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
195
196 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
197 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
198 priv_ops->macversion_supported = ar9003_hw_macversion_supported;
199
200 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
201
202 ar9003_hw_attach_phy_ops(ah);
203 ar9003_hw_attach_calib_ops(ah);
204 ar9003_hw_attach_mac_ops(ah);
205}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
new file mode 100644
index 000000000000..db019dd220b7
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
@@ -0,0 +1,1784 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_9003_H
18#define INITVALS_9003_H
19
20/* AR9003 2.0 */
21
22static const u32 ar9300_2p0_radio_postamble[][5] = {
23 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
24 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
25 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
26 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
27 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
28 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
29 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
30 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
31 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
32 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
33};
34
35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
38 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
39 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
40 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
41 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
42 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
43 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
44 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
45 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
46 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
47 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
48 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
49 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
50 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
51 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
52 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
53 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
54 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
55 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
56 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
57 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
58 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
59 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
60 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
61 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
62 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
63 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
64 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
65 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
66 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
67 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
68 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
69 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
70 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
71 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
72 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
73 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
74 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
75 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
76 {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
77 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
78 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
79 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
80 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
81 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
82 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
83 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
84 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
85 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
86 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
87 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
88 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
89 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
90 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
91 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
92 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
93 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
94 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
95 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
96 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
97 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
98 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
99 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
100 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
101 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
102 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
103 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
104 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
105 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
106 {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
107 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
108 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
109 {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
110 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
111};
112
113static const u32 ar9300Modes_fast_clock_2p0[][3] = {
114 /* Addr 5G_HT20 5G_HT40 */
115 {0x00001030, 0x00000268, 0x000004d0},
116 {0x00001070, 0x0000018c, 0x00000318},
117 {0x000010b0, 0x00000fd0, 0x00001fa0},
118 {0x00008014, 0x044c044c, 0x08980898},
119 {0x0000801c, 0x148ec02b, 0x148ec057},
120 {0x00008318, 0x000044c0, 0x00008980},
121 {0x00009e00, 0x03721821, 0x03721821},
122 {0x0000a230, 0x0000000b, 0x00000016},
123 {0x0000a254, 0x00000898, 0x00001130},
124};
125
126static const u32 ar9300_2p0_radio_core[][2] = {
127 /* Addr allmodes */
128 {0x00016000, 0x36db6db6},
129 {0x00016004, 0x6db6db40},
130 {0x00016008, 0x73f00000},
131 {0x0001600c, 0x00000000},
132 {0x00016040, 0x7f80fff8},
133 {0x0001604c, 0x76d005b5},
134 {0x00016050, 0x556cf031},
135 {0x00016054, 0x13449440},
136 {0x00016058, 0x0c51c92c},
137 {0x0001605c, 0x3db7fffc},
138 {0x00016060, 0xfffffffc},
139 {0x00016064, 0x000f0278},
140 {0x0001606c, 0x6db60000},
141 {0x00016080, 0x00000000},
142 {0x00016084, 0x0e48048c},
143 {0x00016088, 0x54214514},
144 {0x0001608c, 0x119f481e},
145 {0x00016090, 0x24926490},
146 {0x00016098, 0xd2888888},
147 {0x000160a0, 0x0a108ffe},
148 {0x000160a4, 0x812fc370},
149 {0x000160a8, 0x423c8000},
150 {0x000160b4, 0x92480080},
151 {0x000160c0, 0x00adb6d0},
152 {0x000160c4, 0x6db6db60},
153 {0x000160c8, 0x6db6db6c},
154 {0x000160cc, 0x01e6c000},
155 {0x00016100, 0x3fffbe01},
156 {0x00016104, 0xfff80000},
157 {0x00016108, 0x00080010},
158 {0x00016144, 0x02084080},
159 {0x00016148, 0x00000000},
160 {0x00016280, 0x058a0001},
161 {0x00016284, 0x3d840208},
162 {0x00016288, 0x05a20408},
163 {0x0001628c, 0x00038c07},
164 {0x00016290, 0x40000004},
165 {0x00016294, 0x458aa14f},
166 {0x00016380, 0x00000000},
167 {0x00016384, 0x00000000},
168 {0x00016388, 0x00800700},
169 {0x0001638c, 0x00800700},
170 {0x00016390, 0x00800700},
171 {0x00016394, 0x00000000},
172 {0x00016398, 0x00000000},
173 {0x0001639c, 0x00000000},
174 {0x000163a0, 0x00000001},
175 {0x000163a4, 0x00000001},
176 {0x000163a8, 0x00000000},
177 {0x000163ac, 0x00000000},
178 {0x000163b0, 0x00000000},
179 {0x000163b4, 0x00000000},
180 {0x000163b8, 0x00000000},
181 {0x000163bc, 0x00000000},
182 {0x000163c0, 0x000000a0},
183 {0x000163c4, 0x000c0000},
184 {0x000163c8, 0x14021402},
185 {0x000163cc, 0x00001402},
186 {0x000163d0, 0x00000000},
187 {0x000163d4, 0x00000000},
188 {0x00016400, 0x36db6db6},
189 {0x00016404, 0x6db6db40},
190 {0x00016408, 0x73f00000},
191 {0x0001640c, 0x00000000},
192 {0x00016440, 0x7f80fff8},
193 {0x0001644c, 0x76d005b5},
194 {0x00016450, 0x556cf031},
195 {0x00016454, 0x13449440},
196 {0x00016458, 0x0c51c92c},
197 {0x0001645c, 0x3db7fffc},
198 {0x00016460, 0xfffffffc},
199 {0x00016464, 0x000f0278},
200 {0x0001646c, 0x6db60000},
201 {0x00016500, 0x3fffbe01},
202 {0x00016504, 0xfff80000},
203 {0x00016508, 0x00080010},
204 {0x00016544, 0x02084080},
205 {0x00016548, 0x00000000},
206 {0x00016780, 0x00000000},
207 {0x00016784, 0x00000000},
208 {0x00016788, 0x00800700},
209 {0x0001678c, 0x00800700},
210 {0x00016790, 0x00800700},
211 {0x00016794, 0x00000000},
212 {0x00016798, 0x00000000},
213 {0x0001679c, 0x00000000},
214 {0x000167a0, 0x00000001},
215 {0x000167a4, 0x00000001},
216 {0x000167a8, 0x00000000},
217 {0x000167ac, 0x00000000},
218 {0x000167b0, 0x00000000},
219 {0x000167b4, 0x00000000},
220 {0x000167b8, 0x00000000},
221 {0x000167bc, 0x00000000},
222 {0x000167c0, 0x000000a0},
223 {0x000167c4, 0x000c0000},
224 {0x000167c8, 0x14021402},
225 {0x000167cc, 0x00001402},
226 {0x000167d0, 0x00000000},
227 {0x000167d4, 0x00000000},
228 {0x00016800, 0x36db6db6},
229 {0x00016804, 0x6db6db40},
230 {0x00016808, 0x73f00000},
231 {0x0001680c, 0x00000000},
232 {0x00016840, 0x7f80fff8},
233 {0x0001684c, 0x76d005b5},
234 {0x00016850, 0x556cf031},
235 {0x00016854, 0x13449440},
236 {0x00016858, 0x0c51c92c},
237 {0x0001685c, 0x3db7fffc},
238 {0x00016860, 0xfffffffc},
239 {0x00016864, 0x000f0278},
240 {0x0001686c, 0x6db60000},
241 {0x00016900, 0x3fffbe01},
242 {0x00016904, 0xfff80000},
243 {0x00016908, 0x00080010},
244 {0x00016944, 0x02084080},
245 {0x00016948, 0x00000000},
246 {0x00016b80, 0x00000000},
247 {0x00016b84, 0x00000000},
248 {0x00016b88, 0x00800700},
249 {0x00016b8c, 0x00800700},
250 {0x00016b90, 0x00800700},
251 {0x00016b94, 0x00000000},
252 {0x00016b98, 0x00000000},
253 {0x00016b9c, 0x00000000},
254 {0x00016ba0, 0x00000001},
255 {0x00016ba4, 0x00000001},
256 {0x00016ba8, 0x00000000},
257 {0x00016bac, 0x00000000},
258 {0x00016bb0, 0x00000000},
259 {0x00016bb4, 0x00000000},
260 {0x00016bb8, 0x00000000},
261 {0x00016bbc, 0x00000000},
262 {0x00016bc0, 0x000000a0},
263 {0x00016bc4, 0x000c0000},
264 {0x00016bc8, 0x14021402},
265 {0x00016bcc, 0x00001402},
266 {0x00016bd0, 0x00000000},
267 {0x00016bd4, 0x00000000},
268};
269
270static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = {
271 /* Addr allmodes */
272 {0x0000a000, 0x02000101},
273 {0x0000a004, 0x02000102},
274 {0x0000a008, 0x02000103},
275 {0x0000a00c, 0x02000104},
276 {0x0000a010, 0x02000200},
277 {0x0000a014, 0x02000201},
278 {0x0000a018, 0x02000202},
279 {0x0000a01c, 0x02000203},
280 {0x0000a020, 0x02000204},
281 {0x0000a024, 0x02000205},
282 {0x0000a028, 0x02000208},
283 {0x0000a02c, 0x02000302},
284 {0x0000a030, 0x02000303},
285 {0x0000a034, 0x02000304},
286 {0x0000a038, 0x02000400},
287 {0x0000a03c, 0x02010300},
288 {0x0000a040, 0x02010301},
289 {0x0000a044, 0x02010302},
290 {0x0000a048, 0x02000500},
291 {0x0000a04c, 0x02010400},
292 {0x0000a050, 0x02020300},
293 {0x0000a054, 0x02020301},
294 {0x0000a058, 0x02020302},
295 {0x0000a05c, 0x02020303},
296 {0x0000a060, 0x02020400},
297 {0x0000a064, 0x02030300},
298 {0x0000a068, 0x02030301},
299 {0x0000a06c, 0x02030302},
300 {0x0000a070, 0x02030303},
301 {0x0000a074, 0x02030400},
302 {0x0000a078, 0x02040300},
303 {0x0000a07c, 0x02040301},
304 {0x0000a080, 0x02040302},
305 {0x0000a084, 0x02040303},
306 {0x0000a088, 0x02030500},
307 {0x0000a08c, 0x02040400},
308 {0x0000a090, 0x02050203},
309 {0x0000a094, 0x02050204},
310 {0x0000a098, 0x02050205},
311 {0x0000a09c, 0x02040500},
312 {0x0000a0a0, 0x02050301},
313 {0x0000a0a4, 0x02050302},
314 {0x0000a0a8, 0x02050303},
315 {0x0000a0ac, 0x02050400},
316 {0x0000a0b0, 0x02050401},
317 {0x0000a0b4, 0x02050402},
318 {0x0000a0b8, 0x02050403},
319 {0x0000a0bc, 0x02050500},
320 {0x0000a0c0, 0x02050501},
321 {0x0000a0c4, 0x02050502},
322 {0x0000a0c8, 0x02050503},
323 {0x0000a0cc, 0x02050504},
324 {0x0000a0d0, 0x02050600},
325 {0x0000a0d4, 0x02050601},
326 {0x0000a0d8, 0x02050602},
327 {0x0000a0dc, 0x02050603},
328 {0x0000a0e0, 0x02050604},
329 {0x0000a0e4, 0x02050700},
330 {0x0000a0e8, 0x02050701},
331 {0x0000a0ec, 0x02050702},
332 {0x0000a0f0, 0x02050703},
333 {0x0000a0f4, 0x02050704},
334 {0x0000a0f8, 0x02050705},
335 {0x0000a0fc, 0x02050708},
336 {0x0000a100, 0x02050709},
337 {0x0000a104, 0x0205070a},
338 {0x0000a108, 0x0205070b},
339 {0x0000a10c, 0x0205070c},
340 {0x0000a110, 0x0205070d},
341 {0x0000a114, 0x02050710},
342 {0x0000a118, 0x02050711},
343 {0x0000a11c, 0x02050712},
344 {0x0000a120, 0x02050713},
345 {0x0000a124, 0x02050714},
346 {0x0000a128, 0x02050715},
347 {0x0000a12c, 0x02050730},
348 {0x0000a130, 0x02050731},
349 {0x0000a134, 0x02050732},
350 {0x0000a138, 0x02050733},
351 {0x0000a13c, 0x02050734},
352 {0x0000a140, 0x02050735},
353 {0x0000a144, 0x02050750},
354 {0x0000a148, 0x02050751},
355 {0x0000a14c, 0x02050752},
356 {0x0000a150, 0x02050753},
357 {0x0000a154, 0x02050754},
358 {0x0000a158, 0x02050755},
359 {0x0000a15c, 0x02050770},
360 {0x0000a160, 0x02050771},
361 {0x0000a164, 0x02050772},
362 {0x0000a168, 0x02050773},
363 {0x0000a16c, 0x02050774},
364 {0x0000a170, 0x02050775},
365 {0x0000a174, 0x00000776},
366 {0x0000a178, 0x00000776},
367 {0x0000a17c, 0x00000776},
368 {0x0000a180, 0x00000776},
369 {0x0000a184, 0x00000776},
370 {0x0000a188, 0x00000776},
371 {0x0000a18c, 0x00000776},
372 {0x0000a190, 0x00000776},
373 {0x0000a194, 0x00000776},
374 {0x0000a198, 0x00000776},
375 {0x0000a19c, 0x00000776},
376 {0x0000a1a0, 0x00000776},
377 {0x0000a1a4, 0x00000776},
378 {0x0000a1a8, 0x00000776},
379 {0x0000a1ac, 0x00000776},
380 {0x0000a1b0, 0x00000776},
381 {0x0000a1b4, 0x00000776},
382 {0x0000a1b8, 0x00000776},
383 {0x0000a1bc, 0x00000776},
384 {0x0000a1c0, 0x00000776},
385 {0x0000a1c4, 0x00000776},
386 {0x0000a1c8, 0x00000776},
387 {0x0000a1cc, 0x00000776},
388 {0x0000a1d0, 0x00000776},
389 {0x0000a1d4, 0x00000776},
390 {0x0000a1d8, 0x00000776},
391 {0x0000a1dc, 0x00000776},
392 {0x0000a1e0, 0x00000776},
393 {0x0000a1e4, 0x00000776},
394 {0x0000a1e8, 0x00000776},
395 {0x0000a1ec, 0x00000776},
396 {0x0000a1f0, 0x00000776},
397 {0x0000a1f4, 0x00000776},
398 {0x0000a1f8, 0x00000776},
399 {0x0000a1fc, 0x00000776},
400 {0x0000b000, 0x02000101},
401 {0x0000b004, 0x02000102},
402 {0x0000b008, 0x02000103},
403 {0x0000b00c, 0x02000104},
404 {0x0000b010, 0x02000200},
405 {0x0000b014, 0x02000201},
406 {0x0000b018, 0x02000202},
407 {0x0000b01c, 0x02000203},
408 {0x0000b020, 0x02000204},
409 {0x0000b024, 0x02000205},
410 {0x0000b028, 0x02000208},
411 {0x0000b02c, 0x02000302},
412 {0x0000b030, 0x02000303},
413 {0x0000b034, 0x02000304},
414 {0x0000b038, 0x02000400},
415 {0x0000b03c, 0x02010300},
416 {0x0000b040, 0x02010301},
417 {0x0000b044, 0x02010302},
418 {0x0000b048, 0x02000500},
419 {0x0000b04c, 0x02010400},
420 {0x0000b050, 0x02020300},
421 {0x0000b054, 0x02020301},
422 {0x0000b058, 0x02020302},
423 {0x0000b05c, 0x02020303},
424 {0x0000b060, 0x02020400},
425 {0x0000b064, 0x02030300},
426 {0x0000b068, 0x02030301},
427 {0x0000b06c, 0x02030302},
428 {0x0000b070, 0x02030303},
429 {0x0000b074, 0x02030400},
430 {0x0000b078, 0x02040300},
431 {0x0000b07c, 0x02040301},
432 {0x0000b080, 0x02040302},
433 {0x0000b084, 0x02040303},
434 {0x0000b088, 0x02030500},
435 {0x0000b08c, 0x02040400},
436 {0x0000b090, 0x02050203},
437 {0x0000b094, 0x02050204},
438 {0x0000b098, 0x02050205},
439 {0x0000b09c, 0x02040500},
440 {0x0000b0a0, 0x02050301},
441 {0x0000b0a4, 0x02050302},
442 {0x0000b0a8, 0x02050303},
443 {0x0000b0ac, 0x02050400},
444 {0x0000b0b0, 0x02050401},
445 {0x0000b0b4, 0x02050402},
446 {0x0000b0b8, 0x02050403},
447 {0x0000b0bc, 0x02050500},
448 {0x0000b0c0, 0x02050501},
449 {0x0000b0c4, 0x02050502},
450 {0x0000b0c8, 0x02050503},
451 {0x0000b0cc, 0x02050504},
452 {0x0000b0d0, 0x02050600},
453 {0x0000b0d4, 0x02050601},
454 {0x0000b0d8, 0x02050602},
455 {0x0000b0dc, 0x02050603},
456 {0x0000b0e0, 0x02050604},
457 {0x0000b0e4, 0x02050700},
458 {0x0000b0e8, 0x02050701},
459 {0x0000b0ec, 0x02050702},
460 {0x0000b0f0, 0x02050703},
461 {0x0000b0f4, 0x02050704},
462 {0x0000b0f8, 0x02050705},
463 {0x0000b0fc, 0x02050708},
464 {0x0000b100, 0x02050709},
465 {0x0000b104, 0x0205070a},
466 {0x0000b108, 0x0205070b},
467 {0x0000b10c, 0x0205070c},
468 {0x0000b110, 0x0205070d},
469 {0x0000b114, 0x02050710},
470 {0x0000b118, 0x02050711},
471 {0x0000b11c, 0x02050712},
472 {0x0000b120, 0x02050713},
473 {0x0000b124, 0x02050714},
474 {0x0000b128, 0x02050715},
475 {0x0000b12c, 0x02050730},
476 {0x0000b130, 0x02050731},
477 {0x0000b134, 0x02050732},
478 {0x0000b138, 0x02050733},
479 {0x0000b13c, 0x02050734},
480 {0x0000b140, 0x02050735},
481 {0x0000b144, 0x02050750},
482 {0x0000b148, 0x02050751},
483 {0x0000b14c, 0x02050752},
484 {0x0000b150, 0x02050753},
485 {0x0000b154, 0x02050754},
486 {0x0000b158, 0x02050755},
487 {0x0000b15c, 0x02050770},
488 {0x0000b160, 0x02050771},
489 {0x0000b164, 0x02050772},
490 {0x0000b168, 0x02050773},
491 {0x0000b16c, 0x02050774},
492 {0x0000b170, 0x02050775},
493 {0x0000b174, 0x00000776},
494 {0x0000b178, 0x00000776},
495 {0x0000b17c, 0x00000776},
496 {0x0000b180, 0x00000776},
497 {0x0000b184, 0x00000776},
498 {0x0000b188, 0x00000776},
499 {0x0000b18c, 0x00000776},
500 {0x0000b190, 0x00000776},
501 {0x0000b194, 0x00000776},
502 {0x0000b198, 0x00000776},
503 {0x0000b19c, 0x00000776},
504 {0x0000b1a0, 0x00000776},
505 {0x0000b1a4, 0x00000776},
506 {0x0000b1a8, 0x00000776},
507 {0x0000b1ac, 0x00000776},
508 {0x0000b1b0, 0x00000776},
509 {0x0000b1b4, 0x00000776},
510 {0x0000b1b8, 0x00000776},
511 {0x0000b1bc, 0x00000776},
512 {0x0000b1c0, 0x00000776},
513 {0x0000b1c4, 0x00000776},
514 {0x0000b1c8, 0x00000776},
515 {0x0000b1cc, 0x00000776},
516 {0x0000b1d0, 0x00000776},
517 {0x0000b1d4, 0x00000776},
518 {0x0000b1d8, 0x00000776},
519 {0x0000b1dc, 0x00000776},
520 {0x0000b1e0, 0x00000776},
521 {0x0000b1e4, 0x00000776},
522 {0x0000b1e8, 0x00000776},
523 {0x0000b1ec, 0x00000776},
524 {0x0000b1f0, 0x00000776},
525 {0x0000b1f4, 0x00000776},
526 {0x0000b1f8, 0x00000776},
527 {0x0000b1fc, 0x00000776},
528};
529
530static const u32 ar9300_2p0_mac_postamble[][5] = {
531 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
532 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
533 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
534 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
535 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
536 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
537 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
538 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
539 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
540};
541
542static const u32 ar9300_2p0_soc_postamble[][5] = {
543 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
544 {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
545};
546
547static const u32 ar9200_merlin_2p0_radio_core[][2] = {
548 /* Addr allmodes */
549 {0x00007800, 0x00040000},
550 {0x00007804, 0xdb005012},
551 {0x00007808, 0x04924914},
552 {0x0000780c, 0x21084210},
553 {0x00007810, 0x6d801300},
554 {0x00007814, 0x0019beff},
555 {0x00007818, 0x07e41000},
556 {0x0000781c, 0x00392000},
557 {0x00007820, 0x92592480},
558 {0x00007824, 0x00040000},
559 {0x00007828, 0xdb005012},
560 {0x0000782c, 0x04924914},
561 {0x00007830, 0x21084210},
562 {0x00007834, 0x6d801300},
563 {0x00007838, 0x0019beff},
564 {0x0000783c, 0x07e40000},
565 {0x00007840, 0x00392000},
566 {0x00007844, 0x92592480},
567 {0x00007848, 0x00100000},
568 {0x0000784c, 0x773f0567},
569 {0x00007850, 0x54214514},
570 {0x00007854, 0x12035828},
571 {0x00007858, 0x92592692},
572 {0x0000785c, 0x00000000},
573 {0x00007860, 0x56400000},
574 {0x00007864, 0x0a8e370e},
575 {0x00007868, 0xc0102850},
576 {0x0000786c, 0x812d4000},
577 {0x00007870, 0x807ec400},
578 {0x00007874, 0x001b6db0},
579 {0x00007878, 0x00376b63},
580 {0x0000787c, 0x06db6db6},
581 {0x00007880, 0x006d8000},
582 {0x00007884, 0xffeffffe},
583 {0x00007888, 0xffeffffe},
584 {0x0000788c, 0x00010000},
585 {0x00007890, 0x02060aeb},
586 {0x00007894, 0x5a108000},
587};
588
589static const u32 ar9300_2p0_baseband_postamble[][5] = {
590 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
591 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
592 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
593 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
594 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
595 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
596 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
597 {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
598 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
599 {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
600 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
601 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
602 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
603 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
604 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
605 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
606 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
607 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
608 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
609 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
610 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
611 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
612 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
613 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
614 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
615 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
616 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
617 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
618 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
619 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
620 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
621 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
622 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
623 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
624 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
625 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
626 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
627 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
628 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
629 {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
630 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
631 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
632 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
633 {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
634 {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
635 {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
636 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
637 {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
638 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
639 {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
640};
641
642static const u32 ar9300_2p0_baseband_core[][2] = {
643 /* Addr allmodes */
644 {0x00009800, 0xafe68e30},
645 {0x00009804, 0xfd14e000},
646 {0x00009808, 0x9c0a9f6b},
647 {0x0000980c, 0x04900000},
648 {0x00009814, 0x9280c00a},
649 {0x00009818, 0x00000000},
650 {0x0000981c, 0x00020028},
651 {0x00009834, 0x5f3ca3de},
652 {0x00009838, 0x0108ecff},
653 {0x0000983c, 0x14750600},
654 {0x00009880, 0x201fff00},
655 {0x00009884, 0x00001042},
656 {0x000098a4, 0x00200400},
657 {0x000098b0, 0x52440bbe},
658 {0x000098d0, 0x004b6a8e},
659 {0x000098d4, 0x00000820},
660 {0x000098dc, 0x00000000},
661 {0x000098f0, 0x00000000},
662 {0x000098f4, 0x00000000},
663 {0x00009c04, 0xff55ff55},
664 {0x00009c08, 0x0320ff55},
665 {0x00009c0c, 0x00000000},
666 {0x00009c10, 0x00000000},
667 {0x00009c14, 0x00046384},
668 {0x00009c18, 0x05b6b440},
669 {0x00009c1c, 0x00b6b440},
670 {0x00009d00, 0xc080a333},
671 {0x00009d04, 0x40206c10},
672 {0x00009d08, 0x009c4060},
673 {0x00009d0c, 0x9883800a},
674 {0x00009d10, 0x01834061},
675 {0x00009d14, 0x00c0040b},
676 {0x00009d18, 0x00000000},
677 {0x00009e08, 0x0038230c},
678 {0x00009e24, 0x990bb515},
679 {0x00009e28, 0x0c6f0000},
680 {0x00009e30, 0x06336f77},
681 {0x00009e34, 0x6af6532f},
682 {0x00009e38, 0x0cc80c00},
683 {0x00009e3c, 0xcf946222},
684 {0x00009e40, 0x0d261820},
685 {0x00009e4c, 0x00001004},
686 {0x00009e50, 0x00ff03f1},
687 {0x00009e54, 0x00000000},
688 {0x00009fc0, 0x803e4788},
689 {0x00009fc4, 0x0001efb5},
690 {0x00009fcc, 0x40000014},
691 {0x00009fd0, 0x01193b93},
692 {0x0000a20c, 0x00000000},
693 {0x0000a220, 0x00000000},
694 {0x0000a224, 0x00000000},
695 {0x0000a228, 0x10002310},
696 {0x0000a22c, 0x01036a1e},
697 {0x0000a234, 0x10000fff},
698 {0x0000a23c, 0x00000000},
699 {0x0000a244, 0x0c000000},
700 {0x0000a2a0, 0x00000001},
701 {0x0000a2c0, 0x00000001},
702 {0x0000a2c8, 0x00000000},
703 {0x0000a2cc, 0x18c43433},
704 {0x0000a2d4, 0x00000000},
705 {0x0000a2dc, 0x00000000},
706 {0x0000a2e0, 0x00000000},
707 {0x0000a2e4, 0x00000000},
708 {0x0000a2e8, 0x00000000},
709 {0x0000a2ec, 0x00000000},
710 {0x0000a2f0, 0x00000000},
711 {0x0000a2f4, 0x00000000},
712 {0x0000a2f8, 0x00000000},
713 {0x0000a344, 0x00000000},
714 {0x0000a34c, 0x00000000},
715 {0x0000a350, 0x0000a000},
716 {0x0000a364, 0x00000000},
717 {0x0000a370, 0x00000000},
718 {0x0000a390, 0x00000001},
719 {0x0000a394, 0x00000444},
720 {0x0000a398, 0x001f0e0f},
721 {0x0000a39c, 0x0075393f},
722 {0x0000a3a0, 0xb79f6427},
723 {0x0000a3a4, 0x00000000},
724 {0x0000a3a8, 0xaaaaaaaa},
725 {0x0000a3ac, 0x3c466478},
726 {0x0000a3c0, 0x20202020},
727 {0x0000a3c4, 0x22222220},
728 {0x0000a3c8, 0x20200020},
729 {0x0000a3cc, 0x20202020},
730 {0x0000a3d0, 0x20202020},
731 {0x0000a3d4, 0x20202020},
732 {0x0000a3d8, 0x20202020},
733 {0x0000a3dc, 0x20202020},
734 {0x0000a3e0, 0x20202020},
735 {0x0000a3e4, 0x20202020},
736 {0x0000a3e8, 0x20202020},
737 {0x0000a3ec, 0x20202020},
738 {0x0000a3f0, 0x00000000},
739 {0x0000a3f4, 0x00000246},
740 {0x0000a3f8, 0x0cdbd380},
741 {0x0000a3fc, 0x000f0f01},
742 {0x0000a400, 0x8fa91f01},
743 {0x0000a404, 0x00000000},
744 {0x0000a408, 0x0e79e5c6},
745 {0x0000a40c, 0x00820820},
746 {0x0000a414, 0x1ce739ce},
747 {0x0000a418, 0x2d001dce},
748 {0x0000a41c, 0x1ce739ce},
749 {0x0000a420, 0x000001ce},
750 {0x0000a424, 0x1ce739ce},
751 {0x0000a428, 0x000001ce},
752 {0x0000a42c, 0x1ce739ce},
753 {0x0000a430, 0x1ce739ce},
754 {0x0000a434, 0x00000000},
755 {0x0000a438, 0x00001801},
756 {0x0000a43c, 0x00000000},
757 {0x0000a440, 0x00000000},
758 {0x0000a444, 0x00000000},
759 {0x0000a448, 0x04000080},
760 {0x0000a44c, 0x00000001},
761 {0x0000a450, 0x00010000},
762 {0x0000a458, 0x00000000},
763 {0x0000a600, 0x00000000},
764 {0x0000a604, 0x00000000},
765 {0x0000a608, 0x00000000},
766 {0x0000a60c, 0x00000000},
767 {0x0000a610, 0x00000000},
768 {0x0000a614, 0x00000000},
769 {0x0000a618, 0x00000000},
770 {0x0000a61c, 0x00000000},
771 {0x0000a620, 0x00000000},
772 {0x0000a624, 0x00000000},
773 {0x0000a628, 0x00000000},
774 {0x0000a62c, 0x00000000},
775 {0x0000a630, 0x00000000},
776 {0x0000a634, 0x00000000},
777 {0x0000a638, 0x00000000},
778 {0x0000a63c, 0x00000000},
779 {0x0000a640, 0x00000000},
780 {0x0000a644, 0x3fad9d74},
781 {0x0000a648, 0x0048060a},
782 {0x0000a64c, 0x00000637},
783 {0x0000a670, 0x03020100},
784 {0x0000a674, 0x09080504},
785 {0x0000a678, 0x0d0c0b0a},
786 {0x0000a67c, 0x13121110},
787 {0x0000a680, 0x31301514},
788 {0x0000a684, 0x35343332},
789 {0x0000a688, 0x00000036},
790 {0x0000a690, 0x00000838},
791 {0x0000a7c0, 0x00000000},
792 {0x0000a7c4, 0xfffffffc},
793 {0x0000a7c8, 0x00000000},
794 {0x0000a7cc, 0x00000000},
795 {0x0000a7d0, 0x00000000},
796 {0x0000a7d4, 0x00000004},
797 {0x0000a7dc, 0x00000001},
798 {0x0000a8d0, 0x004b6a8e},
799 {0x0000a8d4, 0x00000820},
800 {0x0000a8dc, 0x00000000},
801 {0x0000a8f0, 0x00000000},
802 {0x0000a8f4, 0x00000000},
803 {0x0000b2d0, 0x00000080},
804 {0x0000b2d4, 0x00000000},
805 {0x0000b2dc, 0x00000000},
806 {0x0000b2e0, 0x00000000},
807 {0x0000b2e4, 0x00000000},
808 {0x0000b2e8, 0x00000000},
809 {0x0000b2ec, 0x00000000},
810 {0x0000b2f0, 0x00000000},
811 {0x0000b2f4, 0x00000000},
812 {0x0000b2f8, 0x00000000},
813 {0x0000b408, 0x0e79e5c0},
814 {0x0000b40c, 0x00820820},
815 {0x0000b420, 0x00000000},
816 {0x0000b8d0, 0x004b6a8e},
817 {0x0000b8d4, 0x00000820},
818 {0x0000b8dc, 0x00000000},
819 {0x0000b8f0, 0x00000000},
820 {0x0000b8f4, 0x00000000},
821 {0x0000c2d0, 0x00000080},
822 {0x0000c2d4, 0x00000000},
823 {0x0000c2dc, 0x00000000},
824 {0x0000c2e0, 0x00000000},
825 {0x0000c2e4, 0x00000000},
826 {0x0000c2e8, 0x00000000},
827 {0x0000c2ec, 0x00000000},
828 {0x0000c2f0, 0x00000000},
829 {0x0000c2f4, 0x00000000},
830 {0x0000c2f8, 0x00000000},
831 {0x0000c408, 0x0e79e5c0},
832 {0x0000c40c, 0x00820820},
833 {0x0000c420, 0x00000000},
834};
835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
839 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
840 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
841 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
842 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
843 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
844 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
845 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
846 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
847 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
848 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
849 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
850 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
851 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
852 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
853 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
854 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
855 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
856 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
857 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
858 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
859 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84},
860 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
861 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
862 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
863 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
864 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
865 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
866 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
867 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
868 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
869 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
870 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
871 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
872 {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002},
873 {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004},
874 {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200},
875 {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202},
876 {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400},
877 {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402},
878 {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404},
879 {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603},
880 {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02},
881 {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04},
882 {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20},
883 {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20},
884 {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22},
885 {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24},
886 {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640},
887 {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660},
888 {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861},
889 {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81},
890 {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83},
891 {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84},
892 {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3},
893 {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5},
894 {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9},
895 {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb},
896 {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
897 {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
898 {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
899 {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
900 {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
901 {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
902 {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
903 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
904 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
905 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
906 {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
907 {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
908 {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
909 {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
910 {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
911 {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
912};
913
914static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
915 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
916 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
917 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
918 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
919 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
920 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
921 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
922 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
923 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
924 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
925 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
926 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
927 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
928 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
929 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
930 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
931 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
932 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
933 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
934 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
935 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81},
936 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
937 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84},
938 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
939 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
940 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
941 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
942 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
943 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
944 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
945 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
946 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
947 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
948 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec},
949 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
950 {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002},
951 {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004},
952 {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200},
953 {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202},
954 {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400},
955 {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402},
956 {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404},
957 {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603},
958 {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02},
959 {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04},
960 {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20},
961 {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20},
962 {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22},
963 {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24},
964 {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640},
965 {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660},
966 {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861},
967 {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81},
968 {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83},
969 {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84},
970 {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3},
971 {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5},
972 {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9},
973 {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb},
974 {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
975 {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
976 {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
977 {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
978 {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
979 {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
980 {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
981 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
982 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
983 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
984 {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
985 {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
986 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
987 {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
988 {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
989 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
990};
991
992static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
993 /* Addr allmodes */
994 {0x0000a000, 0x00010000},
995 {0x0000a004, 0x00030002},
996 {0x0000a008, 0x00050004},
997 {0x0000a00c, 0x00810080},
998 {0x0000a010, 0x00830082},
999 {0x0000a014, 0x01810180},
1000 {0x0000a018, 0x01830182},
1001 {0x0000a01c, 0x01850184},
1002 {0x0000a020, 0x01890188},
1003 {0x0000a024, 0x018b018a},
1004 {0x0000a028, 0x018d018c},
1005 {0x0000a02c, 0x01910190},
1006 {0x0000a030, 0x01930192},
1007 {0x0000a034, 0x01950194},
1008 {0x0000a038, 0x038a0196},
1009 {0x0000a03c, 0x038c038b},
1010 {0x0000a040, 0x0390038d},
1011 {0x0000a044, 0x03920391},
1012 {0x0000a048, 0x03940393},
1013 {0x0000a04c, 0x03960395},
1014 {0x0000a050, 0x00000000},
1015 {0x0000a054, 0x00000000},
1016 {0x0000a058, 0x00000000},
1017 {0x0000a05c, 0x00000000},
1018 {0x0000a060, 0x00000000},
1019 {0x0000a064, 0x00000000},
1020 {0x0000a068, 0x00000000},
1021 {0x0000a06c, 0x00000000},
1022 {0x0000a070, 0x00000000},
1023 {0x0000a074, 0x00000000},
1024 {0x0000a078, 0x00000000},
1025 {0x0000a07c, 0x00000000},
1026 {0x0000a080, 0x22222229},
1027 {0x0000a084, 0x1d1d1d1d},
1028 {0x0000a088, 0x1d1d1d1d},
1029 {0x0000a08c, 0x1d1d1d1d},
1030 {0x0000a090, 0x171d1d1d},
1031 {0x0000a094, 0x11111717},
1032 {0x0000a098, 0x00030311},
1033 {0x0000a09c, 0x00000000},
1034 {0x0000a0a0, 0x00000000},
1035 {0x0000a0a4, 0x00000000},
1036 {0x0000a0a8, 0x00000000},
1037 {0x0000a0ac, 0x00000000},
1038 {0x0000a0b0, 0x00000000},
1039 {0x0000a0b4, 0x00000000},
1040 {0x0000a0b8, 0x00000000},
1041 {0x0000a0bc, 0x00000000},
1042 {0x0000a0c0, 0x001f0000},
1043 {0x0000a0c4, 0x01000101},
1044 {0x0000a0c8, 0x011e011f},
1045 {0x0000a0cc, 0x011c011d},
1046 {0x0000a0d0, 0x02030204},
1047 {0x0000a0d4, 0x02010202},
1048 {0x0000a0d8, 0x021f0200},
1049 {0x0000a0dc, 0x0302021e},
1050 {0x0000a0e0, 0x03000301},
1051 {0x0000a0e4, 0x031e031f},
1052 {0x0000a0e8, 0x0402031d},
1053 {0x0000a0ec, 0x04000401},
1054 {0x0000a0f0, 0x041e041f},
1055 {0x0000a0f4, 0x0502041d},
1056 {0x0000a0f8, 0x05000501},
1057 {0x0000a0fc, 0x051e051f},
1058 {0x0000a100, 0x06010602},
1059 {0x0000a104, 0x061f0600},
1060 {0x0000a108, 0x061d061e},
1061 {0x0000a10c, 0x07020703},
1062 {0x0000a110, 0x07000701},
1063 {0x0000a114, 0x00000000},
1064 {0x0000a118, 0x00000000},
1065 {0x0000a11c, 0x00000000},
1066 {0x0000a120, 0x00000000},
1067 {0x0000a124, 0x00000000},
1068 {0x0000a128, 0x00000000},
1069 {0x0000a12c, 0x00000000},
1070 {0x0000a130, 0x00000000},
1071 {0x0000a134, 0x00000000},
1072 {0x0000a138, 0x00000000},
1073 {0x0000a13c, 0x00000000},
1074 {0x0000a140, 0x001f0000},
1075 {0x0000a144, 0x01000101},
1076 {0x0000a148, 0x011e011f},
1077 {0x0000a14c, 0x011c011d},
1078 {0x0000a150, 0x02030204},
1079 {0x0000a154, 0x02010202},
1080 {0x0000a158, 0x021f0200},
1081 {0x0000a15c, 0x0302021e},
1082 {0x0000a160, 0x03000301},
1083 {0x0000a164, 0x031e031f},
1084 {0x0000a168, 0x0402031d},
1085 {0x0000a16c, 0x04000401},
1086 {0x0000a170, 0x041e041f},
1087 {0x0000a174, 0x0502041d},
1088 {0x0000a178, 0x05000501},
1089 {0x0000a17c, 0x051e051f},
1090 {0x0000a180, 0x06010602},
1091 {0x0000a184, 0x061f0600},
1092 {0x0000a188, 0x061d061e},
1093 {0x0000a18c, 0x07020703},
1094 {0x0000a190, 0x07000701},
1095 {0x0000a194, 0x00000000},
1096 {0x0000a198, 0x00000000},
1097 {0x0000a19c, 0x00000000},
1098 {0x0000a1a0, 0x00000000},
1099 {0x0000a1a4, 0x00000000},
1100 {0x0000a1a8, 0x00000000},
1101 {0x0000a1ac, 0x00000000},
1102 {0x0000a1b0, 0x00000000},
1103 {0x0000a1b4, 0x00000000},
1104 {0x0000a1b8, 0x00000000},
1105 {0x0000a1bc, 0x00000000},
1106 {0x0000a1c0, 0x00000000},
1107 {0x0000a1c4, 0x00000000},
1108 {0x0000a1c8, 0x00000000},
1109 {0x0000a1cc, 0x00000000},
1110 {0x0000a1d0, 0x00000000},
1111 {0x0000a1d4, 0x00000000},
1112 {0x0000a1d8, 0x00000000},
1113 {0x0000a1dc, 0x00000000},
1114 {0x0000a1e0, 0x00000000},
1115 {0x0000a1e4, 0x00000000},
1116 {0x0000a1e8, 0x00000000},
1117 {0x0000a1ec, 0x00000000},
1118 {0x0000a1f0, 0x00000396},
1119 {0x0000a1f4, 0x00000396},
1120 {0x0000a1f8, 0x00000396},
1121 {0x0000a1fc, 0x00000196},
1122 {0x0000b000, 0x00010000},
1123 {0x0000b004, 0x00030002},
1124 {0x0000b008, 0x00050004},
1125 {0x0000b00c, 0x00810080},
1126 {0x0000b010, 0x00830082},
1127 {0x0000b014, 0x01810180},
1128 {0x0000b018, 0x01830182},
1129 {0x0000b01c, 0x01850184},
1130 {0x0000b020, 0x02810280},
1131 {0x0000b024, 0x02830282},
1132 {0x0000b028, 0x02850284},
1133 {0x0000b02c, 0x02890288},
1134 {0x0000b030, 0x028b028a},
1135 {0x0000b034, 0x0388028c},
1136 {0x0000b038, 0x038a0389},
1137 {0x0000b03c, 0x038c038b},
1138 {0x0000b040, 0x0390038d},
1139 {0x0000b044, 0x03920391},
1140 {0x0000b048, 0x03940393},
1141 {0x0000b04c, 0x03960395},
1142 {0x0000b050, 0x00000000},
1143 {0x0000b054, 0x00000000},
1144 {0x0000b058, 0x00000000},
1145 {0x0000b05c, 0x00000000},
1146 {0x0000b060, 0x00000000},
1147 {0x0000b064, 0x00000000},
1148 {0x0000b068, 0x00000000},
1149 {0x0000b06c, 0x00000000},
1150 {0x0000b070, 0x00000000},
1151 {0x0000b074, 0x00000000},
1152 {0x0000b078, 0x00000000},
1153 {0x0000b07c, 0x00000000},
1154 {0x0000b080, 0x32323232},
1155 {0x0000b084, 0x2f2f3232},
1156 {0x0000b088, 0x23282a2d},
1157 {0x0000b08c, 0x1c1e2123},
1158 {0x0000b090, 0x14171919},
1159 {0x0000b094, 0x0e0e1214},
1160 {0x0000b098, 0x03050707},
1161 {0x0000b09c, 0x00030303},
1162 {0x0000b0a0, 0x00000000},
1163 {0x0000b0a4, 0x00000000},
1164 {0x0000b0a8, 0x00000000},
1165 {0x0000b0ac, 0x00000000},
1166 {0x0000b0b0, 0x00000000},
1167 {0x0000b0b4, 0x00000000},
1168 {0x0000b0b8, 0x00000000},
1169 {0x0000b0bc, 0x00000000},
1170 {0x0000b0c0, 0x003f0020},
1171 {0x0000b0c4, 0x00400041},
1172 {0x0000b0c8, 0x0140005f},
1173 {0x0000b0cc, 0x0160015f},
1174 {0x0000b0d0, 0x017e017f},
1175 {0x0000b0d4, 0x02410242},
1176 {0x0000b0d8, 0x025f0240},
1177 {0x0000b0dc, 0x027f0260},
1178 {0x0000b0e0, 0x0341027e},
1179 {0x0000b0e4, 0x035f0340},
1180 {0x0000b0e8, 0x037f0360},
1181 {0x0000b0ec, 0x04400441},
1182 {0x0000b0f0, 0x0460045f},
1183 {0x0000b0f4, 0x0541047f},
1184 {0x0000b0f8, 0x055f0540},
1185 {0x0000b0fc, 0x057f0560},
1186 {0x0000b100, 0x06400641},
1187 {0x0000b104, 0x0660065f},
1188 {0x0000b108, 0x067e067f},
1189 {0x0000b10c, 0x07410742},
1190 {0x0000b110, 0x075f0740},
1191 {0x0000b114, 0x077f0760},
1192 {0x0000b118, 0x07800781},
1193 {0x0000b11c, 0x07a0079f},
1194 {0x0000b120, 0x07c107bf},
1195 {0x0000b124, 0x000007c0},
1196 {0x0000b128, 0x00000000},
1197 {0x0000b12c, 0x00000000},
1198 {0x0000b130, 0x00000000},
1199 {0x0000b134, 0x00000000},
1200 {0x0000b138, 0x00000000},
1201 {0x0000b13c, 0x00000000},
1202 {0x0000b140, 0x003f0020},
1203 {0x0000b144, 0x00400041},
1204 {0x0000b148, 0x0140005f},
1205 {0x0000b14c, 0x0160015f},
1206 {0x0000b150, 0x017e017f},
1207 {0x0000b154, 0x02410242},
1208 {0x0000b158, 0x025f0240},
1209 {0x0000b15c, 0x027f0260},
1210 {0x0000b160, 0x0341027e},
1211 {0x0000b164, 0x035f0340},
1212 {0x0000b168, 0x037f0360},
1213 {0x0000b16c, 0x04400441},
1214 {0x0000b170, 0x0460045f},
1215 {0x0000b174, 0x0541047f},
1216 {0x0000b178, 0x055f0540},
1217 {0x0000b17c, 0x057f0560},
1218 {0x0000b180, 0x06400641},
1219 {0x0000b184, 0x0660065f},
1220 {0x0000b188, 0x067e067f},
1221 {0x0000b18c, 0x07410742},
1222 {0x0000b190, 0x075f0740},
1223 {0x0000b194, 0x077f0760},
1224 {0x0000b198, 0x07800781},
1225 {0x0000b19c, 0x07a0079f},
1226 {0x0000b1a0, 0x07c107bf},
1227 {0x0000b1a4, 0x000007c0},
1228 {0x0000b1a8, 0x00000000},
1229 {0x0000b1ac, 0x00000000},
1230 {0x0000b1b0, 0x00000000},
1231 {0x0000b1b4, 0x00000000},
1232 {0x0000b1b8, 0x00000000},
1233 {0x0000b1bc, 0x00000000},
1234 {0x0000b1c0, 0x00000000},
1235 {0x0000b1c4, 0x00000000},
1236 {0x0000b1c8, 0x00000000},
1237 {0x0000b1cc, 0x00000000},
1238 {0x0000b1d0, 0x00000000},
1239 {0x0000b1d4, 0x00000000},
1240 {0x0000b1d8, 0x00000000},
1241 {0x0000b1dc, 0x00000000},
1242 {0x0000b1e0, 0x00000000},
1243 {0x0000b1e4, 0x00000000},
1244 {0x0000b1e8, 0x00000000},
1245 {0x0000b1ec, 0x00000000},
1246 {0x0000b1f0, 0x00000396},
1247 {0x0000b1f4, 0x00000396},
1248 {0x0000b1f8, 0x00000396},
1249 {0x0000b1fc, 0x00000196},
1250};
1251
1252static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
1253 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1254 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1255 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1256 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1257 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1258 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1259 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1260 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1261 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1262 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1263 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1264 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1265 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1266 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1267 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1268 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1269 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1270 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1271 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1272 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1273 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1274 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1275 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1276 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1277 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1278 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1279 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1280 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1281 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1282 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1283 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1284 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1285 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1286 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1287 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1288 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1289 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
1290 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
1291 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
1292 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
1293 {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
1294 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
1295 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
1296 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
1297 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
1298 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
1299 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
1300 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
1301 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
1302 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
1303 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
1304 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
1305 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
1306 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
1307 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
1308 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
1309 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
1310 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
1311 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
1312 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1313 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1314 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1315 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1316 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1317 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1318 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
1319 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1320 {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1321 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1322 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1323 {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1324 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1325 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1326 {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
1327 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1328};
1329
1330static const u32 ar9300_2p0_mac_core[][2] = {
1331 /* Addr allmodes */
1332 {0x00000008, 0x00000000},
1333 {0x00000030, 0x00020085},
1334 {0x00000034, 0x00000005},
1335 {0x00000040, 0x00000000},
1336 {0x00000044, 0x00000000},
1337 {0x00000048, 0x00000008},
1338 {0x0000004c, 0x00000010},
1339 {0x00000050, 0x00000000},
1340 {0x00001040, 0x002ffc0f},
1341 {0x00001044, 0x002ffc0f},
1342 {0x00001048, 0x002ffc0f},
1343 {0x0000104c, 0x002ffc0f},
1344 {0x00001050, 0x002ffc0f},
1345 {0x00001054, 0x002ffc0f},
1346 {0x00001058, 0x002ffc0f},
1347 {0x0000105c, 0x002ffc0f},
1348 {0x00001060, 0x002ffc0f},
1349 {0x00001064, 0x002ffc0f},
1350 {0x000010f0, 0x00000100},
1351 {0x00001270, 0x00000000},
1352 {0x000012b0, 0x00000000},
1353 {0x000012f0, 0x00000000},
1354 {0x0000143c, 0x00000000},
1355 {0x0000147c, 0x00000000},
1356 {0x00008000, 0x00000000},
1357 {0x00008004, 0x00000000},
1358 {0x00008008, 0x00000000},
1359 {0x0000800c, 0x00000000},
1360 {0x00008018, 0x00000000},
1361 {0x00008020, 0x00000000},
1362 {0x00008038, 0x00000000},
1363 {0x0000803c, 0x00000000},
1364 {0x00008040, 0x00000000},
1365 {0x00008044, 0x00000000},
1366 {0x00008048, 0x00000000},
1367 {0x0000804c, 0xffffffff},
1368 {0x00008054, 0x00000000},
1369 {0x00008058, 0x00000000},
1370 {0x0000805c, 0x000fc78f},
1371 {0x00008060, 0x0000000f},
1372 {0x00008064, 0x00000000},
1373 {0x00008070, 0x00000310},
1374 {0x00008074, 0x00000020},
1375 {0x00008078, 0x00000000},
1376 {0x0000809c, 0x0000000f},
1377 {0x000080a0, 0x00000000},
1378 {0x000080a4, 0x02ff0000},
1379 {0x000080a8, 0x0e070605},
1380 {0x000080ac, 0x0000000d},
1381 {0x000080b0, 0x00000000},
1382 {0x000080b4, 0x00000000},
1383 {0x000080b8, 0x00000000},
1384 {0x000080bc, 0x00000000},
1385 {0x000080c0, 0x2a800000},
1386 {0x000080c4, 0x06900168},
1387 {0x000080c8, 0x13881c20},
1388 {0x000080cc, 0x01f40000},
1389 {0x000080d0, 0x00252500},
1390 {0x000080d4, 0x00a00000},
1391 {0x000080d8, 0x00400000},
1392 {0x000080dc, 0x00000000},
1393 {0x000080e0, 0xffffffff},
1394 {0x000080e4, 0x0000ffff},
1395 {0x000080e8, 0x3f3f3f3f},
1396 {0x000080ec, 0x00000000},
1397 {0x000080f0, 0x00000000},
1398 {0x000080f4, 0x00000000},
1399 {0x000080fc, 0x00020000},
1400 {0x00008100, 0x00000000},
1401 {0x00008108, 0x00000052},
1402 {0x0000810c, 0x00000000},
1403 {0x00008110, 0x00000000},
1404 {0x00008114, 0x000007ff},
1405 {0x00008118, 0x000000aa},
1406 {0x0000811c, 0x00003210},
1407 {0x00008124, 0x00000000},
1408 {0x00008128, 0x00000000},
1409 {0x0000812c, 0x00000000},
1410 {0x00008130, 0x00000000},
1411 {0x00008134, 0x00000000},
1412 {0x00008138, 0x00000000},
1413 {0x0000813c, 0x0000ffff},
1414 {0x00008144, 0xffffffff},
1415 {0x00008168, 0x00000000},
1416 {0x0000816c, 0x00000000},
1417 {0x00008170, 0x18486200},
1418 {0x00008174, 0x33332210},
1419 {0x00008178, 0x00000000},
1420 {0x0000817c, 0x00020000},
1421 {0x000081c0, 0x00000000},
1422 {0x000081c4, 0x33332210},
1423 {0x000081c8, 0x00000000},
1424 {0x000081cc, 0x00000000},
1425 {0x000081d4, 0x00000000},
1426 {0x000081ec, 0x00000000},
1427 {0x000081f0, 0x00000000},
1428 {0x000081f4, 0x00000000},
1429 {0x000081f8, 0x00000000},
1430 {0x000081fc, 0x00000000},
1431 {0x00008240, 0x00100000},
1432 {0x00008244, 0x0010f424},
1433 {0x00008248, 0x00000800},
1434 {0x0000824c, 0x0001e848},
1435 {0x00008250, 0x00000000},
1436 {0x00008254, 0x00000000},
1437 {0x00008258, 0x00000000},
1438 {0x0000825c, 0x40000000},
1439 {0x00008260, 0x00080922},
1440 {0x00008264, 0x98a00010},
1441 {0x00008268, 0xffffffff},
1442 {0x0000826c, 0x0000ffff},
1443 {0x00008270, 0x00000000},
1444 {0x00008274, 0x40000000},
1445 {0x00008278, 0x003e4180},
1446 {0x0000827c, 0x00000004},
1447 {0x00008284, 0x0000002c},
1448 {0x00008288, 0x0000002c},
1449 {0x0000828c, 0x000000ff},
1450 {0x00008294, 0x00000000},
1451 {0x00008298, 0x00000000},
1452 {0x0000829c, 0x00000000},
1453 {0x00008300, 0x00000140},
1454 {0x00008314, 0x00000000},
1455 {0x0000831c, 0x0000010d},
1456 {0x00008328, 0x00000000},
1457 {0x0000832c, 0x00000007},
1458 {0x00008330, 0x00000302},
1459 {0x00008334, 0x00000700},
1460 {0x00008338, 0x00ff0000},
1461 {0x0000833c, 0x02400000},
1462 {0x00008340, 0x000107ff},
1463 {0x00008344, 0xaa48105b},
1464 {0x00008348, 0x008f0000},
1465 {0x0000835c, 0x00000000},
1466 {0x00008360, 0xffffffff},
1467 {0x00008364, 0xffffffff},
1468 {0x00008368, 0x00000000},
1469 {0x00008370, 0x00000000},
1470 {0x00008374, 0x000000ff},
1471 {0x00008378, 0x00000000},
1472 {0x0000837c, 0x00000000},
1473 {0x00008380, 0xffffffff},
1474 {0x00008384, 0xffffffff},
1475 {0x00008390, 0xffffffff},
1476 {0x00008394, 0xffffffff},
1477 {0x00008398, 0x00000000},
1478 {0x0000839c, 0x00000000},
1479 {0x000083a0, 0x00000000},
1480 {0x000083a4, 0x0000fa14},
1481 {0x000083a8, 0x000f0c00},
1482 {0x000083ac, 0x33332210},
1483 {0x000083b0, 0x33332210},
1484 {0x000083b4, 0x33332210},
1485 {0x000083b8, 0x33332210},
1486 {0x000083bc, 0x00000000},
1487 {0x000083c0, 0x00000000},
1488 {0x000083c4, 0x00000000},
1489 {0x000083c8, 0x00000000},
1490 {0x000083cc, 0x00000200},
1491 {0x000083d0, 0x000301ff},
1492};
1493
1494static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
1495 /* Addr allmodes */
1496 {0x0000a000, 0x00010000},
1497 {0x0000a004, 0x00030002},
1498 {0x0000a008, 0x00050004},
1499 {0x0000a00c, 0x00810080},
1500 {0x0000a010, 0x00830082},
1501 {0x0000a014, 0x01810180},
1502 {0x0000a018, 0x01830182},
1503 {0x0000a01c, 0x01850184},
1504 {0x0000a020, 0x01890188},
1505 {0x0000a024, 0x018b018a},
1506 {0x0000a028, 0x018d018c},
1507 {0x0000a02c, 0x03820190},
1508 {0x0000a030, 0x03840383},
1509 {0x0000a034, 0x03880385},
1510 {0x0000a038, 0x038a0389},
1511 {0x0000a03c, 0x038c038b},
1512 {0x0000a040, 0x0390038d},
1513 {0x0000a044, 0x03920391},
1514 {0x0000a048, 0x03940393},
1515 {0x0000a04c, 0x03960395},
1516 {0x0000a050, 0x00000000},
1517 {0x0000a054, 0x00000000},
1518 {0x0000a058, 0x00000000},
1519 {0x0000a05c, 0x00000000},
1520 {0x0000a060, 0x00000000},
1521 {0x0000a064, 0x00000000},
1522 {0x0000a068, 0x00000000},
1523 {0x0000a06c, 0x00000000},
1524 {0x0000a070, 0x00000000},
1525 {0x0000a074, 0x00000000},
1526 {0x0000a078, 0x00000000},
1527 {0x0000a07c, 0x00000000},
1528 {0x0000a080, 0x29292929},
1529 {0x0000a084, 0x29292929},
1530 {0x0000a088, 0x29292929},
1531 {0x0000a08c, 0x29292929},
1532 {0x0000a090, 0x22292929},
1533 {0x0000a094, 0x1d1d2222},
1534 {0x0000a098, 0x0c111117},
1535 {0x0000a09c, 0x00030303},
1536 {0x0000a0a0, 0x00000000},
1537 {0x0000a0a4, 0x00000000},
1538 {0x0000a0a8, 0x00000000},
1539 {0x0000a0ac, 0x00000000},
1540 {0x0000a0b0, 0x00000000},
1541 {0x0000a0b4, 0x00000000},
1542 {0x0000a0b8, 0x00000000},
1543 {0x0000a0bc, 0x00000000},
1544 {0x0000a0c0, 0x001f0000},
1545 {0x0000a0c4, 0x01000101},
1546 {0x0000a0c8, 0x011e011f},
1547 {0x0000a0cc, 0x011c011d},
1548 {0x0000a0d0, 0x02030204},
1549 {0x0000a0d4, 0x02010202},
1550 {0x0000a0d8, 0x021f0200},
1551 {0x0000a0dc, 0x0302021e},
1552 {0x0000a0e0, 0x03000301},
1553 {0x0000a0e4, 0x031e031f},
1554 {0x0000a0e8, 0x0402031d},
1555 {0x0000a0ec, 0x04000401},
1556 {0x0000a0f0, 0x041e041f},
1557 {0x0000a0f4, 0x0502041d},
1558 {0x0000a0f8, 0x05000501},
1559 {0x0000a0fc, 0x051e051f},
1560 {0x0000a100, 0x06010602},
1561 {0x0000a104, 0x061f0600},
1562 {0x0000a108, 0x061d061e},
1563 {0x0000a10c, 0x07020703},
1564 {0x0000a110, 0x07000701},
1565 {0x0000a114, 0x00000000},
1566 {0x0000a118, 0x00000000},
1567 {0x0000a11c, 0x00000000},
1568 {0x0000a120, 0x00000000},
1569 {0x0000a124, 0x00000000},
1570 {0x0000a128, 0x00000000},
1571 {0x0000a12c, 0x00000000},
1572 {0x0000a130, 0x00000000},
1573 {0x0000a134, 0x00000000},
1574 {0x0000a138, 0x00000000},
1575 {0x0000a13c, 0x00000000},
1576 {0x0000a140, 0x001f0000},
1577 {0x0000a144, 0x01000101},
1578 {0x0000a148, 0x011e011f},
1579 {0x0000a14c, 0x011c011d},
1580 {0x0000a150, 0x02030204},
1581 {0x0000a154, 0x02010202},
1582 {0x0000a158, 0x021f0200},
1583 {0x0000a15c, 0x0302021e},
1584 {0x0000a160, 0x03000301},
1585 {0x0000a164, 0x031e031f},
1586 {0x0000a168, 0x0402031d},
1587 {0x0000a16c, 0x04000401},
1588 {0x0000a170, 0x041e041f},
1589 {0x0000a174, 0x0502041d},
1590 {0x0000a178, 0x05000501},
1591 {0x0000a17c, 0x051e051f},
1592 {0x0000a180, 0x06010602},
1593 {0x0000a184, 0x061f0600},
1594 {0x0000a188, 0x061d061e},
1595 {0x0000a18c, 0x07020703},
1596 {0x0000a190, 0x07000701},
1597 {0x0000a194, 0x00000000},
1598 {0x0000a198, 0x00000000},
1599 {0x0000a19c, 0x00000000},
1600 {0x0000a1a0, 0x00000000},
1601 {0x0000a1a4, 0x00000000},
1602 {0x0000a1a8, 0x00000000},
1603 {0x0000a1ac, 0x00000000},
1604 {0x0000a1b0, 0x00000000},
1605 {0x0000a1b4, 0x00000000},
1606 {0x0000a1b8, 0x00000000},
1607 {0x0000a1bc, 0x00000000},
1608 {0x0000a1c0, 0x00000000},
1609 {0x0000a1c4, 0x00000000},
1610 {0x0000a1c8, 0x00000000},
1611 {0x0000a1cc, 0x00000000},
1612 {0x0000a1d0, 0x00000000},
1613 {0x0000a1d4, 0x00000000},
1614 {0x0000a1d8, 0x00000000},
1615 {0x0000a1dc, 0x00000000},
1616 {0x0000a1e0, 0x00000000},
1617 {0x0000a1e4, 0x00000000},
1618 {0x0000a1e8, 0x00000000},
1619 {0x0000a1ec, 0x00000000},
1620 {0x0000a1f0, 0x00000396},
1621 {0x0000a1f4, 0x00000396},
1622 {0x0000a1f8, 0x00000396},
1623 {0x0000a1fc, 0x00000196},
1624 {0x0000b000, 0x00010000},
1625 {0x0000b004, 0x00030002},
1626 {0x0000b008, 0x00050004},
1627 {0x0000b00c, 0x00810080},
1628 {0x0000b010, 0x00830082},
1629 {0x0000b014, 0x01810180},
1630 {0x0000b018, 0x01830182},
1631 {0x0000b01c, 0x01850184},
1632 {0x0000b020, 0x02810280},
1633 {0x0000b024, 0x02830282},
1634 {0x0000b028, 0x02850284},
1635 {0x0000b02c, 0x02890288},
1636 {0x0000b030, 0x028b028a},
1637 {0x0000b034, 0x0388028c},
1638 {0x0000b038, 0x038a0389},
1639 {0x0000b03c, 0x038c038b},
1640 {0x0000b040, 0x0390038d},
1641 {0x0000b044, 0x03920391},
1642 {0x0000b048, 0x03940393},
1643 {0x0000b04c, 0x03960395},
1644 {0x0000b050, 0x00000000},
1645 {0x0000b054, 0x00000000},
1646 {0x0000b058, 0x00000000},
1647 {0x0000b05c, 0x00000000},
1648 {0x0000b060, 0x00000000},
1649 {0x0000b064, 0x00000000},
1650 {0x0000b068, 0x00000000},
1651 {0x0000b06c, 0x00000000},
1652 {0x0000b070, 0x00000000},
1653 {0x0000b074, 0x00000000},
1654 {0x0000b078, 0x00000000},
1655 {0x0000b07c, 0x00000000},
1656 {0x0000b080, 0x32323232},
1657 {0x0000b084, 0x2f2f3232},
1658 {0x0000b088, 0x23282a2d},
1659 {0x0000b08c, 0x1c1e2123},
1660 {0x0000b090, 0x14171919},
1661 {0x0000b094, 0x0e0e1214},
1662 {0x0000b098, 0x03050707},
1663 {0x0000b09c, 0x00030303},
1664 {0x0000b0a0, 0x00000000},
1665 {0x0000b0a4, 0x00000000},
1666 {0x0000b0a8, 0x00000000},
1667 {0x0000b0ac, 0x00000000},
1668 {0x0000b0b0, 0x00000000},
1669 {0x0000b0b4, 0x00000000},
1670 {0x0000b0b8, 0x00000000},
1671 {0x0000b0bc, 0x00000000},
1672 {0x0000b0c0, 0x003f0020},
1673 {0x0000b0c4, 0x00400041},
1674 {0x0000b0c8, 0x0140005f},
1675 {0x0000b0cc, 0x0160015f},
1676 {0x0000b0d0, 0x017e017f},
1677 {0x0000b0d4, 0x02410242},
1678 {0x0000b0d8, 0x025f0240},
1679 {0x0000b0dc, 0x027f0260},
1680 {0x0000b0e0, 0x0341027e},
1681 {0x0000b0e4, 0x035f0340},
1682 {0x0000b0e8, 0x037f0360},
1683 {0x0000b0ec, 0x04400441},
1684 {0x0000b0f0, 0x0460045f},
1685 {0x0000b0f4, 0x0541047f},
1686 {0x0000b0f8, 0x055f0540},
1687 {0x0000b0fc, 0x057f0560},
1688 {0x0000b100, 0x06400641},
1689 {0x0000b104, 0x0660065f},
1690 {0x0000b108, 0x067e067f},
1691 {0x0000b10c, 0x07410742},
1692 {0x0000b110, 0x075f0740},
1693 {0x0000b114, 0x077f0760},
1694 {0x0000b118, 0x07800781},
1695 {0x0000b11c, 0x07a0079f},
1696 {0x0000b120, 0x07c107bf},
1697 {0x0000b124, 0x000007c0},
1698 {0x0000b128, 0x00000000},
1699 {0x0000b12c, 0x00000000},
1700 {0x0000b130, 0x00000000},
1701 {0x0000b134, 0x00000000},
1702 {0x0000b138, 0x00000000},
1703 {0x0000b13c, 0x00000000},
1704 {0x0000b140, 0x003f0020},
1705 {0x0000b144, 0x00400041},
1706 {0x0000b148, 0x0140005f},
1707 {0x0000b14c, 0x0160015f},
1708 {0x0000b150, 0x017e017f},
1709 {0x0000b154, 0x02410242},
1710 {0x0000b158, 0x025f0240},
1711 {0x0000b15c, 0x027f0260},
1712 {0x0000b160, 0x0341027e},
1713 {0x0000b164, 0x035f0340},
1714 {0x0000b168, 0x037f0360},
1715 {0x0000b16c, 0x04400441},
1716 {0x0000b170, 0x0460045f},
1717 {0x0000b174, 0x0541047f},
1718 {0x0000b178, 0x055f0540},
1719 {0x0000b17c, 0x057f0560},
1720 {0x0000b180, 0x06400641},
1721 {0x0000b184, 0x0660065f},
1722 {0x0000b188, 0x067e067f},
1723 {0x0000b18c, 0x07410742},
1724 {0x0000b190, 0x075f0740},
1725 {0x0000b194, 0x077f0760},
1726 {0x0000b198, 0x07800781},
1727 {0x0000b19c, 0x07a0079f},
1728 {0x0000b1a0, 0x07c107bf},
1729 {0x0000b1a4, 0x000007c0},
1730 {0x0000b1a8, 0x00000000},
1731 {0x0000b1ac, 0x00000000},
1732 {0x0000b1b0, 0x00000000},
1733 {0x0000b1b4, 0x00000000},
1734 {0x0000b1b8, 0x00000000},
1735 {0x0000b1bc, 0x00000000},
1736 {0x0000b1c0, 0x00000000},
1737 {0x0000b1c4, 0x00000000},
1738 {0x0000b1c8, 0x00000000},
1739 {0x0000b1cc, 0x00000000},
1740 {0x0000b1d0, 0x00000000},
1741 {0x0000b1d4, 0x00000000},
1742 {0x0000b1d8, 0x00000000},
1743 {0x0000b1dc, 0x00000000},
1744 {0x0000b1e0, 0x00000000},
1745 {0x0000b1e4, 0x00000000},
1746 {0x0000b1e8, 0x00000000},
1747 {0x0000b1ec, 0x00000000},
1748 {0x0000b1f0, 0x00000396},
1749 {0x0000b1f4, 0x00000396},
1750 {0x0000b1f8, 0x00000396},
1751 {0x0000b1fc, 0x00000196},
1752};
1753
1754static const u32 ar9300_2p0_soc_preamble[][2] = {
1755 /* Addr allmodes */
1756 {0x000040a4, 0x00a0c1c9},
1757 {0x00007008, 0x00000000},
1758 {0x00007020, 0x00000000},
1759 {0x00007034, 0x00000002},
1760 {0x00007038, 0x000004c2},
1761};
1762
1763static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = {
1764 /* Addr allmodes */
1765 {0x00004040, 0x08212e5e},
1766 {0x00004040, 0x0008003b},
1767 {0x00004044, 0x00000000},
1768};
1769
1770static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = {
1771 /* Addr allmodes */
1772 {0x00004040, 0x08253e5e},
1773 {0x00004040, 0x0008003b},
1774 {0x00004044, 0x00000000},
1775};
1776
1777static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
1778 /* Addr allmodes */
1779 {0x00004040, 0x08213e5e},
1780 {0x00004040, 0x0008003b},
1781 {0x00004044, 0x00000000},
1782};
1783
1784#endif /* INITVALS_9003_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
new file mode 100644
index 000000000000..37ba37481a47
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -0,0 +1,614 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include "hw.h"
17#include "ar9003_mac.h"
18
19static void ar9003_hw_rx_enable(struct ath_hw *hw)
20{
21 REG_WRITE(hw, AR_CR, 0);
22}
23
24static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
25{
26 int checksum;
27
28 checksum = ads->info + ads->link
29 + ads->data0 + ads->ctl3
30 + ads->data1 + ads->ctl5
31 + ads->data2 + ads->ctl7
32 + ads->data3 + ads->ctl9;
33
34 return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
35}
36
37static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
38{
39 struct ar9003_txc *ads = ds;
40
41 ads->link = ds_link;
42 ads->ctl10 &= ~AR_TxPtrChkSum;
43 ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
44}
45
46static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
47{
48 struct ar9003_txc *ads = ds;
49
50 *ds_link = &ads->link;
51}
52
53static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
54{
55 u32 isr = 0;
56 u32 mask2 = 0;
57 struct ath9k_hw_capabilities *pCap = &ah->caps;
58 u32 sync_cause = 0;
59 struct ath_common *common = ath9k_hw_common(ah);
60
61 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
62 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
63 == AR_RTC_STATUS_ON)
64 isr = REG_READ(ah, AR_ISR);
65 }
66
67 sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
68
69 *masked = 0;
70
71 if (!isr && !sync_cause)
72 return false;
73
74 if (isr) {
75 if (isr & AR_ISR_BCNMISC) {
76 u32 isr2;
77 isr2 = REG_READ(ah, AR_ISR_S2);
78
79 mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
80 MAP_ISR_S2_TIM);
81 mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
82 MAP_ISR_S2_DTIM);
83 mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
84 MAP_ISR_S2_DTIMSYNC);
85 mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
86 MAP_ISR_S2_CABEND);
87 mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
88 MAP_ISR_S2_GTT);
89 mask2 |= ((isr2 & AR_ISR_S2_CST) <<
90 MAP_ISR_S2_CST);
91 mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
92 MAP_ISR_S2_TSFOOR);
93
94 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
95 REG_WRITE(ah, AR_ISR_S2, isr2);
96 isr &= ~AR_ISR_BCNMISC;
97 }
98 }
99
100 if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
101 isr = REG_READ(ah, AR_ISR_RAC);
102
103 if (isr == 0xffffffff) {
104 *masked = 0;
105 return false;
106 }
107
108 *masked = isr & ATH9K_INT_COMMON;
109
110 if (ah->config.rx_intr_mitigation)
111 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
112 *masked |= ATH9K_INT_RXLP;
113
114 if (ah->config.tx_intr_mitigation)
115 if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
116 *masked |= ATH9K_INT_TX;
117
118 if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
119 *masked |= ATH9K_INT_RXLP;
120
121 if (isr & AR_ISR_HP_RXOK)
122 *masked |= ATH9K_INT_RXHP;
123
124 if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
125 *masked |= ATH9K_INT_TX;
126
127 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
128 u32 s0, s1;
129 s0 = REG_READ(ah, AR_ISR_S0);
130 REG_WRITE(ah, AR_ISR_S0, s0);
131 s1 = REG_READ(ah, AR_ISR_S1);
132 REG_WRITE(ah, AR_ISR_S1, s1);
133
134 isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
135 AR_ISR_TXEOL);
136 }
137 }
138
139 if (isr & AR_ISR_GENTMR) {
140 u32 s5;
141
142 if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
143 s5 = REG_READ(ah, AR_ISR_S5_S);
144 else
145 s5 = REG_READ(ah, AR_ISR_S5);
146
147 ah->intr_gen_timer_trigger =
148 MS(s5, AR_ISR_S5_GENTIMER_TRIG);
149
150 ah->intr_gen_timer_thresh =
151 MS(s5, AR_ISR_S5_GENTIMER_THRESH);
152
153 if (ah->intr_gen_timer_trigger)
154 *masked |= ATH9K_INT_GENTIMER;
155
156 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
157 REG_WRITE(ah, AR_ISR_S5, s5);
158 isr &= ~AR_ISR_GENTMR;
159 }
160
161 }
162
163 *masked |= mask2;
164
165 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
166 REG_WRITE(ah, AR_ISR, isr);
167
168 (void) REG_READ(ah, AR_ISR);
169 }
170 }
171
172 if (sync_cause) {
173 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
174 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
175 REG_WRITE(ah, AR_RC, 0);
176 *masked |= ATH9K_INT_FATAL;
177 }
178
179 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
180 ath_print(common, ATH_DBG_INTERRUPT,
181 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
182
183 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
184 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
185
186 }
187 return true;
188}
189
190static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
191 bool is_firstseg, bool is_lastseg,
192 const void *ds0, dma_addr_t buf_addr,
193 unsigned int qcu)
194{
195 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
196 unsigned int descid = 0;
197
198 ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
199 (1 << AR_TxRxDesc_S) |
200 (1 << AR_CtrlStat_S) |
201 (qcu << AR_TxQcuNum_S) | 0x17;
202
203 ads->data0 = buf_addr;
204 ads->data1 = 0;
205 ads->data2 = 0;
206 ads->data3 = 0;
207
208 ads->ctl3 = (seglen << AR_BufLen_S);
209 ads->ctl3 &= AR_BufLen;
210
211 /* Fill in pointer checksum and descriptor id */
212 ads->ctl10 = ar9003_calc_ptr_chksum(ads);
213 ads->ctl10 |= (descid << AR_TxDescId_S);
214
215 if (is_firstseg) {
216 ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
217 } else if (is_lastseg) {
218 ads->ctl11 = 0;
219 ads->ctl12 = 0;
220 ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
221 ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
222 } else {
223 /* XXX Intermediate descriptor in a multi-descriptor frame.*/
224 ads->ctl11 = 0;
225 ads->ctl12 = AR_TxMore;
226 ads->ctl13 = 0;
227 ads->ctl14 = 0;
228 }
229}
230
231static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
232 struct ath_tx_status *ts)
233{
234 struct ar9003_txs *ads;
235
236 ads = &ah->ts_ring[ah->ts_tail];
237
238 if ((ads->status8 & AR_TxDone) == 0)
239 return -EINPROGRESS;
240
241 ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
242
243 if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
244 (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
245 ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
246 "Tx Descriptor error %x\n", ads->ds_info);
247 memset(ads, 0, sizeof(*ads));
248 return -EIO;
249 }
250
251 ts->qid = MS(ads->ds_info, AR_TxQcuNum);
252 ts->desc_id = MS(ads->status1, AR_TxDescId);
253 ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
254 ts->ts_tstamp = ads->status4;
255 ts->ts_status = 0;
256 ts->ts_flags = 0;
257
258 if (ads->status3 & AR_ExcessiveRetries)
259 ts->ts_status |= ATH9K_TXERR_XRETRY;
260 if (ads->status3 & AR_Filtered)
261 ts->ts_status |= ATH9K_TXERR_FILT;
262 if (ads->status3 & AR_FIFOUnderrun) {
263 ts->ts_status |= ATH9K_TXERR_FIFO;
264 ath9k_hw_updatetxtriglevel(ah, true);
265 }
266 if (ads->status8 & AR_TxOpExceeded)
267 ts->ts_status |= ATH9K_TXERR_XTXOP;
268 if (ads->status3 & AR_TxTimerExpired)
269 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
270
271 if (ads->status3 & AR_DescCfgErr)
272 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
273 if (ads->status3 & AR_TxDataUnderrun) {
274 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
275 ath9k_hw_updatetxtriglevel(ah, true);
276 }
277 if (ads->status3 & AR_TxDelimUnderrun) {
278 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
279 ath9k_hw_updatetxtriglevel(ah, true);
280 }
281 if (ads->status2 & AR_TxBaStatus) {
282 ts->ts_flags |= ATH9K_TX_BA;
283 ts->ba_low = ads->status5;
284 ts->ba_high = ads->status6;
285 }
286
287 ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
288
289 ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
290 ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
291 ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
292 ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
293 ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
294 ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
295 ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
296 ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
297 ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
298 ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
299 ts->ts_antenna = 0;
300
301 ts->tid = MS(ads->status8, AR_TxTid);
302
303 memset(ads, 0, sizeof(*ads));
304
305 return 0;
306}
307
308static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
309 u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
310 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
311{
312 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
313
314 if (txpower > ah->txpower_limit)
315 txpower = ah->txpower_limit;
316
317 txpower += ah->txpower_indexoffset;
318 if (txpower > 63)
319 txpower = 63;
320
321 ads->ctl11 = (pktlen & AR_FrameLen)
322 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
323 | SM(txpower, AR_XmitPower)
324 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
325 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
326 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
327 | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
328
329 ads->ctl12 =
330 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
331 | SM(type, AR_FrameType)
332 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
333 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
334 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
335
336 ads->ctl17 = SM(keyType, AR_EncrType) |
337 (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
338 ads->ctl18 = 0;
339 ads->ctl19 = AR_Not_Sounding;
340
341 ads->ctl20 = 0;
342 ads->ctl21 = 0;
343 ads->ctl22 = 0;
344}
345
346static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
347 void *lastds,
348 u32 durUpdateEn, u32 rtsctsRate,
349 u32 rtsctsDuration,
350 struct ath9k_11n_rate_series series[],
351 u32 nseries, u32 flags)
352{
353 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
354 struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
355 u_int32_t ctl11;
356
357 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
358 ctl11 = ads->ctl11;
359
360 if (flags & ATH9K_TXDESC_RTSENA) {
361 ctl11 &= ~AR_CTSEnable;
362 ctl11 |= AR_RTSEnable;
363 } else {
364 ctl11 &= ~AR_RTSEnable;
365 ctl11 |= AR_CTSEnable;
366 }
367
368 ads->ctl11 = ctl11;
369 } else {
370 ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
371 }
372
373 ads->ctl13 = set11nTries(series, 0)
374 | set11nTries(series, 1)
375 | set11nTries(series, 2)
376 | set11nTries(series, 3)
377 | (durUpdateEn ? AR_DurUpdateEna : 0)
378 | SM(0, AR_BurstDur);
379
380 ads->ctl14 = set11nRate(series, 0)
381 | set11nRate(series, 1)
382 | set11nRate(series, 2)
383 | set11nRate(series, 3);
384
385 ads->ctl15 = set11nPktDurRTSCTS(series, 0)
386 | set11nPktDurRTSCTS(series, 1);
387
388 ads->ctl16 = set11nPktDurRTSCTS(series, 2)
389 | set11nPktDurRTSCTS(series, 3);
390
391 ads->ctl18 = set11nRateFlags(series, 0)
392 | set11nRateFlags(series, 1)
393 | set11nRateFlags(series, 2)
394 | set11nRateFlags(series, 3)
395 | SM(rtsctsRate, AR_RTSCTSRate);
396 ads->ctl19 = AR_Not_Sounding;
397
398 last_ads->ctl13 = ads->ctl13;
399 last_ads->ctl14 = ads->ctl14;
400}
401
402static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
403 u32 aggrLen)
404{
405 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
406
407 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
408
409 ads->ctl17 &= ~AR_AggrLen;
410 ads->ctl17 |= SM(aggrLen, AR_AggrLen);
411}
412
413static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
414 u32 numDelims)
415{
416 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
417 unsigned int ctl17;
418
419 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
420
421 /*
422 * We use a stack variable to manipulate ctl6 to reduce uncached
423 * read modify, modfiy, write.
424 */
425 ctl17 = ads->ctl17;
426 ctl17 &= ~AR_PadDelim;
427 ctl17 |= SM(numDelims, AR_PadDelim);
428 ads->ctl17 = ctl17;
429}
430
431static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
432{
433 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
434
435 ads->ctl12 |= AR_IsAggr;
436 ads->ctl12 &= ~AR_MoreAggr;
437 ads->ctl17 &= ~AR_PadDelim;
438}
439
440static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
441{
442 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
443
444 ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
445}
446
447static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
448 u32 burstDuration)
449{
450 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
451
452 ads->ctl13 &= ~AR_BurstDur;
453 ads->ctl13 |= SM(burstDuration, AR_BurstDur);
454
455}
456
457static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
458 u32 vmf)
459{
460 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
461
462 if (vmf)
463 ads->ctl11 |= AR_VirtMoreFrag;
464 else
465 ads->ctl11 &= ~AR_VirtMoreFrag;
466}
467
468void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
469{
470 struct ath_hw_ops *ops = ath9k_hw_ops(hw);
471
472 ops->rx_enable = ar9003_hw_rx_enable;
473 ops->set_desc_link = ar9003_hw_set_desc_link;
474 ops->get_desc_link = ar9003_hw_get_desc_link;
475 ops->get_isr = ar9003_hw_get_isr;
476 ops->fill_txdesc = ar9003_hw_fill_txdesc;
477 ops->proc_txdesc = ar9003_hw_proc_txdesc;
478 ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
479 ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
480 ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
481 ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
482 ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
483 ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
484 ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
485 ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
486}
487
488void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
489{
490 REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
491}
492EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
493
494void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
495 enum ath9k_rx_qtype qtype)
496{
497 if (qtype == ATH9K_RX_QUEUE_HP)
498 REG_WRITE(ah, AR_HP_RXDP, rxdp);
499 else
500 REG_WRITE(ah, AR_LP_RXDP, rxdp);
501}
502EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
503
504int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
505 void *buf_addr)
506{
507 struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
508 unsigned int phyerr;
509
510 /* TODO: byte swap on big endian for ar9300_10 */
511
512 if ((rxsp->status11 & AR_RxDone) == 0)
513 return -EINPROGRESS;
514
515 if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
516 return -EINVAL;
517
518 if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
519 return -EINPROGRESS;
520
521 if (!rxs)
522 return 0;
523
524 rxs->rs_status = 0;
525 rxs->rs_flags = 0;
526
527 rxs->rs_datalen = rxsp->status2 & AR_DataLen;
528 rxs->rs_tstamp = rxsp->status3;
529
530 /* XXX: Keycache */
531 rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
532 rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
533 rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
534 rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
535 rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
536 rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
537 rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
538
539 if (rxsp->status11 & AR_RxKeyIdxValid)
540 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
541 else
542 rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
543
544 rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
545 rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
546
547 rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
548 rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
549 rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
550 rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
551 rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
552
553 rxs->evm0 = rxsp->status6;
554 rxs->evm1 = rxsp->status7;
555 rxs->evm2 = rxsp->status8;
556 rxs->evm3 = rxsp->status9;
557 rxs->evm4 = (rxsp->status10 & 0xffff);
558
559 if (rxsp->status11 & AR_PreDelimCRCErr)
560 rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
561
562 if (rxsp->status11 & AR_PostDelimCRCErr)
563 rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
564
565 if (rxsp->status11 & AR_DecryptBusyErr)
566 rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
567
568 if ((rxsp->status11 & AR_RxFrameOK) == 0) {
569 if (rxsp->status11 & AR_CRCErr) {
570 rxs->rs_status |= ATH9K_RXERR_CRC;
571 } else if (rxsp->status11 & AR_PHYErr) {
572 rxs->rs_status |= ATH9K_RXERR_PHY;
573 phyerr = MS(rxsp->status11, AR_PHYErrCode);
574 rxs->rs_phyerr = phyerr;
575 } else if (rxsp->status11 & AR_DecryptCRCErr) {
576 rxs->rs_status |= ATH9K_RXERR_DECRYPT;
577 } else if (rxsp->status11 & AR_MichaelErr) {
578 rxs->rs_status |= ATH9K_RXERR_MIC;
579 }
580 }
581
582 return 0;
583}
584EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
585
586void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
587{
588 ah->ts_tail = 0;
589
590 memset((void *) ah->ts_ring, 0,
591 ah->ts_size * sizeof(struct ar9003_txs));
592
593 ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
594 "TS Start 0x%x End 0x%x Virt %p, Size %d\n",
595 ah->ts_paddr_start, ah->ts_paddr_end,
596 ah->ts_ring, ah->ts_size);
597
598 REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
599 REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
600}
601
602void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
603 u32 ts_paddr_start,
604 u8 size)
605{
606
607 ah->ts_paddr_start = ts_paddr_start;
608 ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
609 ah->ts_size = size;
610 ah->ts_ring = (struct ar9003_txs *) ts_start;
611
612 ath9k_hw_reset_txstatus_ring(ah);
613}
614EXPORT_SYMBOL(ath9k_hw_setup_statusring);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
new file mode 100644
index 000000000000..f17558b14539
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef AR9003_MAC_H
18#define AR9003_MAC_H
19
20#define AR_DescId 0xffff0000
21#define AR_DescId_S 16
22#define AR_CtrlStat 0x00004000
23#define AR_CtrlStat_S 14
24#define AR_TxRxDesc 0x00008000
25#define AR_TxRxDesc_S 15
26#define AR_TxQcuNum 0x00000f00
27#define AR_TxQcuNum_S 8
28
29#define AR_BufLen 0x0fff0000
30#define AR_BufLen_S 16
31
32#define AR_TxDescId 0xffff0000
33#define AR_TxDescId_S 16
34#define AR_TxPtrChkSum 0x0000ffff
35
36#define AR_TxTid 0xf0000000
37#define AR_TxTid_S 28
38
39#define AR_LowRxChain 0x00004000
40
41#define AR_Not_Sounding 0x20000000
42
43#define MAP_ISR_S2_CST 6
44#define MAP_ISR_S2_GTT 6
45#define MAP_ISR_S2_TIM 3
46#define MAP_ISR_S2_CABEND 0
47#define MAP_ISR_S2_DTIMSYNC 7
48#define MAP_ISR_S2_DTIM 7
49#define MAP_ISR_S2_TSFOOR 4
50
51#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
52
53struct ar9003_rxs {
54 u32 ds_info;
55 u32 status1;
56 u32 status2;
57 u32 status3;
58 u32 status4;
59 u32 status5;
60 u32 status6;
61 u32 status7;
62 u32 status8;
63 u32 status9;
64 u32 status10;
65 u32 status11;
66} __packed;
67
68/* Transmit Control Descriptor */
69struct ar9003_txc {
70 u32 info; /* descriptor information */
71 u32 link; /* link pointer */
72 u32 data0; /* data pointer to 1st buffer */
73 u32 ctl3; /* DMA control 3 */
74 u32 data1; /* data pointer to 2nd buffer */
75 u32 ctl5; /* DMA control 5 */
76 u32 data2; /* data pointer to 3rd buffer */
77 u32 ctl7; /* DMA control 7 */
78 u32 data3; /* data pointer to 4th buffer */
79 u32 ctl9; /* DMA control 9 */
80 u32 ctl10; /* DMA control 10 */
81 u32 ctl11; /* DMA control 11 */
82 u32 ctl12; /* DMA control 12 */
83 u32 ctl13; /* DMA control 13 */
84 u32 ctl14; /* DMA control 14 */
85 u32 ctl15; /* DMA control 15 */
86 u32 ctl16; /* DMA control 16 */
87 u32 ctl17; /* DMA control 17 */
88 u32 ctl18; /* DMA control 18 */
89 u32 ctl19; /* DMA control 19 */
90 u32 ctl20; /* DMA control 20 */
91 u32 ctl21; /* DMA control 21 */
92 u32 ctl22; /* DMA control 22 */
93 u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
94} __packed;
95
96struct ar9003_txs {
97 u32 ds_info;
98 u32 status1;
99 u32 status2;
100 u32 status3;
101 u32 status4;
102 u32 status5;
103 u32 status6;
104 u32 status7;
105 u32 status8;
106} __packed;
107
108void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
109void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
110void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
111 enum ath9k_rx_qtype qtype);
112
113int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
114 struct ath_rx_status *rxs,
115 void *buf_addr);
116void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
117void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
118 u32 ts_paddr_start,
119 u8 size);
120#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
new file mode 100644
index 000000000000..80431a2f6dc1
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -0,0 +1,1134 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar9003_phy.h"
19
20/**
21 * ar9003_hw_set_channel - set channel on single-chip device
22 * @ah: atheros hardware structure
23 * @chan:
24 *
25 * This is the function to change channel on single-chip devices, that is
26 * all devices after ar9280.
27 *
28 * This function takes the channel value in MHz and sets
29 * hardware channel value. Assumes writes have been enabled to analog bus.
30 *
31 * Actual Expression,
32 *
33 * For 2GHz channel,
34 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
35 * (freq_ref = 40MHz)
36 *
37 * For 5GHz channel,
38 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
39 * (freq_ref = 40MHz/(24>>amodeRefSel))
40 *
41 * For 5GHz channels which are 5MHz spaced,
42 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
43 * (freq_ref = 40MHz)
44 */
45static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
46{
47 u16 bMode, fracMode = 0, aModeRefSel = 0;
48 u32 freq, channelSel = 0, reg32 = 0;
49 struct chan_centers centers;
50 int loadSynthChannel;
51
52 ath9k_hw_get_channel_centers(ah, chan, &centers);
53 freq = centers.synth_center;
54
55 if (freq < 4800) { /* 2 GHz, fractional mode */
56 channelSel = CHANSEL_2G(freq);
57 /* Set to 2G mode */
58 bMode = 1;
59 } else {
60 channelSel = CHANSEL_5G(freq);
61 /* Doubler is ON, so, divide channelSel by 2. */
62 channelSel >>= 1;
63 /* Set to 5G mode */
64 bMode = 0;
65 }
66
67 /* Enable fractional mode for all channels */
68 fracMode = 1;
69 aModeRefSel = 0;
70 loadSynthChannel = 0;
71
72 reg32 = (bMode << 29);
73 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
74
75 /* Enable Long shift Select for Synthesizer */
76 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4,
77 AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);
78
79 /* Program Synth. setting */
80 reg32 = (channelSel << 2) | (fracMode << 30) |
81 (aModeRefSel << 28) | (loadSynthChannel << 31);
82 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
83
84 /* Toggle Load Synth channel bit */
85 loadSynthChannel = 1;
86 reg32 = (channelSel << 2) | (fracMode << 30) |
87 (aModeRefSel << 28) | (loadSynthChannel << 31);
88 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
89
90 ah->curchan = chan;
91 ah->curchan_rad_index = -1;
92
93 return 0;
94}
95
96/**
97 * ar9003_hw_spur_mitigate - convert baseband spur frequency
98 * @ah: atheros hardware structure
99 * @chan:
100 *
101 * For single-chip solutions. Converts to baseband spur frequency given the
102 * input channel frequency and compute register settings below.
103 *
104 * Spur mitigation for MRC CCK
105 */
106static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
107 struct ath9k_channel *chan)
108{
109 u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
110 int cur_bb_spur, negative = 0, cck_spur_freq;
111 int i;
112
113 /*
114 * Need to verify range +/- 10 MHz in control channel, otherwise spur
115 * is out-of-band and can be ignored.
116 */
117
118 for (i = 0; i < 4; i++) {
119 negative = 0;
120 cur_bb_spur = spur_freq[i] - chan->channel;
121
122 if (cur_bb_spur < 0) {
123 negative = 1;
124 cur_bb_spur = -cur_bb_spur;
125 }
126 if (cur_bb_spur < 10) {
127 cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
128
129 if (negative == 1)
130 cck_spur_freq = -cck_spur_freq;
131
132 cck_spur_freq = cck_spur_freq & 0xfffff;
133
134 REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
135 AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
136 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
137 AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
138 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
139 AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE,
140 0x2);
141 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
142 AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT,
143 0x1);
144 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
145 AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
146 cck_spur_freq);
147
148 return;
149 }
150 }
151
152 REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
153 AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
154 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
155 AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
156 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
157 AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
158}
159
160/* Clean all spur register fields */
161static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah)
162{
163 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
164 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
165 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
166 AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
167 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
168 AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
169 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
170 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
171 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
172 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
173 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
174 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
175 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
176 AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
177 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
178 AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
179 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
180 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
181
182 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
183 AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
184 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
185 AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
186 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
187 AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
188 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
189 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
190 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
191 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
192 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
193 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
194 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
195 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
196 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
197 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
198 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
199 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
200 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
201 AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
202}
203
204static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
205 int freq_offset,
206 int spur_freq_sd,
207 int spur_delta_phase,
208 int spur_subchannel_sd)
209{
210 int mask_index = 0;
211
212 /* OFDM Spur mitigation */
213 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
214 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
215 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
216 AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
217 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
218 AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
219 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
220 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
221 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
222 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
223 REG_RMW_FIELD(ah, AR_PHY_TIMING11,
224 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
225 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
226 AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
227 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
228 AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
229 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
230 AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
231
232 if (REG_READ_FIELD(ah, AR_PHY_MODE,
233 AR_PHY_MODE_DYNAMIC) == 0x1)
234 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
235 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
236
237 mask_index = (freq_offset << 4) / 5;
238 if (mask_index < 0)
239 mask_index = mask_index - 1;
240
241 mask_index = mask_index & 0x7f;
242
243 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
244 AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
245 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
246 AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
247 REG_RMW_FIELD(ah, AR_PHY_TIMING4,
248 AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
249 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
250 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
251 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
252 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index);
253 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
254 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
255 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
256 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc);
257 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
258 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc);
259 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
260 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
261 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
262 AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
263}
264
265static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
266 struct ath9k_channel *chan,
267 int freq_offset)
268{
269 int spur_freq_sd = 0;
270 int spur_subchannel_sd = 0;
271 int spur_delta_phase = 0;
272
273 if (IS_CHAN_HT40(chan)) {
274 if (freq_offset < 0) {
275 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
276 AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
277 spur_subchannel_sd = 1;
278 else
279 spur_subchannel_sd = 0;
280
281 spur_freq_sd = ((freq_offset + 10) << 9) / 11;
282
283 } else {
284 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
285 AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
286 spur_subchannel_sd = 0;
287 else
288 spur_subchannel_sd = 1;
289
290 spur_freq_sd = ((freq_offset - 10) << 9) / 11;
291
292 }
293
294 spur_delta_phase = (freq_offset << 17) / 5;
295
296 } else {
297 spur_subchannel_sd = 0;
298 spur_freq_sd = (freq_offset << 9) /11;
299 spur_delta_phase = (freq_offset << 18) / 5;
300 }
301
302 spur_freq_sd = spur_freq_sd & 0x3ff;
303 spur_delta_phase = spur_delta_phase & 0xfffff;
304
305 ar9003_hw_spur_ofdm(ah,
306 freq_offset,
307 spur_freq_sd,
308 spur_delta_phase,
309 spur_subchannel_sd);
310}
311
312/* Spur mitigation for OFDM */
313static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
314 struct ath9k_channel *chan)
315{
316 int synth_freq;
317 int range = 10;
318 int freq_offset = 0;
319 int mode;
320 u8* spurChansPtr;
321 unsigned int i;
322 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
323
324 if (IS_CHAN_5GHZ(chan)) {
325 spurChansPtr = &(eep->modalHeader5G.spurChans[0]);
326 mode = 0;
327 }
328 else {
329 spurChansPtr = &(eep->modalHeader2G.spurChans[0]);
330 mode = 1;
331 }
332
333 if (spurChansPtr[0] == 0)
334 return; /* No spur in the mode */
335
336 if (IS_CHAN_HT40(chan)) {
337 range = 19;
338 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
339 AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
340 synth_freq = chan->channel - 10;
341 else
342 synth_freq = chan->channel + 10;
343 } else {
344 range = 10;
345 synth_freq = chan->channel;
346 }
347
348 ar9003_hw_spur_ofdm_clear(ah);
349
350 for (i = 0; spurChansPtr[i] && i < 5; i++) {
351 freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
352 if (abs(freq_offset) < range) {
353 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
354 break;
355 }
356 }
357}
358
359static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
360 struct ath9k_channel *chan)
361{
362 ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
363 ar9003_hw_spur_mitigate_ofdm(ah, chan);
364}
365
366static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
367 struct ath9k_channel *chan)
368{
369 u32 pll;
370
371 pll = SM(0x5, AR_RTC_9300_PLL_REFDIV);
372
373 if (chan && IS_CHAN_HALF_RATE(chan))
374 pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL);
375 else if (chan && IS_CHAN_QUARTER_RATE(chan))
376 pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL);
377
378 pll |= SM(0x2c, AR_RTC_9300_PLL_DIV);
379
380 return pll;
381}
382
383static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
384 struct ath9k_channel *chan)
385{
386 u32 phymode;
387 u32 enableDacFifo = 0;
388
389 enableDacFifo =
390 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO);
391
392 /* Enable 11n HT, 20 MHz */
393 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH |
394 AR_PHY_GC_SHORT_GI_40 | enableDacFifo;
395
396 /* Configure baseband for dynamic 20/40 operation */
397 if (IS_CHAN_HT40(chan)) {
398 phymode |= AR_PHY_GC_DYN2040_EN;
399 /* Configure control (primary) channel at +-10MHz */
400 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
401 (chan->chanmode == CHANNEL_G_HT40PLUS))
402 phymode |= AR_PHY_GC_DYN2040_PRI_CH;
403
404 }
405
406 /* make sure we preserve INI settings */
407 phymode |= REG_READ(ah, AR_PHY_GEN_CTRL);
408 /* turn off Green Field detection for STA for now */
409 phymode &= ~AR_PHY_GC_GF_DETECT_EN;
410
411 REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
412
413 /* Configure MAC for 20/40 operation */
414 ath9k_hw_set11nmac2040(ah);
415
416 /* global transmit timeout (25 TUs default)*/
417 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
418 /* carrier sense timeout */
419 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
420}
421
422static void ar9003_hw_init_bb(struct ath_hw *ah,
423 struct ath9k_channel *chan)
424{
425 u32 synthDelay;
426
427 /*
428 * Wait for the frequency synth to settle (synth goes on
429 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
430 * Value is in 100ns increments.
431 */
432 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
433 if (IS_CHAN_B(chan))
434 synthDelay = (4 * synthDelay) / 22;
435 else
436 synthDelay /= 10;
437
438 /* Activate the PHY (includes baseband activate + synthesizer on) */
439 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
440
441 /*
442 * There is an issue if the AP starts the calibration before
443 * the base band timeout completes. This could result in the
444 * rx_clear false triggering. As a workaround we add delay an
445 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
446 * does not happen.
447 */
448 udelay(synthDelay + BASE_ACTIVATE_DELAY);
449}
450
451void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
452{
453 switch (rx) {
454 case 0x5:
455 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
456 AR_PHY_SWAP_ALT_CHAIN);
457 case 0x3:
458 case 0x1:
459 case 0x2:
460 case 0x7:
461 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
462 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
463 break;
464 default:
465 break;
466 }
467
468 REG_WRITE(ah, AR_SELFGEN_MASK, tx);
469 if (tx == 0x5) {
470 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
471 AR_PHY_SWAP_ALT_CHAIN);
472 }
473}
474
475/*
476 * Override INI values with chip specific configuration.
477 */
478static void ar9003_hw_override_ini(struct ath_hw *ah)
479{
480 u32 val;
481
482 /*
483 * Set the RX_ABORT and RX_DIS and clear it only after
484 * RXE is set for MAC. This prevents frames with
485 * corrupted descriptor status.
486 */
487 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
488
489 /*
490 * For AR9280 and above, there is a new feature that allows
491 * Multicast search based on both MAC Address and Key ID. By default,
492 * this feature is enabled. But since the driver is not using this
493 * feature, we switch it off; otherwise multicast search based on
494 * MAC addr only will fail.
495 */
496 val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
497 REG_WRITE(ah, AR_PCU_MISC_MODE2,
498 val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE);
499}
500
501static void ar9003_hw_prog_ini(struct ath_hw *ah,
502 struct ar5416IniArray *iniArr,
503 int column)
504{
505 unsigned int i, regWrites = 0;
506
507 /* New INI format: Array may be undefined (pre, core, post arrays) */
508 if (!iniArr->ia_array)
509 return;
510
511 /*
512 * New INI format: Pre, core, and post arrays for a given subsystem
513 * may be modal (> 2 columns) or non-modal (2 columns). Determine if
514 * the array is non-modal and force the column to 1.
515 */
516 if (column >= iniArr->ia_columns)
517 column = 1;
518
519 for (i = 0; i < iniArr->ia_rows; i++) {
520 u32 reg = INI_RA(iniArr, i, 0);
521 u32 val = INI_RA(iniArr, i, column);
522
523 REG_WRITE(ah, reg, val);
524
525 /*
526 * Determine if this is a shift register value, and insert the
527 * configured delay if so.
528 */
529 if (reg >= 0x16000 && reg < 0x17000
530 && ah->config.analog_shiftreg)
531 udelay(100);
532
533 DO_DELAY(regWrites);
534 }
535}
536
537static int ar9003_hw_process_ini(struct ath_hw *ah,
538 struct ath9k_channel *chan)
539{
540 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
541 unsigned int regWrites = 0, i;
542 struct ieee80211_channel *channel = chan->chan;
543 u32 modesIndex, freqIndex;
544
545 switch (chan->chanmode) {
546 case CHANNEL_A:
547 case CHANNEL_A_HT20:
548 modesIndex = 1;
549 freqIndex = 1;
550 break;
551 case CHANNEL_A_HT40PLUS:
552 case CHANNEL_A_HT40MINUS:
553 modesIndex = 2;
554 freqIndex = 1;
555 break;
556 case CHANNEL_G:
557 case CHANNEL_G_HT20:
558 case CHANNEL_B:
559 modesIndex = 4;
560 freqIndex = 2;
561 break;
562 case CHANNEL_G_HT40PLUS:
563 case CHANNEL_G_HT40MINUS:
564 modesIndex = 3;
565 freqIndex = 2;
566 break;
567
568 default:
569 return -EINVAL;
570 }
571
572 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
573 ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
574 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
575 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
576 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
577 }
578
579 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
580 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
581
582 /*
583 * For 5GHz channels requiring Fast Clock, apply
584 * different modal values.
585 */
586 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
587 REG_WRITE_ARRAY(&ah->iniModesAdditional,
588 modesIndex, regWrites);
589
590 ar9003_hw_override_ini(ah);
591 ar9003_hw_set_channel_regs(ah, chan);
592 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
593
594 /* Set TX power */
595 ah->eep_ops->set_txpower(ah, chan,
596 ath9k_regd_get_ctl(regulatory, chan),
597 channel->max_antenna_gain * 2,
598 channel->max_power * 2,
599 min((u32) MAX_RATE_POWER,
600 (u32) regulatory->power_limit));
601
602 return 0;
603}
604
605static void ar9003_hw_set_rfmode(struct ath_hw *ah,
606 struct ath9k_channel *chan)
607{
608 u32 rfMode = 0;
609
610 if (chan == NULL)
611 return;
612
613 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
614 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
615
616 if (IS_CHAN_A_FAST_CLOCK(ah, chan))
617 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
618
619 REG_WRITE(ah, AR_PHY_MODE, rfMode);
620}
621
622static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
623{
624 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
625}
626
627static void ar9003_hw_set_delta_slope(struct ath_hw *ah,
628 struct ath9k_channel *chan)
629{
630 u32 coef_scaled, ds_coef_exp, ds_coef_man;
631 u32 clockMhzScaled = 0x64000000;
632 struct chan_centers centers;
633
634 /*
635 * half and quarter rate can divide the scaled clock by 2 or 4
636 * scale for selected channel bandwidth
637 */
638 if (IS_CHAN_HALF_RATE(chan))
639 clockMhzScaled = clockMhzScaled >> 1;
640 else if (IS_CHAN_QUARTER_RATE(chan))
641 clockMhzScaled = clockMhzScaled >> 2;
642
643 /*
644 * ALGO -> coef = 1e8/fcarrier*fclock/40;
645 * scaled coef to provide precision for this floating calculation
646 */
647 ath9k_hw_get_channel_centers(ah, chan, &centers);
648 coef_scaled = clockMhzScaled / centers.synth_center;
649
650 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
651 &ds_coef_exp);
652
653 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
654 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
655 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
656 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
657
658 /*
659 * For Short GI,
660 * scaled coeff is 9/10 that of normal coeff
661 */
662 coef_scaled = (9 * coef_scaled) / 10;
663
664 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
665 &ds_coef_exp);
666
667 /* for short gi */
668 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
669 AR_PHY_SGI_DSC_MAN, ds_coef_man);
670 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
671 AR_PHY_SGI_DSC_EXP, ds_coef_exp);
672}
673
674static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
675{
676 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
677 return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
678 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
679}
680
681/*
682 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
683 * Read the phy active delay register. Value is in 100ns increments.
684 */
685static void ar9003_hw_rfbus_done(struct ath_hw *ah)
686{
687 u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
688 if (IS_CHAN_B(ah->curchan))
689 synthDelay = (4 * synthDelay) / 22;
690 else
691 synthDelay /= 10;
692
693 udelay(synthDelay + BASE_ACTIVATE_DELAY);
694
695 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
696}
697
698/*
699 * Set the interrupt and GPIO values so the ISR can disable RF
700 * on a switch signal. Assumes GPIO port and interrupt polarity
701 * are set prior to call.
702 */
703static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
704{
705 /* Connect rfsilent_bb_l to baseband */
706 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
707 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
708 /* Set input mux for rfsilent_bb_l to GPIO #0 */
709 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
710 AR_GPIO_INPUT_MUX2_RFSILENT);
711
712 /*
713 * Configure the desired GPIO port for input and
714 * enable baseband rf silence.
715 */
716 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
717 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
718}
719
720static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
721{
722 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
723 if (value)
724 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
725 else
726 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
727 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
728}
729
730static bool ar9003_hw_ani_control(struct ath_hw *ah,
731 enum ath9k_ani_cmd cmd, int param)
732{
733 struct ar5416AniState *aniState = ah->curani;
734 struct ath_common *common = ath9k_hw_common(ah);
735
736 switch (cmd & ah->ani_function) {
737 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
738 u32 level = param;
739
740 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
741 ath_print(common, ATH_DBG_ANI,
742 "level out of range (%u > %u)\n",
743 level,
744 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
745 return false;
746 }
747
748 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
749 AR_PHY_DESIRED_SZ_TOT_DES,
750 ah->totalSizeDesired[level]);
751 REG_RMW_FIELD(ah, AR_PHY_AGC,
752 AR_PHY_AGC_COARSE_LOW,
753 ah->coarse_low[level]);
754 REG_RMW_FIELD(ah, AR_PHY_AGC,
755 AR_PHY_AGC_COARSE_HIGH,
756 ah->coarse_high[level]);
757 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
758 AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
759
760 if (level > aniState->noiseImmunityLevel)
761 ah->stats.ast_ani_niup++;
762 else if (level < aniState->noiseImmunityLevel)
763 ah->stats.ast_ani_nidown++;
764 aniState->noiseImmunityLevel = level;
765 break;
766 }
767 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
768 const int m1ThreshLow[] = { 127, 50 };
769 const int m2ThreshLow[] = { 127, 40 };
770 const int m1Thresh[] = { 127, 0x4d };
771 const int m2Thresh[] = { 127, 0x40 };
772 const int m2CountThr[] = { 31, 16 };
773 const int m2CountThrLow[] = { 63, 48 };
774 u32 on = param ? 1 : 0;
775
776 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
777 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
778 m1ThreshLow[on]);
779 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
780 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
781 m2ThreshLow[on]);
782 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
783 AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]);
784 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
785 AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]);
786 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
787 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]);
788 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
789 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
790 m2CountThrLow[on]);
791
792 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
793 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]);
794 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
795 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]);
796 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
797 AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]);
798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
799 AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]);
800
801 if (on)
802 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
803 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
804 else
805 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
806 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
807
808 if (!on != aniState->ofdmWeakSigDetectOff) {
809 if (on)
810 ah->stats.ast_ani_ofdmon++;
811 else
812 ah->stats.ast_ani_ofdmoff++;
813 aniState->ofdmWeakSigDetectOff = !on;
814 }
815 break;
816 }
817 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
818 const int weakSigThrCck[] = { 8, 6 };
819 u32 high = param ? 1 : 0;
820
821 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
822 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
823 weakSigThrCck[high]);
824 if (high != aniState->cckWeakSigThreshold) {
825 if (high)
826 ah->stats.ast_ani_cckhigh++;
827 else
828 ah->stats.ast_ani_ccklow++;
829 aniState->cckWeakSigThreshold = high;
830 }
831 break;
832 }
833 case ATH9K_ANI_FIRSTEP_LEVEL:{
834 const int firstep[] = { 0, 4, 8 };
835 u32 level = param;
836
837 if (level >= ARRAY_SIZE(firstep)) {
838 ath_print(common, ATH_DBG_ANI,
839 "level out of range (%u > %u)\n",
840 level,
841 (unsigned) ARRAY_SIZE(firstep));
842 return false;
843 }
844 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
845 AR_PHY_FIND_SIG_FIRSTEP,
846 firstep[level]);
847 if (level > aniState->firstepLevel)
848 ah->stats.ast_ani_stepup++;
849 else if (level < aniState->firstepLevel)
850 ah->stats.ast_ani_stepdown++;
851 aniState->firstepLevel = level;
852 break;
853 }
854 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
855 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
856 u32 level = param;
857
858 if (level >= ARRAY_SIZE(cycpwrThr1)) {
859 ath_print(common, ATH_DBG_ANI,
860 "level out of range (%u > %u)\n",
861 level,
862 (unsigned) ARRAY_SIZE(cycpwrThr1));
863 return false;
864 }
865 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
866 AR_PHY_TIMING5_CYCPWR_THR1,
867 cycpwrThr1[level]);
868 if (level > aniState->spurImmunityLevel)
869 ah->stats.ast_ani_spurup++;
870 else if (level < aniState->spurImmunityLevel)
871 ah->stats.ast_ani_spurdown++;
872 aniState->spurImmunityLevel = level;
873 break;
874 }
875 case ATH9K_ANI_PRESENT:
876 break;
877 default:
878 ath_print(common, ATH_DBG_ANI,
879 "invalid cmd %u\n", cmd);
880 return false;
881 }
882
883 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
884 ath_print(common, ATH_DBG_ANI,
885 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
886 "ofdmWeakSigDetectOff=%d\n",
887 aniState->noiseImmunityLevel,
888 aniState->spurImmunityLevel,
889 !aniState->ofdmWeakSigDetectOff);
890 ath_print(common, ATH_DBG_ANI,
891 "cckWeakSigThreshold=%d, "
892 "firstepLevel=%d, listenTime=%d\n",
893 aniState->cckWeakSigThreshold,
894 aniState->firstepLevel,
895 aniState->listenTime);
896 ath_print(common, ATH_DBG_ANI,
897 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
898 aniState->cycleCount,
899 aniState->ofdmPhyErrCount,
900 aniState->cckPhyErrCount);
901
902 return true;
903}
904
905static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
906{
907 struct ath_common *common = ath9k_hw_common(ah);
908
909 if (*nf > ah->nf_2g_max) {
910 ath_print(common, ATH_DBG_CALIBRATE,
911 "2 GHz NF (%d) > MAX (%d), "
912 "correcting to MAX",
913 *nf, ah->nf_2g_max);
914 *nf = ah->nf_2g_max;
915 } else if (*nf < ah->nf_2g_min) {
916 ath_print(common, ATH_DBG_CALIBRATE,
917 "2 GHz NF (%d) < MIN (%d), "
918 "correcting to MIN",
919 *nf, ah->nf_2g_min);
920 *nf = ah->nf_2g_min;
921 }
922}
923
924static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
925{
926 struct ath_common *common = ath9k_hw_common(ah);
927
928 if (*nf > ah->nf_5g_max) {
929 ath_print(common, ATH_DBG_CALIBRATE,
930 "5 GHz NF (%d) > MAX (%d), "
931 "correcting to MAX",
932 *nf, ah->nf_5g_max);
933 *nf = ah->nf_5g_max;
934 } else if (*nf < ah->nf_5g_min) {
935 ath_print(common, ATH_DBG_CALIBRATE,
936 "5 GHz NF (%d) < MIN (%d), "
937 "correcting to MIN",
938 *nf, ah->nf_5g_min);
939 *nf = ah->nf_5g_min;
940 }
941}
942
943static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
944{
945 if (IS_CHAN_2GHZ(ah->curchan))
946 ar9003_hw_nf_sanitize_2g(ah, nf);
947 else
948 ar9003_hw_nf_sanitize_5g(ah, nf);
949}
950
951static void ar9003_hw_do_getnf(struct ath_hw *ah,
952 int16_t nfarray[NUM_NF_READINGS])
953{
954 struct ath_common *common = ath9k_hw_common(ah);
955 int16_t nf;
956
957 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
958 if (nf & 0x100)
959 nf = 0 - ((nf ^ 0x1ff) + 1);
960 ar9003_hw_nf_sanitize(ah, &nf);
961 ath_print(common, ATH_DBG_CALIBRATE,
962 "NF calibrated [ctl] [chain 0] is %d\n", nf);
963 nfarray[0] = nf;
964
965 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
966 if (nf & 0x100)
967 nf = 0 - ((nf ^ 0x1ff) + 1);
968 ar9003_hw_nf_sanitize(ah, &nf);
969 ath_print(common, ATH_DBG_CALIBRATE,
970 "NF calibrated [ctl] [chain 1] is %d\n", nf);
971 nfarray[1] = nf;
972
973 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
974 if (nf & 0x100)
975 nf = 0 - ((nf ^ 0x1ff) + 1);
976 ar9003_hw_nf_sanitize(ah, &nf);
977 ath_print(common, ATH_DBG_CALIBRATE,
978 "NF calibrated [ctl] [chain 2] is %d\n", nf);
979 nfarray[2] = nf;
980
981 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
982 if (nf & 0x100)
983 nf = 0 - ((nf ^ 0x1ff) + 1);
984 ar9003_hw_nf_sanitize(ah, &nf);
985 ath_print(common, ATH_DBG_CALIBRATE,
986 "NF calibrated [ext] [chain 0] is %d\n", nf);
987 nfarray[3] = nf;
988
989 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
990 if (nf & 0x100)
991 nf = 0 - ((nf ^ 0x1ff) + 1);
992 ar9003_hw_nf_sanitize(ah, &nf);
993 ath_print(common, ATH_DBG_CALIBRATE,
994 "NF calibrated [ext] [chain 1] is %d\n", nf);
995 nfarray[4] = nf;
996
997 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
998 if (nf & 0x100)
999 nf = 0 - ((nf ^ 0x1ff) + 1);
1000 ar9003_hw_nf_sanitize(ah, &nf);
1001 ath_print(common, ATH_DBG_CALIBRATE,
1002 "NF calibrated [ext] [chain 2] is %d\n", nf);
1003 nfarray[5] = nf;
1004}
1005
1006void ar9003_hw_set_nf_limits(struct ath_hw *ah)
1007{
1008 ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
1009 ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
1010 ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
1011 ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
1012}
1013
1014/*
1015 * Find out which of the RX chains are enabled
1016 */
1017static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
1018{
1019 u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
1020 /*
1021 * The bits [2:0] indicate the rx chain mask and are to be
1022 * interpreted as follows:
1023 * 00x => Only chain 0 is enabled
1024 * 01x => Chain 1 and 0 enabled
1025 * 1xx => Chain 2,1 and 0 enabled
1026 */
1027 return chain & 0x7;
1028}
1029
1030static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1031{
1032 struct ath9k_nfcal_hist *h;
1033 unsigned i, j;
1034 int32_t val;
1035 const u32 ar9300_cca_regs[6] = {
1036 AR_PHY_CCA_0,
1037 AR_PHY_CCA_1,
1038 AR_PHY_CCA_2,
1039 AR_PHY_EXT_CCA,
1040 AR_PHY_EXT_CCA_1,
1041 AR_PHY_EXT_CCA_2,
1042 };
1043 u8 chainmask, rx_chain_status;
1044 struct ath_common *common = ath9k_hw_common(ah);
1045
1046 rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
1047
1048 chainmask = 0x3F;
1049 h = ah->nfCalHist;
1050
1051 for (i = 0; i < NUM_NF_READINGS; i++) {
1052 if (chainmask & (1 << i)) {
1053 val = REG_READ(ah, ar9300_cca_regs[i]);
1054 val &= 0xFFFFFE00;
1055 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1056 REG_WRITE(ah, ar9300_cca_regs[i], val);
1057 }
1058 }
1059
1060 /*
1061 * Load software filtered NF value into baseband internal minCCApwr
1062 * variable.
1063 */
1064 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1065 AR_PHY_AGC_CONTROL_ENABLE_NF);
1066 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1067 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1068 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1069
1070 /*
1071 * Wait for load to complete, should be fast, a few 10s of us.
1072 * The max delay was changed from an original 250us to 10000us
1073 * since 250us often results in NF load timeout and causes deaf
1074 * condition during stress testing 12/12/2009
1075 */
1076 for (j = 0; j < 1000; j++) {
1077 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1078 AR_PHY_AGC_CONTROL_NF) == 0)
1079 break;
1080 udelay(10);
1081 }
1082
1083 /*
1084 * We timed out waiting for the noisefloor to load, probably due to an
1085 * in-progress rx. Simply return here and allow the load plenty of time
1086 * to complete before the next calibration interval. We need to avoid
1087 * trying to load -50 (which happens below) while the previous load is
1088 * still in progress as this can cause rx deafness. Instead by returning
1089 * here, the baseband nf cal will just be capped by our present
1090 * noisefloor until the next calibration timer.
1091 */
1092 if (j == 1000) {
1093 ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
1094 "to load: AR_PHY_AGC_CONTROL=0x%x\n",
1095 REG_READ(ah, AR_PHY_AGC_CONTROL));
1096 return;
1097 }
1098
1099 /*
1100 * Restore maxCCAPower register parameter again so that we're not capped
1101 * by the median we just loaded. This will be initial (and max) value
1102 * of next noise floor calibration the baseband does.
1103 */
1104 for (i = 0; i < NUM_NF_READINGS; i++) {
1105 if (chainmask & (1 << i)) {
1106 val = REG_READ(ah, ar9300_cca_regs[i]);
1107 val &= 0xFFFFFE00;
1108 val |= (((u32) (-50) << 1) & 0x1ff);
1109 REG_WRITE(ah, ar9300_cca_regs[i], val);
1110 }
1111 }
1112}
1113
1114void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1115{
1116 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1117
1118 priv_ops->rf_set_freq = ar9003_hw_set_channel;
1119 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
1120 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
1121 priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
1122 priv_ops->init_bb = ar9003_hw_init_bb;
1123 priv_ops->process_ini = ar9003_hw_process_ini;
1124 priv_ops->set_rfmode = ar9003_hw_set_rfmode;
1125 priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive;
1126 priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
1127 priv_ops->rfbus_req = ar9003_hw_rfbus_req;
1128 priv_ops->rfbus_done = ar9003_hw_rfbus_done;
1129 priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
1130 priv_ops->set_diversity = ar9003_hw_set_diversity;
1131 priv_ops->ani_control = ar9003_hw_ani_control;
1132 priv_ops->do_getnf = ar9003_hw_do_getnf;
1133 priv_ops->loadnf = ar9003_hw_loadnf;
1134}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
new file mode 100644
index 000000000000..f08cc8bda005
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -0,0 +1,847 @@
1/*
2 * Copyright (c) 2002-2010 Atheros Communications, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef AR9003_PHY_H
18#define AR9003_PHY_H
19
20/*
21 * Channel Register Map
22 */
23#define AR_CHAN_BASE 0x9800
24
25#define AR_PHY_TIMING1 (AR_CHAN_BASE + 0x0)
26#define AR_PHY_TIMING2 (AR_CHAN_BASE + 0x4)
27#define AR_PHY_TIMING3 (AR_CHAN_BASE + 0x8)
28#define AR_PHY_TIMING4 (AR_CHAN_BASE + 0xc)
29#define AR_PHY_TIMING5 (AR_CHAN_BASE + 0x10)
30#define AR_PHY_TIMING6 (AR_CHAN_BASE + 0x14)
31#define AR_PHY_TIMING11 (AR_CHAN_BASE + 0x18)
32#define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c)
33#define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc)
34#define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0)
35
36#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
37#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
38
39#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
40#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
41
42#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000
43#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC_S 30
44
45#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000
46#define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR_S 31
47
48#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT 0x4000000
49#define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT_S 26
50
51#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 /* bins move with freq offset */
52#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM_S 17
53#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x000000FF
54#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
55#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI 0x00000100
56#define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI_S 8
57#define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03FC0000
58#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
59
60#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN 0x20000000
61#define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN_S 29
62
63#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN 0x80000000
64#define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN_S 31
65
66#define AR_PHY_FIND_SIG_LOW (AR_CHAN_BASE + 0x20)
67
68#define AR_PHY_SFCORR (AR_CHAN_BASE + 0x24)
69#define AR_PHY_SFCORR_LOW (AR_CHAN_BASE + 0x28)
70#define AR_PHY_SFCORR_EXT (AR_CHAN_BASE + 0x2c)
71
72#define AR_PHY_EXT_CCA (AR_CHAN_BASE + 0x30)
73#define AR_PHY_RADAR_0 (AR_CHAN_BASE + 0x34)
74#define AR_PHY_RADAR_1 (AR_CHAN_BASE + 0x38)
75#define AR_PHY_RADAR_EXT (AR_CHAN_BASE + 0x3c)
76#define AR_PHY_MULTICHAIN_CTRL (AR_CHAN_BASE + 0x80)
77#define AR_PHY_PERCHAIN_CSD (AR_CHAN_BASE + 0x84)
78
79#define AR_PHY_TX_PHASE_RAMP_0 (AR_CHAN_BASE + 0xd0)
80#define AR_PHY_ADC_GAIN_DC_CORR_0 (AR_CHAN_BASE + 0xd4)
81#define AR_PHY_IQ_ADC_MEAS_0_B0 (AR_CHAN_BASE + 0xc0)
82#define AR_PHY_IQ_ADC_MEAS_1_B0 (AR_CHAN_BASE + 0xc4)
83#define AR_PHY_IQ_ADC_MEAS_2_B0 (AR_CHAN_BASE + 0xc8)
84#define AR_PHY_IQ_ADC_MEAS_3_B0 (AR_CHAN_BASE + 0xcc)
85
86/* The following registers changed position from AR9300 1.0 to AR9300 2.0 */
87#define AR_PHY_TX_PHASE_RAMP_0_9300_10 (AR_CHAN_BASE + 0xd0 - 0x10)
88#define AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 (AR_CHAN_BASE + 0xd4 - 0x10)
89#define AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 (AR_CHAN_BASE + 0xc0 + 0x8)
90#define AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 (AR_CHAN_BASE + 0xc4 + 0x8)
91#define AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 (AR_CHAN_BASE + 0xc8 + 0x8)
92#define AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 (AR_CHAN_BASE + 0xcc + 0x8)
93
94#define AR_PHY_TX_CRC (AR_CHAN_BASE + 0xa0)
95#define AR_PHY_TST_DAC_CONST (AR_CHAN_BASE + 0xa4)
96#define AR_PHY_SPUR_REPORT_0 (AR_CHAN_BASE + 0xa8)
97#define AR_PHY_CHAN_INFO_TAB_0 (AR_CHAN_BASE + 0x300)
98
99/*
100 * Channel Field Definitions
101 */
102#define AR_PHY_TIMING2_USE_FORCE_PPM 0x00001000
103#define AR_PHY_TIMING2_FORCE_PPM_VAL 0x00000fff
104#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
105#define AR_PHY_TIMING3_DSC_MAN_S 17
106#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
107#define AR_PHY_TIMING3_DSC_EXP_S 13
108#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX 0xF000
109#define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S 12
110#define AR_PHY_TIMING4_DO_CAL 0x10000
111
112#define AR_PHY_TIMING4_ENABLE_PILOT_MASK 0x10000000
113#define AR_PHY_TIMING4_ENABLE_PILOT_MASK_S 28
114#define AR_PHY_TIMING4_ENABLE_CHAN_MASK 0x20000000
115#define AR_PHY_TIMING4_ENABLE_CHAN_MASK_S 29
116
117#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000
118#define AR_PHY_TIMING4_ENABLE_SPUR_FILTER_S 30
119#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000
120#define AR_PHY_TIMING4_ENABLE_SPUR_RSSI_S 31
121
122#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
123#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
124#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
125#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
126#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
127#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
128#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
129#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
130#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
131#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
132#define AR_PHY_SFCORR_M2COUNT_THR_S 0
133#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
134#define AR_PHY_SFCORR_M1_THRESH_S 17
135#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
136#define AR_PHY_SFCORR_M2_THRESH_S 24
137#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
138#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
139#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
140#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
141#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
142#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
143#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
144#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
145#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000
146#define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD_S 28
147#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
148#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
149#define AR_PHY_EXT_CCA_THRESH62_S 16
150#define AR_PHY_EXT_MINCCA_PWR 0x01FF0000
151#define AR_PHY_EXT_MINCCA_PWR_S 16
152#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
153#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
154#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001
155#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE_S 0
156#define AR_PHY_TIMING5_CYCPWR_THR1A 0x007F0000
157#define AR_PHY_TIMING5_CYCPWR_THR1A_S 16
158#define AR_PHY_TIMING5_RSSI_THR1A (0x7F << 16)
159#define AR_PHY_TIMING5_RSSI_THR1A_S 16
160#define AR_PHY_TIMING5_RSSI_THR1A_ENA (0x1 << 15)
161#define AR_PHY_RADAR_0_ENA 0x00000001
162#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
163#define AR_PHY_RADAR_0_INBAND 0x0000003e
164#define AR_PHY_RADAR_0_INBAND_S 1
165#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
166#define AR_PHY_RADAR_0_PRSSI_S 6
167#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
168#define AR_PHY_RADAR_0_HEIGHT_S 12
169#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
170#define AR_PHY_RADAR_0_RRSSI_S 18
171#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
172#define AR_PHY_RADAR_0_FIRPWR_S 24
173#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
174#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
175#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
176#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
177#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
178#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
179#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
180#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
181#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
182#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
183#define AR_PHY_RADAR_1_MAXLEN_S 0
184#define AR_PHY_RADAR_EXT_ENA 0x00004000
185#define AR_PHY_RADAR_DC_PWR_THRESH 0x007f8000
186#define AR_PHY_RADAR_DC_PWR_THRESH_S 15
187#define AR_PHY_RADAR_LB_DC_CAP 0x7f800000
188#define AR_PHY_RADAR_LB_DC_CAP_S 23
189#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW (0x3f << 6)
190#define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S 6
191#define AR_PHY_FIND_SIG_LOW_FIRPWR (0x7f << 12)
192#define AR_PHY_FIND_SIG_LOW_FIRPWR_S 12
193#define AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT 19
194#define AR_PHY_FIND_SIG_LOW_RELSTEP 0x1f
195#define AR_PHY_FIND_SIG_LOW_RELSTEP_S 0
196#define AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT 5
197#define AR_PHY_CHAN_INFO_TAB_S2_READ 0x00000008
198#define AR_PHY_CHAN_INFO_TAB_S2_READ_S 3
199#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF 0x0000007F
200#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S 0
201#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF 0x00003F80
202#define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S 7
203#define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE 0x00004000
204#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF 0x003f8000
205#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15
206#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF 0x1fc00000
207#define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22
208
209/*
210 * MRC Register Map
211 */
212#define AR_MRC_BASE 0x9c00
213
214#define AR_PHY_TIMING_3A (AR_MRC_BASE + 0x0)
215#define AR_PHY_LDPC_CNTL1 (AR_MRC_BASE + 0x4)
216#define AR_PHY_LDPC_CNTL2 (AR_MRC_BASE + 0x8)
217#define AR_PHY_PILOT_SPUR_MASK (AR_MRC_BASE + 0xc)
218#define AR_PHY_CHAN_SPUR_MASK (AR_MRC_BASE + 0x10)
219#define AR_PHY_SGI_DELTA (AR_MRC_BASE + 0x14)
220#define AR_PHY_ML_CNTL_1 (AR_MRC_BASE + 0x18)
221#define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c)
222#define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20)
223
224#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0
225#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5
226#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F
227#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
228
229#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0
230#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5
231#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F
232#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0
233
234/*
235 * MRC Feild Definitions
236 */
237#define AR_PHY_SGI_DSC_MAN 0x0007FFF0
238#define AR_PHY_SGI_DSC_MAN_S 4
239#define AR_PHY_SGI_DSC_EXP 0x0000000F
240#define AR_PHY_SGI_DSC_EXP_S 0
241/*
242 * BBB Register Map
243 */
244#define AR_BBB_BASE 0x9d00
245
246/*
247 * AGC Register Map
248 */
249#define AR_AGC_BASE 0x9e00
250
251#define AR_PHY_SETTLING (AR_AGC_BASE + 0x0)
252#define AR_PHY_FORCEMAX_GAINS_0 (AR_AGC_BASE + 0x4)
253#define AR_PHY_GAINS_MINOFF0 (AR_AGC_BASE + 0x8)
254#define AR_PHY_DESIRED_SZ (AR_AGC_BASE + 0xc)
255#define AR_PHY_FIND_SIG (AR_AGC_BASE + 0x10)
256#define AR_PHY_AGC (AR_AGC_BASE + 0x14)
257#define AR_PHY_EXT_ATTEN_CTL_0 (AR_AGC_BASE + 0x18)
258#define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c)
259#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
260#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
261#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
262#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
263#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
264#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
265#define AR_PHY_RIFS_SRCH (AR_AGC_BASE + 0x38)
266#define AR_PHY_PEAK_DET_CTRL_1 (AR_AGC_BASE + 0x3c)
267#define AR_PHY_PEAK_DET_CTRL_2 (AR_AGC_BASE + 0x40)
268#define AR_PHY_RX_GAIN_BOUNDS_1 (AR_AGC_BASE + 0x44)
269#define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48)
270#define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180)
271#define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184)
272#define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0)
273#define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4)
274#define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8)
275
276#define AR_PHY_CCK_SPUR_MIT (AR_AGC_BASE + 0x1cc)
277#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR 0x000001fe
278#define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S 1
279#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE 0x60000000
280#define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S 29
281#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT 0x00000001
282#define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_S 0
283#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00
284#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9
285
286#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
287
288#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
289#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
290#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125
291#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125
292#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
293#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
294
295/*
296 * AGC Field Definitions
297 */
298#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN 0x00FC0000
299#define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S 18
300#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN 0x00003C00
301#define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S 10
302#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN 0x0000001F
303#define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S 0
304#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN 0x003E0000
305#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S 17
306#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN 0x0001F000
307#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S 12
308#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB 0x00000FC0
309#define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S 6
310#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB 0x0000003F
311#define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S 0
312#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
313#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
314#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
315#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
316#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
317#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
318#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
319#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
320#define AR_PHY_SETTLING_SWITCH 0x00003F80
321#define AR_PHY_SETTLING_SWITCH_S 7
322#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
323#define AR_PHY_DESIRED_SZ_ADC_S 0
324#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
325#define AR_PHY_DESIRED_SZ_PGA_S 8
326#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
327#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
328#define AR_PHY_MINCCA_PWR 0x1FF00000
329#define AR_PHY_MINCCA_PWR_S 20
330#define AR_PHY_CCA_THRESH62 0x0007F000
331#define AR_PHY_CCA_THRESH62_S 12
332#define AR9280_PHY_MINCCA_PWR 0x1FF00000
333#define AR9280_PHY_MINCCA_PWR_S 20
334#define AR9280_PHY_CCA_THRESH62 0x000FF000
335#define AR9280_PHY_CCA_THRESH62_S 12
336#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
337#define AR_PHY_EXT_CCA0_THRESH62_S 0
338#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
339#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
340#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
341#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
342#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
343
344#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
345#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR_S 9
346#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
347#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
348
349#define AR_PHY_RIFS_INIT_DELAY 0x3ff0000
350#define AR_PHY_AGC_COARSE_LOW 0x00007F80
351#define AR_PHY_AGC_COARSE_LOW_S 7
352#define AR_PHY_AGC_COARSE_HIGH 0x003F8000
353#define AR_PHY_AGC_COARSE_HIGH_S 15
354#define AR_PHY_AGC_COARSE_PWR_CONST 0x0000007F
355#define AR_PHY_AGC_COARSE_PWR_CONST_S 0
356#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
357#define AR_PHY_FIND_SIG_FIRSTEP_S 12
358#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
359#define AR_PHY_FIND_SIG_FIRPWR_S 18
360#define AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT 25
361#define AR_PHY_FIND_SIG_RELPWR (0x1f << 6)
362#define AR_PHY_FIND_SIG_RELPWR_S 6
363#define AR_PHY_FIND_SIG_RELPWR_SIGN_BIT 11
364#define AR_PHY_FIND_SIG_RELSTEP 0x1f
365#define AR_PHY_FIND_SIG_RELSTEP_S 0
366#define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT 5
367#define AR_PHY_RESTART_DIV_GC 0x001C0000
368#define AR_PHY_RESTART_DIV_GC_S 18
369#define AR_PHY_RESTART_ENA 0x01
370#define AR_PHY_DC_RESTART_DIS 0x40000000
371
372#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON 0xFF000000
373#define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON_S 24
374#define AR_PHY_TPC_OLPC_GAIN_DELTA 0x00FF0000
375#define AR_PHY_TPC_OLPC_GAIN_DELTA_S 16
376
377#define AR_PHY_TPC_6_ERROR_EST_MODE 0x03000000
378#define AR_PHY_TPC_6_ERROR_EST_MODE_S 24
379
380/*
381 * SM Register Map
382 */
383#define AR_SM_BASE 0xa200
384
385#define AR_PHY_D2_CHIP_ID (AR_SM_BASE + 0x0)
386#define AR_PHY_GEN_CTRL (AR_SM_BASE + 0x4)
387#define AR_PHY_MODE (AR_SM_BASE + 0x8)
388#define AR_PHY_ACTIVE (AR_SM_BASE + 0xc)
389#define AR_PHY_SPUR_MASK_A (AR_SM_BASE + 0x20)
390#define AR_PHY_SPUR_MASK_B (AR_SM_BASE + 0x24)
391#define AR_PHY_SPECTRAL_SCAN (AR_SM_BASE + 0x28)
392#define AR_PHY_RADAR_BW_FILTER (AR_SM_BASE + 0x2c)
393#define AR_PHY_SEARCH_START_DELAY (AR_SM_BASE + 0x30)
394#define AR_PHY_MAX_RX_LEN (AR_SM_BASE + 0x34)
395#define AR_PHY_FRAME_CTL (AR_SM_BASE + 0x38)
396#define AR_PHY_RFBUS_REQ (AR_SM_BASE + 0x3c)
397#define AR_PHY_RFBUS_GRANT (AR_SM_BASE + 0x40)
398#define AR_PHY_RIFS (AR_SM_BASE + 0x44)
399#define AR_PHY_RX_CLR_DELAY (AR_SM_BASE + 0x50)
400#define AR_PHY_RX_DELAY (AR_SM_BASE + 0x54)
401
402#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64)
403#define AR_PHY_MISC_PA_CTL (AR_SM_BASE + 0x80)
404#define AR_PHY_SWITCH_CHAIN_0 (AR_SM_BASE + 0x84)
405#define AR_PHY_SWITCH_COM (AR_SM_BASE + 0x88)
406#define AR_PHY_SWITCH_COM_2 (AR_SM_BASE + 0x8c)
407#define AR_PHY_RX_CHAINMASK (AR_SM_BASE + 0xa0)
408#define AR_PHY_CAL_CHAINMASK (AR_SM_BASE + 0xc0)
409#define AR_PHY_CALMODE (AR_SM_BASE + 0xc8)
410#define AR_PHY_FCAL_1 (AR_SM_BASE + 0xcc)
411#define AR_PHY_FCAL_2_0 (AR_SM_BASE + 0xd0)
412#define AR_PHY_DFT_TONE_CTL_0 (AR_SM_BASE + 0xd4)
413#define AR_PHY_CL_CAL_CTL (AR_SM_BASE + 0xd8)
414#define AR_PHY_CL_TAB_0 (AR_SM_BASE + 0x100)
415#define AR_PHY_SYNTH_CONTROL (AR_SM_BASE + 0x140)
416#define AR_PHY_ADDAC_CLK_SEL (AR_SM_BASE + 0x144)
417#define AR_PHY_PLL_CTL (AR_SM_BASE + 0x148)
418#define AR_PHY_ANALOG_SWAP (AR_SM_BASE + 0x14c)
419#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150)
420#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158)
421
422#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00
423#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10
424#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF
425#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S 0
426
427#define AR_PHY_TEST (AR_SM_BASE + 0x160)
428
429#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
430#define AR_PHY_TEST_BBB_OBS_SEL_S 19
431
432#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
433#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
434
435#define AR_PHY_TEST_CHAIN_SEL 0xC0000000
436#define AR_PHY_TEST_CHAIN_SEL_S 30
437
438#define AR_PHY_TEST_CTL_STATUS (AR_SM_BASE + 0x164)
439#define AR_PHY_TEST_CTL_TSTDAC_EN 0x1
440#define AR_PHY_TEST_CTL_TSTDAC_EN_S 0
441#define AR_PHY_TEST_CTL_TX_OBS_SEL 0x1C
442#define AR_PHY_TEST_CTL_TX_OBS_SEL_S 2
443#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL 0x60
444#define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S 5
445#define AR_PHY_TEST_CTL_TSTADC_EN 0x100
446#define AR_PHY_TEST_CTL_TSTADC_EN_S 8
447#define AR_PHY_TEST_CTL_RX_OBS_SEL 0x3C00
448#define AR_PHY_TEST_CTL_RX_OBS_SEL_S 10
449
450
451#define AR_PHY_TSTDAC (AR_SM_BASE + 0x168)
452
453#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c)
454#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170)
455#define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174)
456#define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178)
457#define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c)
458#define AR_PHY_CHAN_INFO_GAIN_0 (AR_SM_BASE + 0x180)
459#define AR_PHY_SCRAMBLER_SEED (AR_SM_BASE + 0x190)
460#define AR_PHY_CCK_TX_CTRL (AR_SM_BASE + 0x194)
461
462#define AR_PHY_HEAVYCLIP_CTL (AR_SM_BASE + 0x1a4)
463#define AR_PHY_HEAVYCLIP_20 (AR_SM_BASE + 0x1a8)
464#define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac)
465#define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0)
466
467#define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0)
468#define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4)
469
470#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204)
471#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208)
472#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c)
473#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220)
474#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c)
475#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240)
476
477#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
478
479#define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280)
480
481#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
482#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
483#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
484#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
485
486#define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0)
487#define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4)
488#define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8)
489#define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc)
490#define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0)
491#define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4)
492#define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc)
493#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248)
494
495#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
496#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
497#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
498#define AR_PHY_65NM_CH0_SYNTH7 0x16098
499#define AR_PHY_65NM_CH0_BIAS1 0x160c0
500#define AR_PHY_65NM_CH0_BIAS2 0x160c4
501#define AR_PHY_65NM_CH0_BIAS4 0x160cc
502#define AR_PHY_65NM_CH0_RXTX4 0x1610c
503#define AR_PHY_65NM_CH0_THERM 0x16290
504
505#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
506#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
507#define AR_PHY_65NM_CH0_THERM_START 0x20000000
508#define AR_PHY_65NM_CH0_THERM_START_S 29
509#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00
510#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
511
512#define AR_PHY_65NM_CH0_RXTX1 0x16100
513#define AR_PHY_65NM_CH0_RXTX2 0x16104
514#define AR_PHY_65NM_CH1_RXTX1 0x16500
515#define AR_PHY_65NM_CH1_RXTX2 0x16504
516#define AR_PHY_65NM_CH2_RXTX1 0x16900
517#define AR_PHY_65NM_CH2_RXTX2 0x16904
518
519#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000
520#define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19
521#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000
522#define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT_S 22
523#define AR_PHY_LNAGAIN_LONG_SHIFT 0xe0000000
524#define AR_PHY_LNAGAIN_LONG_SHIFT_S 29
525#define AR_PHY_MXRGAIN_LONG_SHIFT 0x03000000
526#define AR_PHY_MXRGAIN_LONG_SHIFT_S 24
527#define AR_PHY_VGAGAIN_LONG_SHIFT 0x1c000000
528#define AR_PHY_VGAGAIN_LONG_SHIFT_S 26
529#define AR_PHY_SCFIR_GAIN_LONG_SHIFT 0x00000001
530#define AR_PHY_SCFIR_GAIN_LONG_SHIFT_S 0
531#define AR_PHY_MANRXGAIN_LONG_SHIFT 0x00000002
532#define AR_PHY_MANRXGAIN_LONG_SHIFT_S 1
533
534/*
535 * SM Field Definitions
536 */
537#define AR_PHY_CL_CAL_ENABLE 0x00000002
538#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
539#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
540#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
541
542#define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000
543
544#define AR_PHY_FCAL20_CAP_STATUS_0 0x01f00000
545#define AR_PHY_FCAL20_CAP_STATUS_0_S 20
546
547#define AR_PHY_RFBUS_REQ_EN 0x00000001 /* request for RF bus */
548#define AR_PHY_RFBUS_GRANT_EN 0x00000001 /* RF bus granted */
549#define AR_PHY_GC_TURBO_MODE 0x00000001 /* set turbo mode bits */
550#define AR_PHY_GC_TURBO_SHORT 0x00000002 /* set short symbols to turbo mode setting */
551#define AR_PHY_GC_DYN2040_EN 0x00000004 /* enable dyn 20/40 mode */
552#define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008 /* dyn 20/40 - primary only */
553#define AR_PHY_GC_DYN2040_PRI_CH 0x00000010 /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/
554#define AR_PHY_GC_DYN2040_PRI_CH_S 4
555#define AR_PHY_GC_DYN2040_EXT_CH 0x00000020 /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */
556#define AR_PHY_GC_HT_EN 0x00000040 /* ht enable */
557#define AR_PHY_GC_SHORT_GI_40 0x00000080 /* allow short GI for HT 40 */
558#define AR_PHY_GC_WALSH 0x00000100 /* walsh spatial spreading for 2 chains,2 streams TX */
559#define AR_PHY_GC_SINGLE_HT_LTF1 0x00000200 /* single length (4us) 1st HT long training symbol */
560#define AR_PHY_GC_GF_DETECT_EN 0x00000400 /* enable Green Field detection. Only affects rx, not tx */
561#define AR_PHY_GC_ENABLE_DAC_FIFO 0x00000800 /* fifo between bb and dac */
562#define AR_PHY_RX_DELAY_DELAY 0x00003FFF /* delay from wakeup to rx ena */
563
564#define AR_PHY_CALMODE_IQ 0x00000000
565#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
566#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
567#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
568#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
569#define AR_PHY_MODE_OFDM 0x00000000
570#define AR_PHY_MODE_CCK 0x00000001
571#define AR_PHY_MODE_DYNAMIC 0x00000004
572#define AR_PHY_MODE_DYNAMIC_S 2
573#define AR_PHY_MODE_HALF 0x00000020
574#define AR_PHY_MODE_QUARTER 0x00000040
575#define AR_PHY_MAC_CLK_MODE 0x00000080
576#define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100
577#define AR_PHY_MODE_SVD_HALF 0x00000200
578#define AR_PHY_ACTIVE_EN 0x00000001
579#define AR_PHY_ACTIVE_DIS 0x00000000
580#define AR_PHY_FORCE_XPA_CFG 0x000000001
581#define AR_PHY_FORCE_XPA_CFG_S 0
582#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF 0xFF000000
583#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S 24
584#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF 0x00FF0000
585#define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S 16
586#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON 0x0000FF00
587#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S 8
588#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON 0x000000FF
589#define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S 0
590#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
591#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
592#define AR_PHY_TX_END_DATA_START 0x000000FF
593#define AR_PHY_TX_END_DATA_START_S 0
594#define AR_PHY_TX_END_PA_ON 0x0000FF00
595#define AR_PHY_TX_END_PA_ON_S 8
596#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
597#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
598#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
599#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
600#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
601#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
602#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
603#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
604#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
605#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
606#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
607#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
608#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
609#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
610#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
611#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
612#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
613#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
614#define AR_PHY_TPCGR1_FORCED_DAC_GAIN 0x0000003e
615#define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1
616#define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001
617#define AR_PHY_TXGAIN_FORCE 0x00000001
618#define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00
619#define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10
620#define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000
621#define AR_PHY_TXGAIN_FORCED_PADVGNRB_S 14
622#define AR_PHY_TXGAIN_FORCED_PADVGNRD 0x00c00000
623#define AR_PHY_TXGAIN_FORCED_PADVGNRD_S 22
624#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN 0x000003c0
625#define AR_PHY_TXGAIN_FORCED_TXMXRGAIN_S 6
626#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN 0x0000000e
627#define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1
628
629#define AR_PHY_POWER_TX_RATE1 0x9934
630#define AR_PHY_POWER_TX_RATE2 0x9938
631#define AR_PHY_POWER_TX_RATE_MAX 0x993c
632#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
633#define PHY_AGC_CLR 0x10000000
634#define RFSILENT_BB 0x00002000
635#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK 0xFFF
636#define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_SIGNED_BIT 0x800
637#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
638#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
639#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
640#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
641#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001
642#define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0
643#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002
644#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1
645#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0
646#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
647#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00
648#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
649#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000
650#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
651#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
652#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
653#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
654#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
655#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
656#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
657#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
658
659#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
660#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
661#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
662
663#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff
664#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
665#define AR_PHY_TPC_19_ALPHA_THERM 0xff
666#define AR_PHY_TPC_19_ALPHA_THERM_S 0
667
668#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
669#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
670
671#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
672#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
673
674/*
675 * Channel 1 Register Map
676 */
677#define AR_CHAN1_BASE 0xa800
678
679#define AR_PHY_EXT_CCA_1 (AR_CHAN1_BASE + 0x30)
680#define AR_PHY_TX_PHASE_RAMP_1 (AR_CHAN1_BASE + 0xd0)
681#define AR_PHY_ADC_GAIN_DC_CORR_1 (AR_CHAN1_BASE + 0xd4)
682
683#define AR_PHY_SPUR_REPORT_1 (AR_CHAN1_BASE + 0xa8)
684#define AR_PHY_CHAN_INFO_TAB_1 (AR_CHAN1_BASE + 0x300)
685#define AR_PHY_RX_IQCAL_CORR_B1 (AR_CHAN1_BASE + 0xdc)
686
687/*
688 * Channel 1 Field Definitions
689 */
690#define AR_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
691#define AR_PHY_CH1_EXT_MINCCA_PWR_S 16
692
693/*
694 * AGC 1 Register Map
695 */
696#define AR_AGC1_BASE 0xae00
697
698#define AR_PHY_FORCEMAX_GAINS_1 (AR_AGC1_BASE + 0x4)
699#define AR_PHY_EXT_ATTEN_CTL_1 (AR_AGC1_BASE + 0x18)
700#define AR_PHY_CCA_1 (AR_AGC1_BASE + 0x1c)
701#define AR_PHY_CCA_CTRL_1 (AR_AGC1_BASE + 0x20)
702#define AR_PHY_RSSI_1 (AR_AGC1_BASE + 0x180)
703#define AR_PHY_SPUR_CCK_REP_1 (AR_AGC1_BASE + 0x184)
704#define AR_PHY_RX_OCGAIN_2 (AR_AGC1_BASE + 0x200)
705
706/*
707 * AGC 1 Field Definitions
708 */
709#define AR_PHY_CH1_MINCCA_PWR 0x1FF00000
710#define AR_PHY_CH1_MINCCA_PWR_S 20
711
712/*
713 * SM 1 Register Map
714 */
715#define AR_SM1_BASE 0xb200
716
717#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84)
718#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0)
719#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4)
720#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100)
721#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180)
722#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204)
723#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
724#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
725#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
726#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240)
727#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
728#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450)
729
730/*
731 * Channel 2 Register Map
732 */
733#define AR_CHAN2_BASE 0xb800
734
735#define AR_PHY_EXT_CCA_2 (AR_CHAN2_BASE + 0x30)
736#define AR_PHY_TX_PHASE_RAMP_2 (AR_CHAN2_BASE + 0xd0)
737#define AR_PHY_ADC_GAIN_DC_CORR_2 (AR_CHAN2_BASE + 0xd4)
738
739#define AR_PHY_SPUR_REPORT_2 (AR_CHAN2_BASE + 0xa8)
740#define AR_PHY_CHAN_INFO_TAB_2 (AR_CHAN2_BASE + 0x300)
741#define AR_PHY_RX_IQCAL_CORR_B2 (AR_CHAN2_BASE + 0xdc)
742
743/*
744 * Channel 2 Field Definitions
745 */
746#define AR_PHY_CH2_EXT_MINCCA_PWR 0x01FF0000
747#define AR_PHY_CH2_EXT_MINCCA_PWR_S 16
748/*
749 * AGC 2 Register Map
750 */
751#define AR_AGC2_BASE 0xbe00
752
753#define AR_PHY_FORCEMAX_GAINS_2 (AR_AGC2_BASE + 0x4)
754#define AR_PHY_EXT_ATTEN_CTL_2 (AR_AGC2_BASE + 0x18)
755#define AR_PHY_CCA_2 (AR_AGC2_BASE + 0x1c)
756#define AR_PHY_CCA_CTRL_2 (AR_AGC2_BASE + 0x20)
757#define AR_PHY_RSSI_2 (AR_AGC2_BASE + 0x180)
758
759/*
760 * AGC 2 Field Definitions
761 */
762#define AR_PHY_CH2_MINCCA_PWR 0x1FF00000
763#define AR_PHY_CH2_MINCCA_PWR_S 20
764
765/*
766 * SM 2 Register Map
767 */
768#define AR_SM2_BASE 0xc200
769
770#define AR_PHY_SWITCH_CHAIN_2 (AR_SM2_BASE + 0x84)
771#define AR_PHY_FCAL_2_2 (AR_SM2_BASE + 0xd0)
772#define AR_PHY_DFT_TONE_CTL_2 (AR_SM2_BASE + 0xd4)
773#define AR_PHY_CL_TAB_2 (AR_SM2_BASE + 0x100)
774#define AR_PHY_CHAN_INFO_GAIN_2 (AR_SM2_BASE + 0x180)
775#define AR_PHY_TPC_4_B2 (AR_SM2_BASE + 0x204)
776#define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208)
777#define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c)
778#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
779#define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240)
780#define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c)
781#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450)
782
783#define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001
784
785/*
786 * AGC 3 Register Map
787 */
788#define AR_AGC3_BASE 0xce00
789
790#define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180)
791
792/*
793 * Misc helper defines
794 */
795#define AR_PHY_CHAIN_OFFSET (AR_CHAN1_BASE - AR_CHAN_BASE)
796
797#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (AR_PHY_ADC_GAIN_DC_CORR_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
798#define AR_PHY_NEW_ADC_DC_GAIN_CORR_9300_10(_i) (AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
799#define AR_PHY_SWITCH_CHAIN(_i) (AR_PHY_SWITCH_CHAIN_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
800#define AR_PHY_EXT_ATTEN_CTL(_i) (AR_PHY_EXT_ATTEN_CTL_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
801
802#define AR_PHY_RXGAIN(_i) (AR_PHY_FORCEMAX_GAINS_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
803#define AR_PHY_TPCRG5(_i) (AR_PHY_TPC_5_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
804#define AR_PHY_PDADC_TAB(_i) (AR_PHY_PDADC_TAB_0 + (AR_PHY_CHAIN_OFFSET * (_i)))
805
806#define AR_PHY_CAL_MEAS_0(_i) (AR_PHY_IQ_ADC_MEAS_0_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
807#define AR_PHY_CAL_MEAS_1(_i) (AR_PHY_IQ_ADC_MEAS_1_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
808#define AR_PHY_CAL_MEAS_2(_i) (AR_PHY_IQ_ADC_MEAS_2_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
809#define AR_PHY_CAL_MEAS_3(_i) (AR_PHY_IQ_ADC_MEAS_3_B0 + (AR_PHY_CHAIN_OFFSET * (_i)))
810#define AR_PHY_CAL_MEAS_0_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
811#define AR_PHY_CAL_MEAS_1_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
812#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
813#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
814
815#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001
816#define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002
817#define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000
818#define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC
819
820#define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002
821#define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004
822#define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9
823
824#define AR_PHY_BB_WD_STATUS 0x00000007
825#define AR_PHY_BB_WD_STATUS_S 0
826#define AR_PHY_BB_WD_DET_HANG 0x00000008
827#define AR_PHY_BB_WD_DET_HANG_S 3
828#define AR_PHY_BB_WD_RADAR_SM 0x000000F0
829#define AR_PHY_BB_WD_RADAR_SM_S 4
830#define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00
831#define AR_PHY_BB_WD_RX_OFDM_SM_S 8
832#define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000
833#define AR_PHY_BB_WD_RX_CCK_SM_S 12
834#define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000
835#define AR_PHY_BB_WD_TX_OFDM_SM_S 16
836#define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000
837#define AR_PHY_BB_WD_TX_CCK_SM_S 20
838#define AR_PHY_BB_WD_AGC_SM 0x0F000000
839#define AR_PHY_BB_WD_AGC_SM_S 24
840#define AR_PHY_BB_WD_SRCH_SM 0xF0000000
841#define AR_PHY_BB_WD_SRCH_SM_S 28
842
843#define AR_PHY_BB_WD_STATUS_CLR 0x00000008
844
845void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
846
847#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 83c7ea4c007f..fbb7dec6ddeb 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -114,8 +114,10 @@ enum buffer_type {
114#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) 114#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
115#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) 115#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
116 116
117#define ATH_TXSTATUS_RING_SIZE 64
118
117struct ath_descdma { 119struct ath_descdma {
118 struct ath_desc *dd_desc; 120 void *dd_desc;
119 dma_addr_t dd_desc_paddr; 121 dma_addr_t dd_desc_paddr;
120 u32 dd_desc_len; 122 u32 dd_desc_len;
121 struct ath_buf *dd_bufptr; 123 struct ath_buf *dd_bufptr;
@@ -123,7 +125,7 @@ struct ath_descdma {
123 125
124int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, 126int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
125 struct list_head *head, const char *name, 127 struct list_head *head, const char *name,
126 int nbuf, int ndesc); 128 int nbuf, int ndesc, bool is_tx);
127void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, 129void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
128 struct list_head *head); 130 struct list_head *head);
129 131
@@ -178,9 +180,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
178#define BAW_WITHIN(_start, _bawsz, _seqno) \ 180#define BAW_WITHIN(_start, _bawsz, _seqno) \
179 ((((_seqno) - (_start)) & 4095) < (_bawsz)) 181 ((((_seqno) - (_start)) & 4095) < (_bawsz))
180 182
181#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
182#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
183#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
184#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 183#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
185 184
186#define ATH_TX_COMPLETE_POLL_INT 1000 185#define ATH_TX_COMPLETE_POLL_INT 1000
@@ -191,6 +190,7 @@ enum ATH_AGGR_STATUS {
191 ATH_AGGR_LIMITED, 190 ATH_AGGR_LIMITED,
192}; 191};
193 192
193#define ATH_TXFIFO_DEPTH 8
194struct ath_txq { 194struct ath_txq {
195 u32 axq_qnum; 195 u32 axq_qnum;
196 u32 *axq_link; 196 u32 *axq_link;
@@ -200,6 +200,10 @@ struct ath_txq {
200 bool stopped; 200 bool stopped;
201 bool axq_tx_inprogress; 201 bool axq_tx_inprogress;
202 struct list_head axq_acq; 202 struct list_head axq_acq;
203 struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
204 struct list_head txq_fifo_pending;
205 u8 txq_headidx;
206 u8 txq_tailidx;
203}; 207};
204 208
205#define AGGR_CLEANUP BIT(1) 209#define AGGR_CLEANUP BIT(1)
@@ -226,6 +230,12 @@ struct ath_tx {
226 struct ath_descdma txdma; 230 struct ath_descdma txdma;
227}; 231};
228 232
233struct ath_rx_edma {
234 struct sk_buff_head rx_fifo;
235 struct sk_buff_head rx_buffers;
236 u32 rx_fifo_hwsize;
237};
238
229struct ath_rx { 239struct ath_rx {
230 u8 defant; 240 u8 defant;
231 u8 rxotherant; 241 u8 rxotherant;
@@ -235,6 +245,8 @@ struct ath_rx {
235 spinlock_t rxbuflock; 245 spinlock_t rxbuflock;
236 struct list_head rxbuf; 246 struct list_head rxbuf;
237 struct ath_descdma rxdma; 247 struct ath_descdma rxdma;
248 struct ath_buf *rx_bufptr;
249 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
238}; 250};
239 251
240int ath_startrecv(struct ath_softc *sc); 252int ath_startrecv(struct ath_softc *sc);
@@ -243,7 +255,7 @@ void ath_flushrecv(struct ath_softc *sc);
243u32 ath_calcrxfilter(struct ath_softc *sc); 255u32 ath_calcrxfilter(struct ath_softc *sc);
244int ath_rx_init(struct ath_softc *sc, int nbufs); 256int ath_rx_init(struct ath_softc *sc, int nbufs);
245void ath_rx_cleanup(struct ath_softc *sc); 257void ath_rx_cleanup(struct ath_softc *sc);
246int ath_rx_tasklet(struct ath_softc *sc, int flush); 258int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
247struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); 259struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
248void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); 260void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
249int ath_tx_setup(struct ath_softc *sc, int haltype); 261int ath_tx_setup(struct ath_softc *sc, int haltype);
@@ -261,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
261int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, 273int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
262 struct ath_tx_control *txctl); 274 struct ath_tx_control *txctl);
263void ath_tx_tasklet(struct ath_softc *sc); 275void ath_tx_tasklet(struct ath_softc *sc);
276void ath_tx_edma_tasklet(struct ath_softc *sc);
264void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); 277void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
265bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); 278bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
266void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 279void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -483,7 +496,6 @@ struct ath_softc {
483 bool ps_enabled; 496 bool ps_enabled;
484 bool ps_idle; 497 bool ps_idle;
485 unsigned long ps_usecount; 498 unsigned long ps_usecount;
486 enum ath9k_int imask;
487 499
488 struct ath_config config; 500 struct ath_config config;
489 struct ath_rx rx; 501 struct ath_rx rx;
@@ -511,6 +523,8 @@ struct ath_softc {
511 struct ath_beacon_config cur_beacon_conf; 523 struct ath_beacon_config cur_beacon_conf;
512 struct delayed_work tx_complete_work; 524 struct delayed_work tx_complete_work;
513 struct ath_btcoex btcoex; 525 struct ath_btcoex btcoex;
526
527 struct ath_descdma txsdma;
514}; 528};
515 529
516struct ath_wiphy { 530struct ath_wiphy {
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b4a31a43a62c..c8a4558f79ba 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -93,8 +93,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
93 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); 93 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
94 } 94 }
95 95
96 ds->ds_data = bf->bf_buf_addr;
97
98 sband = &sc->sbands[common->hw->conf.channel->band]; 96 sband = &sc->sbands[common->hw->conf.channel->band];
99 rate = sband->bitrates[rateidx].hw_value; 97 rate = sband->bitrates[rateidx].hw_value;
100 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 98 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
@@ -109,7 +107,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
109 107
110 /* NB: beacon's BufLen must be a multiple of 4 bytes */ 108 /* NB: beacon's BufLen must be a multiple of 4 bytes */
111 ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), 109 ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
112 true, true, ds); 110 true, true, ds, bf->bf_buf_addr,
111 sc->beacon.beaconq);
113 112
114 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); 113 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
115 series[0].Tries = 1; 114 series[0].Tries = 1;
@@ -524,6 +523,7 @@ static void ath9k_beacon_init(struct ath_softc *sc,
524static void ath_beacon_config_ap(struct ath_softc *sc, 523static void ath_beacon_config_ap(struct ath_softc *sc,
525 struct ath_beacon_config *conf) 524 struct ath_beacon_config *conf)
526{ 525{
526 struct ath_hw *ah = sc->sc_ah;
527 u32 nexttbtt, intval; 527 u32 nexttbtt, intval;
528 528
529 /* NB: the beacon interval is kept internally in TU's */ 529 /* NB: the beacon interval is kept internally in TU's */
@@ -539,15 +539,15 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
539 * prepare beacon frames. 539 * prepare beacon frames.
540 */ 540 */
541 intval |= ATH9K_BEACON_ENA; 541 intval |= ATH9K_BEACON_ENA;
542 sc->imask |= ATH9K_INT_SWBA; 542 ah->imask |= ATH9K_INT_SWBA;
543 ath_beaconq_config(sc); 543 ath_beaconq_config(sc);
544 544
545 /* Set the computed AP beacon timers */ 545 /* Set the computed AP beacon timers */
546 546
547 ath9k_hw_set_interrupts(sc->sc_ah, 0); 547 ath9k_hw_set_interrupts(ah, 0);
548 ath9k_beacon_init(sc, nexttbtt, intval); 548 ath9k_beacon_init(sc, nexttbtt, intval);
549 sc->beacon.bmisscnt = 0; 549 sc->beacon.bmisscnt = 0;
550 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 550 ath9k_hw_set_interrupts(ah, ah->imask);
551 551
552 /* Clear the reset TSF flag, so that subsequent beacon updation 552 /* Clear the reset TSF flag, so that subsequent beacon updation
553 will not reset the HW TSF. */ 553 will not reset the HW TSF. */
@@ -566,7 +566,8 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
566static void ath_beacon_config_sta(struct ath_softc *sc, 566static void ath_beacon_config_sta(struct ath_softc *sc,
567 struct ath_beacon_config *conf) 567 struct ath_beacon_config *conf)
568{ 568{
569 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 569 struct ath_hw *ah = sc->sc_ah;
570 struct ath_common *common = ath9k_hw_common(ah);
570 struct ath9k_beacon_state bs; 571 struct ath9k_beacon_state bs;
571 int dtimperiod, dtimcount, sleepduration; 572 int dtimperiod, dtimcount, sleepduration;
572 int cfpperiod, cfpcount; 573 int cfpperiod, cfpcount;
@@ -605,7 +606,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
605 * Pull nexttbtt forward to reflect the current 606 * Pull nexttbtt forward to reflect the current
606 * TSF and calculate dtim+cfp state for the result. 607 * TSF and calculate dtim+cfp state for the result.
607 */ 608 */
608 tsf = ath9k_hw_gettsf64(sc->sc_ah); 609 tsf = ath9k_hw_gettsf64(ah);
609 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 610 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
610 611
611 num_beacons = tsftu / intval + 1; 612 num_beacons = tsftu / intval + 1;
@@ -678,17 +679,18 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
678 679
679 /* Set the computed STA beacon timers */ 680 /* Set the computed STA beacon timers */
680 681
681 ath9k_hw_set_interrupts(sc->sc_ah, 0); 682 ath9k_hw_set_interrupts(ah, 0);
682 ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs); 683 ath9k_hw_set_sta_beacon_timers(ah, &bs);
683 sc->imask |= ATH9K_INT_BMISS; 684 ah->imask |= ATH9K_INT_BMISS;
684 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 685 ath9k_hw_set_interrupts(ah, ah->imask);
685} 686}
686 687
687static void ath_beacon_config_adhoc(struct ath_softc *sc, 688static void ath_beacon_config_adhoc(struct ath_softc *sc,
688 struct ath_beacon_config *conf, 689 struct ath_beacon_config *conf,
689 struct ieee80211_vif *vif) 690 struct ieee80211_vif *vif)
690{ 691{
691 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 692 struct ath_hw *ah = sc->sc_ah;
693 struct ath_common *common = ath9k_hw_common(ah);
692 u64 tsf; 694 u64 tsf;
693 u32 tsftu, intval, nexttbtt; 695 u32 tsftu, intval, nexttbtt;
694 696
@@ -703,7 +705,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
703 else if (intval) 705 else if (intval)
704 nexttbtt = roundup(nexttbtt, intval); 706 nexttbtt = roundup(nexttbtt, intval);
705 707
706 tsf = ath9k_hw_gettsf64(sc->sc_ah); 708 tsf = ath9k_hw_gettsf64(ah);
707 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; 709 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
708 do { 710 do {
709 nexttbtt += intval; 711 nexttbtt += intval;
@@ -719,20 +721,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
719 * self-linked tx descriptor and let the hardware deal with things. 721 * self-linked tx descriptor and let the hardware deal with things.
720 */ 722 */
721 intval |= ATH9K_BEACON_ENA; 723 intval |= ATH9K_BEACON_ENA;
722 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) 724 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
723 sc->imask |= ATH9K_INT_SWBA; 725 ah->imask |= ATH9K_INT_SWBA;
724 726
725 ath_beaconq_config(sc); 727 ath_beaconq_config(sc);
726 728
727 /* Set the computed ADHOC beacon timers */ 729 /* Set the computed ADHOC beacon timers */
728 730
729 ath9k_hw_set_interrupts(sc->sc_ah, 0); 731 ath9k_hw_set_interrupts(ah, 0);
730 ath9k_beacon_init(sc, nexttbtt, intval); 732 ath9k_beacon_init(sc, nexttbtt, intval);
731 sc->beacon.bmisscnt = 0; 733 sc->beacon.bmisscnt = 0;
732 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 734 ath9k_hw_set_interrupts(ah, ah->imask);
733 735
734 /* FIXME: Handle properly when vif is NULL */ 736 /* FIXME: Handle properly when vif is NULL */
735 if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) 737 if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
736 ath_beacon_start_adhoc(sc, vif); 738 ath_beacon_start_adhoc(sc, vif);
737} 739}
738 740
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 238a5744d8e9..07b8fa6fb62f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -15,6 +15,9 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h"
19
20/* Common calibration code */
18 21
19/* We can tune this as we go by monitoring really low values */ 22/* We can tune this as we go by monitoring really low values */
20#define ATH9K_NF_TOO_LOW -60 23#define ATH9K_NF_TOO_LOW -60
@@ -83,93 +86,11 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
83 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); 86 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
84 } 87 }
85 } 88 }
86 return;
87} 89}
88 90
89static void ath9k_hw_do_getnf(struct ath_hw *ah, 91static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah,
90 int16_t nfarray[NUM_NF_READINGS]) 92 enum ieee80211_band band,
91{ 93 int16_t *nft)
92 struct ath_common *common = ath9k_hw_common(ah);
93 int16_t nf;
94
95 if (AR_SREV_9280_10_OR_LATER(ah))
96 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
97 else
98 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
99
100 if (nf & 0x100)
101 nf = 0 - ((nf ^ 0x1ff) + 1);
102 ath_print(common, ATH_DBG_CALIBRATE,
103 "NF calibrated [ctl] [chain 0] is %d\n", nf);
104 nfarray[0] = nf;
105
106 if (!AR_SREV_9285(ah)) {
107 if (AR_SREV_9280_10_OR_LATER(ah))
108 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
109 AR9280_PHY_CH1_MINCCA_PWR);
110 else
111 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
112 AR_PHY_CH1_MINCCA_PWR);
113
114 if (nf & 0x100)
115 nf = 0 - ((nf ^ 0x1ff) + 1);
116 ath_print(common, ATH_DBG_CALIBRATE,
117 "NF calibrated [ctl] [chain 1] is %d\n", nf);
118 nfarray[1] = nf;
119
120 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
121 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
122 AR_PHY_CH2_MINCCA_PWR);
123 if (nf & 0x100)
124 nf = 0 - ((nf ^ 0x1ff) + 1);
125 ath_print(common, ATH_DBG_CALIBRATE,
126 "NF calibrated [ctl] [chain 2] is %d\n", nf);
127 nfarray[2] = nf;
128 }
129 }
130
131 if (AR_SREV_9280_10_OR_LATER(ah))
132 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
133 AR9280_PHY_EXT_MINCCA_PWR);
134 else
135 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
136 AR_PHY_EXT_MINCCA_PWR);
137
138 if (nf & 0x100)
139 nf = 0 - ((nf ^ 0x1ff) + 1);
140 ath_print(common, ATH_DBG_CALIBRATE,
141 "NF calibrated [ext] [chain 0] is %d\n", nf);
142 nfarray[3] = nf;
143
144 if (!AR_SREV_9285(ah)) {
145 if (AR_SREV_9280_10_OR_LATER(ah))
146 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
147 AR9280_PHY_CH1_EXT_MINCCA_PWR);
148 else
149 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
150 AR_PHY_CH1_EXT_MINCCA_PWR);
151
152 if (nf & 0x100)
153 nf = 0 - ((nf ^ 0x1ff) + 1);
154 ath_print(common, ATH_DBG_CALIBRATE,
155 "NF calibrated [ext] [chain 1] is %d\n", nf);
156 nfarray[4] = nf;
157
158 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
159 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
160 AR_PHY_CH2_EXT_MINCCA_PWR);
161 if (nf & 0x100)
162 nf = 0 - ((nf ^ 0x1ff) + 1);
163 ath_print(common, ATH_DBG_CALIBRATE,
164 "NF calibrated [ext] [chain 2] is %d\n", nf);
165 nfarray[5] = nf;
166 }
167 }
168}
169
170static bool getNoiseFloorThresh(struct ath_hw *ah,
171 enum ieee80211_band band,
172 int16_t *nft)
173{ 94{
174 switch (band) { 95 switch (band) {
175 case IEEE80211_BAND_5GHZ: 96 case IEEE80211_BAND_5GHZ:
@@ -186,44 +107,8 @@ static bool getNoiseFloorThresh(struct ath_hw *ah,
186 return true; 107 return true;
187} 108}
188 109
189static void ath9k_hw_setup_calibration(struct ath_hw *ah, 110void ath9k_hw_reset_calibration(struct ath_hw *ah,
190 struct ath9k_cal_list *currCal) 111 struct ath9k_cal_list *currCal)
191{
192 struct ath_common *common = ath9k_hw_common(ah);
193
194 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
195 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
196 currCal->calData->calCountMax);
197
198 switch (currCal->calData->calType) {
199 case IQ_MISMATCH_CAL:
200 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
201 ath_print(common, ATH_DBG_CALIBRATE,
202 "starting IQ Mismatch Calibration\n");
203 break;
204 case ADC_GAIN_CAL:
205 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
206 ath_print(common, ATH_DBG_CALIBRATE,
207 "starting ADC Gain Calibration\n");
208 break;
209 case ADC_DC_CAL:
210 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
211 ath_print(common, ATH_DBG_CALIBRATE,
212 "starting ADC DC Calibration\n");
213 break;
214 case ADC_DC_INIT_CAL:
215 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
216 ath_print(common, ATH_DBG_CALIBRATE,
217 "starting Init ADC DC Calibration\n");
218 break;
219 }
220
221 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
222 AR_PHY_TIMING_CTRL4_DO_CAL);
223}
224
225static void ath9k_hw_reset_calibration(struct ath_hw *ah,
226 struct ath9k_cal_list *currCal)
227{ 112{
228 int i; 113 int i;
229 114
@@ -241,324 +126,6 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah,
241 ah->cal_samples = 0; 126 ah->cal_samples = 0;
242} 127}
243 128
244static bool ath9k_hw_per_calibration(struct ath_hw *ah,
245 struct ath9k_channel *ichan,
246 u8 rxchainmask,
247 struct ath9k_cal_list *currCal)
248{
249 bool iscaldone = false;
250
251 if (currCal->calState == CAL_RUNNING) {
252 if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
253 AR_PHY_TIMING_CTRL4_DO_CAL)) {
254
255 currCal->calData->calCollect(ah);
256 ah->cal_samples++;
257
258 if (ah->cal_samples >= currCal->calData->calNumSamples) {
259 int i, numChains = 0;
260 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
261 if (rxchainmask & (1 << i))
262 numChains++;
263 }
264
265 currCal->calData->calPostProc(ah, numChains);
266 ichan->CalValid |= currCal->calData->calType;
267 currCal->calState = CAL_DONE;
268 iscaldone = true;
269 } else {
270 ath9k_hw_setup_calibration(ah, currCal);
271 }
272 }
273 } else if (!(ichan->CalValid & currCal->calData->calType)) {
274 ath9k_hw_reset_calibration(ah, currCal);
275 }
276
277 return iscaldone;
278}
279
280/* Assumes you are talking about the currently configured channel */
281static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
282 enum ath9k_cal_types calType)
283{
284 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
285
286 switch (calType & ah->supp_cals) {
287 case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
288 return true;
289 case ADC_GAIN_CAL:
290 case ADC_DC_CAL:
291 if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
292 conf_is_ht20(conf)))
293 return true;
294 break;
295 }
296 return false;
297}
298
299static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
300{
301 int i;
302
303 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
304 ah->totalPowerMeasI[i] +=
305 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
306 ah->totalPowerMeasQ[i] +=
307 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
308 ah->totalIqCorrMeas[i] +=
309 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
310 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
311 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
312 ah->cal_samples, i, ah->totalPowerMeasI[i],
313 ah->totalPowerMeasQ[i],
314 ah->totalIqCorrMeas[i]);
315 }
316}
317
318static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
319{
320 int i;
321
322 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
323 ah->totalAdcIOddPhase[i] +=
324 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
325 ah->totalAdcIEvenPhase[i] +=
326 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
327 ah->totalAdcQOddPhase[i] +=
328 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
329 ah->totalAdcQEvenPhase[i] +=
330 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
331
332 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
333 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
334 "oddq=0x%08x; evenq=0x%08x;\n",
335 ah->cal_samples, i,
336 ah->totalAdcIOddPhase[i],
337 ah->totalAdcIEvenPhase[i],
338 ah->totalAdcQOddPhase[i],
339 ah->totalAdcQEvenPhase[i]);
340 }
341}
342
343static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
344{
345 int i;
346
347 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
348 ah->totalAdcDcOffsetIOddPhase[i] +=
349 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
350 ah->totalAdcDcOffsetIEvenPhase[i] +=
351 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
352 ah->totalAdcDcOffsetQOddPhase[i] +=
353 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
354 ah->totalAdcDcOffsetQEvenPhase[i] +=
355 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
356
357 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
358 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
359 "oddq=0x%08x; evenq=0x%08x;\n",
360 ah->cal_samples, i,
361 ah->totalAdcDcOffsetIOddPhase[i],
362 ah->totalAdcDcOffsetIEvenPhase[i],
363 ah->totalAdcDcOffsetQOddPhase[i],
364 ah->totalAdcDcOffsetQEvenPhase[i]);
365 }
366}
367
368static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
369{
370 struct ath_common *common = ath9k_hw_common(ah);
371 u32 powerMeasQ, powerMeasI, iqCorrMeas;
372 u32 qCoffDenom, iCoffDenom;
373 int32_t qCoff, iCoff;
374 int iqCorrNeg, i;
375
376 for (i = 0; i < numChains; i++) {
377 powerMeasI = ah->totalPowerMeasI[i];
378 powerMeasQ = ah->totalPowerMeasQ[i];
379 iqCorrMeas = ah->totalIqCorrMeas[i];
380
381 ath_print(common, ATH_DBG_CALIBRATE,
382 "Starting IQ Cal and Correction for Chain %d\n",
383 i);
384
385 ath_print(common, ATH_DBG_CALIBRATE,
386 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
387 i, ah->totalIqCorrMeas[i]);
388
389 iqCorrNeg = 0;
390
391 if (iqCorrMeas > 0x80000000) {
392 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
393 iqCorrNeg = 1;
394 }
395
396 ath_print(common, ATH_DBG_CALIBRATE,
397 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
398 ath_print(common, ATH_DBG_CALIBRATE,
399 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
400 ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
401 iqCorrNeg);
402
403 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
404 qCoffDenom = powerMeasQ / 64;
405
406 if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
407 (qCoffDenom != 0)) {
408 iCoff = iqCorrMeas / iCoffDenom;
409 qCoff = powerMeasI / qCoffDenom - 64;
410 ath_print(common, ATH_DBG_CALIBRATE,
411 "Chn %d iCoff = 0x%08x\n", i, iCoff);
412 ath_print(common, ATH_DBG_CALIBRATE,
413 "Chn %d qCoff = 0x%08x\n", i, qCoff);
414
415 iCoff = iCoff & 0x3f;
416 ath_print(common, ATH_DBG_CALIBRATE,
417 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
418 if (iqCorrNeg == 0x0)
419 iCoff = 0x40 - iCoff;
420
421 if (qCoff > 15)
422 qCoff = 15;
423 else if (qCoff <= -16)
424 qCoff = 16;
425
426 ath_print(common, ATH_DBG_CALIBRATE,
427 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
428 i, iCoff, qCoff);
429
430 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
431 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
432 iCoff);
433 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
434 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
435 qCoff);
436 ath_print(common, ATH_DBG_CALIBRATE,
437 "IQ Cal and Correction done for Chain %d\n",
438 i);
439 }
440 }
441
442 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
443 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
444}
445
446static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
447{
448 struct ath_common *common = ath9k_hw_common(ah);
449 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
450 u32 qGainMismatch, iGainMismatch, val, i;
451
452 for (i = 0; i < numChains; i++) {
453 iOddMeasOffset = ah->totalAdcIOddPhase[i];
454 iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
455 qOddMeasOffset = ah->totalAdcQOddPhase[i];
456 qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
457
458 ath_print(common, ATH_DBG_CALIBRATE,
459 "Starting ADC Gain Cal for Chain %d\n", i);
460
461 ath_print(common, ATH_DBG_CALIBRATE,
462 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
463 iOddMeasOffset);
464 ath_print(common, ATH_DBG_CALIBRATE,
465 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
466 iEvenMeasOffset);
467 ath_print(common, ATH_DBG_CALIBRATE,
468 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
469 qOddMeasOffset);
470 ath_print(common, ATH_DBG_CALIBRATE,
471 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
472 qEvenMeasOffset);
473
474 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
475 iGainMismatch =
476 ((iEvenMeasOffset * 32) /
477 iOddMeasOffset) & 0x3f;
478 qGainMismatch =
479 ((qOddMeasOffset * 32) /
480 qEvenMeasOffset) & 0x3f;
481
482 ath_print(common, ATH_DBG_CALIBRATE,
483 "Chn %d gain_mismatch_i = 0x%08x\n", i,
484 iGainMismatch);
485 ath_print(common, ATH_DBG_CALIBRATE,
486 "Chn %d gain_mismatch_q = 0x%08x\n", i,
487 qGainMismatch);
488
489 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
490 val &= 0xfffff000;
491 val |= (qGainMismatch) | (iGainMismatch << 6);
492 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
493
494 ath_print(common, ATH_DBG_CALIBRATE,
495 "ADC Gain Cal done for Chain %d\n", i);
496 }
497 }
498
499 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
500 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
501 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
502}
503
504static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
505{
506 struct ath_common *common = ath9k_hw_common(ah);
507 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
508 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
509 const struct ath9k_percal_data *calData =
510 ah->cal_list_curr->calData;
511 u32 numSamples =
512 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
513
514 for (i = 0; i < numChains; i++) {
515 iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
516 iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
517 qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
518 qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
519
520 ath_print(common, ATH_DBG_CALIBRATE,
521 "Starting ADC DC Offset Cal for Chain %d\n", i);
522
523 ath_print(common, ATH_DBG_CALIBRATE,
524 "Chn %d pwr_meas_odd_i = %d\n", i,
525 iOddMeasOffset);
526 ath_print(common, ATH_DBG_CALIBRATE,
527 "Chn %d pwr_meas_even_i = %d\n", i,
528 iEvenMeasOffset);
529 ath_print(common, ATH_DBG_CALIBRATE,
530 "Chn %d pwr_meas_odd_q = %d\n", i,
531 qOddMeasOffset);
532 ath_print(common, ATH_DBG_CALIBRATE,
533 "Chn %d pwr_meas_even_q = %d\n", i,
534 qEvenMeasOffset);
535
536 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
537 numSamples) & 0x1ff;
538 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
539 numSamples) & 0x1ff;
540
541 ath_print(common, ATH_DBG_CALIBRATE,
542 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
543 iDcMismatch);
544 ath_print(common, ATH_DBG_CALIBRATE,
545 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
546 qDcMismatch);
547
548 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
549 val &= 0xc0000fff;
550 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
551 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
552
553 ath_print(common, ATH_DBG_CALIBRATE,
554 "ADC DC Offset Cal done for Chain %d\n", i);
555 }
556
557 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
558 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
559 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
560}
561
562/* This is done for the currently configured channel */ 129/* This is done for the currently configured channel */
563bool ath9k_hw_reset_calvalid(struct ath_hw *ah) 130bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
564{ 131{
@@ -605,72 +172,6 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah)
605 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 172 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
606} 173}
607 174
608void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
609{
610 struct ath9k_nfcal_hist *h;
611 int i, j;
612 int32_t val;
613 const u32 ar5416_cca_regs[6] = {
614 AR_PHY_CCA,
615 AR_PHY_CH1_CCA,
616 AR_PHY_CH2_CCA,
617 AR_PHY_EXT_CCA,
618 AR_PHY_CH1_EXT_CCA,
619 AR_PHY_CH2_EXT_CCA
620 };
621 u8 chainmask, rx_chain_status;
622
623 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
624 if (AR_SREV_9285(ah))
625 chainmask = 0x9;
626 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
627 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
628 chainmask = 0x1B;
629 else
630 chainmask = 0x09;
631 } else {
632 if (rx_chain_status & 0x4)
633 chainmask = 0x3F;
634 else if (rx_chain_status & 0x2)
635 chainmask = 0x1B;
636 else
637 chainmask = 0x09;
638 }
639
640 h = ah->nfCalHist;
641
642 for (i = 0; i < NUM_NF_READINGS; i++) {
643 if (chainmask & (1 << i)) {
644 val = REG_READ(ah, ar5416_cca_regs[i]);
645 val &= 0xFFFFFE00;
646 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
647 REG_WRITE(ah, ar5416_cca_regs[i], val);
648 }
649 }
650
651 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
652 AR_PHY_AGC_CONTROL_ENABLE_NF);
653 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
654 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
655 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
656
657 for (j = 0; j < 5; j++) {
658 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
659 AR_PHY_AGC_CONTROL_NF) == 0)
660 break;
661 udelay(50);
662 }
663
664 for (i = 0; i < NUM_NF_READINGS; i++) {
665 if (chainmask & (1 << i)) {
666 val = REG_READ(ah, ar5416_cca_regs[i]);
667 val &= 0xFFFFFE00;
668 val |= (((u32) (-50) << 1) & 0x1ff);
669 REG_WRITE(ah, ar5416_cca_regs[i], val);
670 }
671 }
672}
673
674int16_t ath9k_hw_getnf(struct ath_hw *ah, 175int16_t ath9k_hw_getnf(struct ath_hw *ah,
675 struct ath9k_channel *chan) 176 struct ath9k_channel *chan)
676{ 177{
@@ -690,7 +191,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
690 } else { 191 } else {
691 ath9k_hw_do_getnf(ah, nfarray); 192 ath9k_hw_do_getnf(ah, nfarray);
692 nf = nfarray[0]; 193 nf = nfarray[0];
693 if (getNoiseFloorThresh(ah, c->band, &nfThresh) 194 if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
694 && nf > nfThresh) { 195 && nf > nfThresh) {
695 ath_print(common, ATH_DBG_CALIBRATE, 196 ath_print(common, ATH_DBG_CALIBRATE,
696 "noise floor failed detected; " 197 "noise floor failed detected; "
@@ -715,7 +216,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
715 216
716 if (AR_SREV_9280(ah)) 217 if (AR_SREV_9280(ah))
717 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 218 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
718 else if (AR_SREV_9285(ah)) 219 else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
719 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 220 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
720 else if (AR_SREV_9287(ah)) 221 else if (AR_SREV_9287(ah))
721 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; 222 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
@@ -748,508 +249,3 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
748 return nf; 249 return nf;
749} 250}
750EXPORT_SYMBOL(ath9k_hw_getchan_noise); 251EXPORT_SYMBOL(ath9k_hw_getchan_noise);
751
752static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
753{
754 u32 rddata;
755 int32_t delta, currPDADC, slope;
756
757 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
758 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
759
760 if (ah->initPDADC == 0 || currPDADC == 0) {
761 /*
762 * Zero value indicates that no frames have been transmitted yet,
763 * can't do temperature compensation until frames are transmitted.
764 */
765 return;
766 } else {
767 slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
768
769 if (slope == 0) { /* to avoid divide by zero case */
770 delta = 0;
771 } else {
772 delta = ((currPDADC - ah->initPDADC)*4) / slope;
773 }
774 REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
775 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
776 REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
777 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
778 }
779}
780
781static void ath9k_olc_temp_compensation(struct ath_hw *ah)
782{
783 u32 rddata, i;
784 int delta, currPDADC, regval;
785
786 if (OLC_FOR_AR9287_10_LATER) {
787 ath9k_olc_temp_compensation_9287(ah);
788 } else {
789 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
790 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
791
792 if (ah->initPDADC == 0 || currPDADC == 0) {
793 return;
794 } else {
795 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
796 delta = (currPDADC - ah->initPDADC + 4) / 8;
797 else
798 delta = (currPDADC - ah->initPDADC + 5) / 10;
799
800 if (delta != ah->PDADCdelta) {
801 ah->PDADCdelta = delta;
802 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
803 regval = ah->originalGain[i] - delta;
804 if (regval < 0)
805 regval = 0;
806
807 REG_RMW_FIELD(ah,
808 AR_PHY_TX_GAIN_TBL1 + i * 4,
809 AR_PHY_TX_GAIN, regval);
810 }
811 }
812 }
813 }
814}
815
816static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset)
817{
818 u32 regVal;
819 unsigned int i;
820 u32 regList [][2] = {
821 { 0x786c, 0 },
822 { 0x7854, 0 },
823 { 0x7820, 0 },
824 { 0x7824, 0 },
825 { 0x7868, 0 },
826 { 0x783c, 0 },
827 { 0x7838, 0 } ,
828 { 0x7828, 0 } ,
829 };
830
831 for (i = 0; i < ARRAY_SIZE(regList); i++)
832 regList[i][1] = REG_READ(ah, regList[i][0]);
833
834 regVal = REG_READ(ah, 0x7834);
835 regVal &= (~(0x1));
836 REG_WRITE(ah, 0x7834, regVal);
837 regVal = REG_READ(ah, 0x9808);
838 regVal |= (0x1 << 27);
839 REG_WRITE(ah, 0x9808, regVal);
840
841 /* 786c,b23,1, pwddac=1 */
842 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
843 /* 7854, b5,1, pdrxtxbb=1 */
844 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
845 /* 7854, b7,1, pdv2i=1 */
846 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
847 /* 7854, b8,1, pddacinterface=1 */
848 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
849 /* 7824,b12,0, offcal=0 */
850 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
851 /* 7838, b1,0, pwddb=0 */
852 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
853 /* 7820,b11,0, enpacal=0 */
854 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
855 /* 7820,b25,1, pdpadrv1=0 */
856 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
857 /* 7820,b24,0, pdpadrv2=0 */
858 REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
859 /* 7820,b23,0, pdpaout=0 */
860 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
861 /* 783c,b14-16,7, padrvgn2tab_0=7 */
862 REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
863 /*
864 * 7838,b29-31,0, padrvgn1tab_0=0
865 * does not matter since we turn it off
866 */
867 REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
868
869 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
870
871 /* Set:
872 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
873 * txon=1,paon=1,oscon=1,synthon_force=1
874 */
875 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
876 udelay(30);
877 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
878
879 /* find off_6_1; */
880 for (i = 6; i > 0; i--) {
881 regVal = REG_READ(ah, 0x7834);
882 regVal |= (1 << (20 + i));
883 REG_WRITE(ah, 0x7834, regVal);
884 udelay(1);
885 //regVal = REG_READ(ah, 0x7834);
886 regVal &= (~(0x1 << (20 + i)));
887 regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
888 << (20 + i));
889 REG_WRITE(ah, 0x7834, regVal);
890 }
891
892 regVal = (regVal >>20) & 0x7f;
893
894 /* Update PA cal info */
895 if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) {
896 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
897 ah->pacal_info.max_skipcount =
898 2 * ah->pacal_info.max_skipcount;
899 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
900 } else {
901 ah->pacal_info.max_skipcount = 1;
902 ah->pacal_info.skipcount = 0;
903 ah->pacal_info.prev_offset = regVal;
904 }
905
906 regVal = REG_READ(ah, 0x7834);
907 regVal |= 0x1;
908 REG_WRITE(ah, 0x7834, regVal);
909 regVal = REG_READ(ah, 0x9808);
910 regVal &= (~(0x1 << 27));
911 REG_WRITE(ah, 0x9808, regVal);
912
913 for (i = 0; i < ARRAY_SIZE(regList); i++)
914 REG_WRITE(ah, regList[i][0], regList[i][1]);
915}
916
917static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
918{
919 struct ath_common *common = ath9k_hw_common(ah);
920 u32 regVal;
921 int i, offset, offs_6_1, offs_0;
922 u32 ccomp_org, reg_field;
923 u32 regList[][2] = {
924 { 0x786c, 0 },
925 { 0x7854, 0 },
926 { 0x7820, 0 },
927 { 0x7824, 0 },
928 { 0x7868, 0 },
929 { 0x783c, 0 },
930 { 0x7838, 0 },
931 };
932
933 ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
934
935 /* PA CAL is not needed for high power solution */
936 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
937 AR5416_EEP_TXGAIN_HIGH_POWER)
938 return;
939
940 if (AR_SREV_9285_11(ah)) {
941 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
942 udelay(10);
943 }
944
945 for (i = 0; i < ARRAY_SIZE(regList); i++)
946 regList[i][1] = REG_READ(ah, regList[i][0]);
947
948 regVal = REG_READ(ah, 0x7834);
949 regVal &= (~(0x1));
950 REG_WRITE(ah, 0x7834, regVal);
951 regVal = REG_READ(ah, 0x9808);
952 regVal |= (0x1 << 27);
953 REG_WRITE(ah, 0x9808, regVal);
954
955 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
956 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
957 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
958 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
959 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
960 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
961 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
962 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
963 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
964 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
965 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
966 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
967 ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
968 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
969
970 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
971 udelay(30);
972 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
973 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
974
975 for (i = 6; i > 0; i--) {
976 regVal = REG_READ(ah, 0x7834);
977 regVal |= (1 << (19 + i));
978 REG_WRITE(ah, 0x7834, regVal);
979 udelay(1);
980 regVal = REG_READ(ah, 0x7834);
981 regVal &= (~(0x1 << (19 + i)));
982 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
983 regVal |= (reg_field << (19 + i));
984 REG_WRITE(ah, 0x7834, regVal);
985 }
986
987 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
988 udelay(1);
989 reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
990 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
991 offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
992 offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
993
994 offset = (offs_6_1<<1) | offs_0;
995 offset = offset - 0;
996 offs_6_1 = offset>>1;
997 offs_0 = offset & 1;
998
999 if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
1000 if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
1001 ah->pacal_info.max_skipcount =
1002 2 * ah->pacal_info.max_skipcount;
1003 ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
1004 } else {
1005 ah->pacal_info.max_skipcount = 1;
1006 ah->pacal_info.skipcount = 0;
1007 ah->pacal_info.prev_offset = offset;
1008 }
1009
1010 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
1011 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
1012
1013 regVal = REG_READ(ah, 0x7834);
1014 regVal |= 0x1;
1015 REG_WRITE(ah, 0x7834, regVal);
1016 regVal = REG_READ(ah, 0x9808);
1017 regVal &= (~(0x1 << 27));
1018 REG_WRITE(ah, 0x9808, regVal);
1019
1020 for (i = 0; i < ARRAY_SIZE(regList); i++)
1021 REG_WRITE(ah, regList[i][0], regList[i][1]);
1022
1023 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
1024
1025 if (AR_SREV_9285_11(ah))
1026 REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
1027
1028}
1029
1030bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1031 u8 rxchainmask, bool longcal)
1032{
1033 bool iscaldone = true;
1034 struct ath9k_cal_list *currCal = ah->cal_list_curr;
1035
1036 if (currCal &&
1037 (currCal->calState == CAL_RUNNING ||
1038 currCal->calState == CAL_WAITING)) {
1039 iscaldone = ath9k_hw_per_calibration(ah, chan,
1040 rxchainmask, currCal);
1041 if (iscaldone) {
1042 ah->cal_list_curr = currCal = currCal->calNext;
1043
1044 if (currCal->calState == CAL_WAITING) {
1045 iscaldone = false;
1046 ath9k_hw_reset_calibration(ah, currCal);
1047 }
1048 }
1049 }
1050
1051 /* Do NF cal only at longer intervals */
1052 if (longcal) {
1053 /* Do periodic PAOffset Cal */
1054 if (AR_SREV_9271(ah))
1055 ath9k_hw_9271_pa_cal(ah, false);
1056 else if (AR_SREV_9285_11_OR_LATER(ah)) {
1057 if (!ah->pacal_info.skipcount)
1058 ath9k_hw_9285_pa_cal(ah, false);
1059 else
1060 ah->pacal_info.skipcount--;
1061 }
1062
1063 if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
1064 ath9k_olc_temp_compensation(ah);
1065
1066 /* Get the value from the previous NF cal and update history buffer */
1067 ath9k_hw_getnf(ah, chan);
1068
1069 /*
1070 * Load the NF from history buffer of the current channel.
1071 * NF is slow time-variant, so it is OK to use a historical value.
1072 */
1073 ath9k_hw_loadnf(ah, ah->curchan);
1074
1075 ath9k_hw_start_nfcal(ah);
1076 }
1077
1078 return iscaldone;
1079}
1080EXPORT_SYMBOL(ath9k_hw_calibrate);
1081
1082/* Carrier leakage Calibration fix */
1083static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
1084{
1085 struct ath_common *common = ath9k_hw_common(ah);
1086
1087 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1088 if (IS_CHAN_HT20(chan)) {
1089 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1090 REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1091 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1092 AR_PHY_AGC_CONTROL_FLTR_CAL);
1093 REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1094 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1095 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1096 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
1097 ath_print(common, ATH_DBG_CALIBRATE, "offset "
1098 "calibration failed to complete in "
1099 "1ms; noisy ??\n");
1100 return false;
1101 }
1102 REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
1103 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
1104 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1105 }
1106 REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1107 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1108 REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
1109 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
1110 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1111 0, AH_WAIT_TIMEOUT)) {
1112 ath_print(common, ATH_DBG_CALIBRATE, "offset calibration "
1113 "failed to complete in 1ms; noisy ??\n");
1114 return false;
1115 }
1116
1117 REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
1118 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1119 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
1120
1121 return true;
1122}
1123
1124bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
1125{
1126 struct ath_common *common = ath9k_hw_common(ah);
1127
1128 if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
1129 if (!ar9285_clc(ah, chan))
1130 return false;
1131 } else {
1132 if (AR_SREV_9280_10_OR_LATER(ah)) {
1133 if (!AR_SREV_9287_10_OR_LATER(ah))
1134 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
1135 AR_PHY_ADC_CTL_OFF_PWDADC);
1136 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1137 AR_PHY_AGC_CONTROL_FLTR_CAL);
1138 }
1139
1140 /* Calibrate the AGC */
1141 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1142 REG_READ(ah, AR_PHY_AGC_CONTROL) |
1143 AR_PHY_AGC_CONTROL_CAL);
1144
1145 /* Poll for offset calibration complete */
1146 if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
1147 0, AH_WAIT_TIMEOUT)) {
1148 ath_print(common, ATH_DBG_CALIBRATE,
1149 "offset calibration failed to "
1150 "complete in 1ms; noisy environment?\n");
1151 return false;
1152 }
1153
1154 if (AR_SREV_9280_10_OR_LATER(ah)) {
1155 if (!AR_SREV_9287_10_OR_LATER(ah))
1156 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
1157 AR_PHY_ADC_CTL_OFF_PWDADC);
1158 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1159 AR_PHY_AGC_CONTROL_FLTR_CAL);
1160 }
1161 }
1162
1163 /* Do PA Calibration */
1164 if (AR_SREV_9271(ah))
1165 ath9k_hw_9271_pa_cal(ah, true);
1166 else if (AR_SREV_9285_11_OR_LATER(ah))
1167 ath9k_hw_9285_pa_cal(ah, true);
1168
1169 /* Do NF Calibration after DC offset and other calibrations */
1170 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1171 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
1172
1173 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1174
1175 /* Enable IQ, ADC Gain and ADC DC offset CALs */
1176 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
1177 if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
1178 INIT_CAL(&ah->adcgain_caldata);
1179 INSERT_CAL(ah, &ah->adcgain_caldata);
1180 ath_print(common, ATH_DBG_CALIBRATE,
1181 "enabling ADC Gain Calibration.\n");
1182 }
1183 if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
1184 INIT_CAL(&ah->adcdc_caldata);
1185 INSERT_CAL(ah, &ah->adcdc_caldata);
1186 ath_print(common, ATH_DBG_CALIBRATE,
1187 "enabling ADC DC Calibration.\n");
1188 }
1189 if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
1190 INIT_CAL(&ah->iq_caldata);
1191 INSERT_CAL(ah, &ah->iq_caldata);
1192 ath_print(common, ATH_DBG_CALIBRATE,
1193 "enabling IQ Calibration.\n");
1194 }
1195
1196 ah->cal_list_curr = ah->cal_list;
1197
1198 if (ah->cal_list_curr)
1199 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1200 }
1201
1202 chan->CalValid = 0;
1203
1204 return true;
1205}
1206
1207const struct ath9k_percal_data iq_cal_multi_sample = {
1208 IQ_MISMATCH_CAL,
1209 MAX_CAL_SAMPLES,
1210 PER_MIN_LOG_COUNT,
1211 ath9k_hw_iqcal_collect,
1212 ath9k_hw_iqcalibrate
1213};
1214const struct ath9k_percal_data iq_cal_single_sample = {
1215 IQ_MISMATCH_CAL,
1216 MIN_CAL_SAMPLES,
1217 PER_MAX_LOG_COUNT,
1218 ath9k_hw_iqcal_collect,
1219 ath9k_hw_iqcalibrate
1220};
1221const struct ath9k_percal_data adc_gain_cal_multi_sample = {
1222 ADC_GAIN_CAL,
1223 MAX_CAL_SAMPLES,
1224 PER_MIN_LOG_COUNT,
1225 ath9k_hw_adc_gaincal_collect,
1226 ath9k_hw_adc_gaincal_calibrate
1227};
1228const struct ath9k_percal_data adc_gain_cal_single_sample = {
1229 ADC_GAIN_CAL,
1230 MIN_CAL_SAMPLES,
1231 PER_MAX_LOG_COUNT,
1232 ath9k_hw_adc_gaincal_collect,
1233 ath9k_hw_adc_gaincal_calibrate
1234};
1235const struct ath9k_percal_data adc_dc_cal_multi_sample = {
1236 ADC_DC_CAL,
1237 MAX_CAL_SAMPLES,
1238 PER_MIN_LOG_COUNT,
1239 ath9k_hw_adc_dccal_collect,
1240 ath9k_hw_adc_dccal_calibrate
1241};
1242const struct ath9k_percal_data adc_dc_cal_single_sample = {
1243 ADC_DC_CAL,
1244 MIN_CAL_SAMPLES,
1245 PER_MAX_LOG_COUNT,
1246 ath9k_hw_adc_dccal_collect,
1247 ath9k_hw_adc_dccal_calibrate
1248};
1249const struct ath9k_percal_data adc_init_dc_cal = {
1250 ADC_DC_INIT_CAL,
1251 MIN_CAL_SAMPLES,
1252 INIT_LOG_COUNT,
1253 ath9k_hw_adc_dccal_collect,
1254 ath9k_hw_adc_dccal_calibrate
1255};
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b2c873e97485..24538bdb9126 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -19,14 +19,6 @@
19 19
20#include "hw.h" 20#include "hw.h"
21 21
22extern const struct ath9k_percal_data iq_cal_multi_sample;
23extern const struct ath9k_percal_data iq_cal_single_sample;
24extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
25extern const struct ath9k_percal_data adc_gain_cal_single_sample;
26extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
27extern const struct ath9k_percal_data adc_dc_cal_single_sample;
28extern const struct ath9k_percal_data adc_init_dc_cal;
29
30#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85 22#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
31#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112 23#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
32#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118 24#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
@@ -76,7 +68,8 @@ enum ath9k_cal_types {
76 ADC_DC_INIT_CAL = 0x1, 68 ADC_DC_INIT_CAL = 0x1,
77 ADC_GAIN_CAL = 0x2, 69 ADC_GAIN_CAL = 0x2,
78 ADC_DC_CAL = 0x4, 70 ADC_DC_CAL = 0x4,
79 IQ_MISMATCH_CAL = 0x8 71 IQ_MISMATCH_CAL = 0x8,
72 TEMP_COMP_CAL = 0x10,
80}; 73};
81 74
82enum ath9k_cal_state { 75enum ath9k_cal_state {
@@ -122,14 +115,12 @@ struct ath9k_pacal_info{
122 115
123bool ath9k_hw_reset_calvalid(struct ath_hw *ah); 116bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
124void ath9k_hw_start_nfcal(struct ath_hw *ah); 117void ath9k_hw_start_nfcal(struct ath_hw *ah);
125void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
126int16_t ath9k_hw_getnf(struct ath_hw *ah, 118int16_t ath9k_hw_getnf(struct ath_hw *ah,
127 struct ath9k_channel *chan); 119 struct ath9k_channel *chan);
128void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); 120void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
129s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); 121s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
130bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, 122void ath9k_hw_reset_calibration(struct ath_hw *ah,
131 u8 rxchainmask, bool longcal); 123 struct ath9k_cal_list *currCal);
132bool ath9k_hw_init_cal(struct ath_hw *ah, 124
133 struct ath9k_channel *chan);
134 125
135#endif /* CALIB_H */ 126#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4d775ae141db..7707341cd0d3 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -57,13 +57,19 @@ static bool ath9k_rx_accept(struct ath_common *common,
57 * rs_more indicates chained descriptors which can be used 57 * rs_more indicates chained descriptors which can be used
58 * to link buffers together for a sort of scatter-gather 58 * to link buffers together for a sort of scatter-gather
59 * operation. 59 * operation.
60 * 60 * reject the frame, we don't support scatter-gather yet and
61 * the frame is probably corrupt anyway
62 */
63 if (rx_stats->rs_more)
64 return false;
65
66 /*
61 * The rx_stats->rs_status will not be set until the end of the 67 * The rx_stats->rs_status will not be set until the end of the
62 * chained descriptors so it can be ignored if rs_more is set. The 68 * chained descriptors so it can be ignored if rs_more is set. The
63 * rs_more will be false at the last element of the chained 69 * rs_more will be false at the last element of the chained
64 * descriptors. 70 * descriptors.
65 */ 71 */
66 if (!rx_stats->rs_more && rx_stats->rs_status != 0) { 72 if (rx_stats->rs_status != 0) {
67 if (rx_stats->rs_status & ATH9K_RXERR_CRC) 73 if (rx_stats->rs_status & ATH9K_RXERR_CRC)
68 rxs->flag |= RX_FLAG_FAILED_FCS_CRC; 74 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
69 if (rx_stats->rs_status & ATH9K_RXERR_PHY) 75 if (rx_stats->rs_status & ATH9K_RXERR_PHY)
@@ -102,11 +108,11 @@ static bool ath9k_rx_accept(struct ath_common *common,
102 return true; 108 return true;
103} 109}
104 110
105static u8 ath9k_process_rate(struct ath_common *common, 111static int ath9k_process_rate(struct ath_common *common,
106 struct ieee80211_hw *hw, 112 struct ieee80211_hw *hw,
107 struct ath_rx_status *rx_stats, 113 struct ath_rx_status *rx_stats,
108 struct ieee80211_rx_status *rxs, 114 struct ieee80211_rx_status *rxs,
109 struct sk_buff *skb) 115 struct sk_buff *skb)
110{ 116{
111 struct ieee80211_supported_band *sband; 117 struct ieee80211_supported_band *sband;
112 enum ieee80211_band band; 118 enum ieee80211_band band;
@@ -122,25 +128,32 @@ static u8 ath9k_process_rate(struct ath_common *common,
122 rxs->flag |= RX_FLAG_40MHZ; 128 rxs->flag |= RX_FLAG_40MHZ;
123 if (rx_stats->rs_flags & ATH9K_RX_GI) 129 if (rx_stats->rs_flags & ATH9K_RX_GI)
124 rxs->flag |= RX_FLAG_SHORT_GI; 130 rxs->flag |= RX_FLAG_SHORT_GI;
125 return rx_stats->rs_rate & 0x7f; 131 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
132 return 0;
126 } 133 }
127 134
128 for (i = 0; i < sband->n_bitrates; i++) { 135 for (i = 0; i < sband->n_bitrates; i++) {
129 if (sband->bitrates[i].hw_value == rx_stats->rs_rate) 136 if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
130 return i; 137 rxs->rate_idx = i;
138 return 0;
139 }
131 if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { 140 if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
132 rxs->flag |= RX_FLAG_SHORTPRE; 141 rxs->flag |= RX_FLAG_SHORTPRE;
133 return i; 142 rxs->rate_idx = i;
143 return 0;
134 } 144 }
135 } 145 }
136 146
137 /* No valid hardware bitrate found -- we should not get here */ 147 /*
148 * No valid hardware bitrate found -- we should not get here
149 * because hardware has already validated this frame as OK.
150 */
138 ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " 151 ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
139 "0x%02x using 1 Mbit\n", rx_stats->rs_rate); 152 "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
140 if ((common->debug_mask & ATH_DBG_XMIT)) 153 if ((common->debug_mask & ATH_DBG_XMIT))
141 print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); 154 print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len);
142 155
143 return 0; 156 return -EINVAL;
144} 157}
145 158
146static void ath9k_process_rssi(struct ath_common *common, 159static void ath9k_process_rssi(struct ath_common *common,
@@ -202,17 +215,22 @@ int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
202 struct ath_hw *ah = common->ah; 215 struct ath_hw *ah = common->ah;
203 216
204 memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); 217 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
218
219 /*
220 * everything but the rate is checked here, the rate check is done
221 * separately to avoid doing two lookups for a rate for each frame.
222 */
205 if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) 223 if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error))
206 return -EINVAL; 224 return -EINVAL;
207 225
208 ath9k_process_rssi(common, hw, skb, rx_stats); 226 ath9k_process_rssi(common, hw, skb, rx_stats);
209 227
210 rx_status->rate_idx = ath9k_process_rate(common, hw, 228 if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb))
211 rx_stats, rx_status, skb); 229 return -EINVAL;
230
212 rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); 231 rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp);
213 rx_status->band = hw->conf.channel->band; 232 rx_status->band = hw->conf.channel->band;
214 rx_status->freq = hw->conf.channel->center_freq; 233 rx_status->freq = hw->conf.channel->center_freq;
215 rx_status->noise = common->ani.noise_floor;
216 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; 234 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
217 rx_status->antenna = rx_stats->rs_antenna; 235 rx_status->antenna = rx_stats->rs_antenna;
218 rx_status->flag |= RX_FLAG_TSFT; 236 rx_status->flag |= RX_FLAG_TSFT;
@@ -255,7 +273,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
255 273
256 keyix = rx_stats->rs_keyix; 274 keyix = rx_stats->rs_keyix;
257 275
258 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { 276 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
277 ieee80211_has_protected(fc)) {
259 rxs->flag |= RX_FLAG_DECRYPTED; 278 rxs->flag |= RX_FLAG_DECRYPTED;
260 } else if (ieee80211_has_protected(fc) 279 } else if (ieee80211_has_protected(fc)
261 && !decrypt_error && skb->len >= hdrlen + 4) { 280 && !decrypt_error && skb->len >= hdrlen + 4) {
@@ -286,6 +305,345 @@ int ath9k_cmn_padpos(__le16 frame_control)
286} 305}
287EXPORT_SYMBOL(ath9k_cmn_padpos); 306EXPORT_SYMBOL(ath9k_cmn_padpos);
288 307
308int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
309{
310 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
311
312 if (tx_info->control.hw_key) {
313 if (tx_info->control.hw_key->alg == ALG_WEP)
314 return ATH9K_KEY_TYPE_WEP;
315 else if (tx_info->control.hw_key->alg == ALG_TKIP)
316 return ATH9K_KEY_TYPE_TKIP;
317 else if (tx_info->control.hw_key->alg == ALG_CCMP)
318 return ATH9K_KEY_TYPE_AES;
319 }
320
321 return ATH9K_KEY_TYPE_CLEAR;
322}
323EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
324
325static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
326 enum nl80211_channel_type channel_type)
327{
328 u32 chanmode = 0;
329
330 switch (chan->band) {
331 case IEEE80211_BAND_2GHZ:
332 switch (channel_type) {
333 case NL80211_CHAN_NO_HT:
334 case NL80211_CHAN_HT20:
335 chanmode = CHANNEL_G_HT20;
336 break;
337 case NL80211_CHAN_HT40PLUS:
338 chanmode = CHANNEL_G_HT40PLUS;
339 break;
340 case NL80211_CHAN_HT40MINUS:
341 chanmode = CHANNEL_G_HT40MINUS;
342 break;
343 }
344 break;
345 case IEEE80211_BAND_5GHZ:
346 switch (channel_type) {
347 case NL80211_CHAN_NO_HT:
348 case NL80211_CHAN_HT20:
349 chanmode = CHANNEL_A_HT20;
350 break;
351 case NL80211_CHAN_HT40PLUS:
352 chanmode = CHANNEL_A_HT40PLUS;
353 break;
354 case NL80211_CHAN_HT40MINUS:
355 chanmode = CHANNEL_A_HT40MINUS;
356 break;
357 }
358 break;
359 default:
360 break;
361 }
362
363 return chanmode;
364}
365
366/*
367 * Update internal channel flags.
368 */
369void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
370 struct ath9k_channel *ichan)
371{
372 struct ieee80211_channel *chan = hw->conf.channel;
373 struct ieee80211_conf *conf = &hw->conf;
374
375 ichan->channel = chan->center_freq;
376 ichan->chan = chan;
377
378 if (chan->band == IEEE80211_BAND_2GHZ) {
379 ichan->chanmode = CHANNEL_G;
380 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
381 } else {
382 ichan->chanmode = CHANNEL_A;
383 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
384 }
385
386 if (conf_is_ht(conf))
387 ichan->chanmode = ath9k_get_extchanmode(chan,
388 conf->channel_type);
389}
390EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
391
392/*
393 * Get the internal channel reference.
394 */
395struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
396 struct ath_hw *ah)
397{
398 struct ieee80211_channel *curchan = hw->conf.channel;
399 struct ath9k_channel *channel;
400 u8 chan_idx;
401
402 chan_idx = curchan->hw_value;
403 channel = &ah->channels[chan_idx];
404 ath9k_cmn_update_ichannel(hw, channel);
405
406 return channel;
407}
408EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
409
410static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
411 struct ath9k_keyval *hk, const u8 *addr,
412 bool authenticator)
413{
414 struct ath_hw *ah = common->ah;
415 const u8 *key_rxmic;
416 const u8 *key_txmic;
417
418 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
419 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
420
421 if (addr == NULL) {
422 /*
423 * Group key installation - only two key cache entries are used
424 * regardless of splitmic capability since group key is only
425 * used either for TX or RX.
426 */
427 if (authenticator) {
428 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
429 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
430 } else {
431 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
432 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
433 }
434 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
435 }
436 if (!common->splitmic) {
437 /* TX and RX keys share the same key cache entry. */
438 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
439 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
440 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
441 }
442
443 /* Separate key cache entries for TX and RX */
444
445 /* TX key goes at first index, RX key at +32. */
446 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
447 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
448 /* TX MIC entry failed. No need to proceed further */
449 ath_print(common, ATH_DBG_FATAL,
450 "Setting TX MIC Key Failed\n");
451 return 0;
452 }
453
454 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
455 /* XXX delete tx key on failure? */
456 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
457}
458
459static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
460{
461 int i;
462
463 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
464 if (test_bit(i, common->keymap) ||
465 test_bit(i + 64, common->keymap))
466 continue; /* At least one part of TKIP key allocated */
467 if (common->splitmic &&
468 (test_bit(i + 32, common->keymap) ||
469 test_bit(i + 64 + 32, common->keymap)))
470 continue; /* At least one part of TKIP key allocated */
471
472 /* Found a free slot for a TKIP key */
473 return i;
474 }
475 return -1;
476}
477
478static int ath_reserve_key_cache_slot(struct ath_common *common)
479{
480 int i;
481
482 /* First, try to find slots that would not be available for TKIP. */
483 if (common->splitmic) {
484 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
485 if (!test_bit(i, common->keymap) &&
486 (test_bit(i + 32, common->keymap) ||
487 test_bit(i + 64, common->keymap) ||
488 test_bit(i + 64 + 32, common->keymap)))
489 return i;
490 if (!test_bit(i + 32, common->keymap) &&
491 (test_bit(i, common->keymap) ||
492 test_bit(i + 64, common->keymap) ||
493 test_bit(i + 64 + 32, common->keymap)))
494 return i + 32;
495 if (!test_bit(i + 64, common->keymap) &&
496 (test_bit(i , common->keymap) ||
497 test_bit(i + 32, common->keymap) ||
498 test_bit(i + 64 + 32, common->keymap)))
499 return i + 64;
500 if (!test_bit(i + 64 + 32, common->keymap) &&
501 (test_bit(i, common->keymap) ||
502 test_bit(i + 32, common->keymap) ||
503 test_bit(i + 64, common->keymap)))
504 return i + 64 + 32;
505 }
506 } else {
507 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
508 if (!test_bit(i, common->keymap) &&
509 test_bit(i + 64, common->keymap))
510 return i;
511 if (test_bit(i, common->keymap) &&
512 !test_bit(i + 64, common->keymap))
513 return i + 64;
514 }
515 }
516
517 /* No partially used TKIP slots, pick any available slot */
518 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
519 /* Do not allow slots that could be needed for TKIP group keys
520 * to be used. This limitation could be removed if we know that
521 * TKIP will not be used. */
522 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
523 continue;
524 if (common->splitmic) {
525 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
526 continue;
527 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
528 continue;
529 }
530
531 if (!test_bit(i, common->keymap))
532 return i; /* Found a free slot for a key */
533 }
534
535 /* No free slot found */
536 return -1;
537}
538
539/*
540 * Configure encryption in the HW.
541 */
542int ath9k_cmn_key_config(struct ath_common *common,
543 struct ieee80211_vif *vif,
544 struct ieee80211_sta *sta,
545 struct ieee80211_key_conf *key)
546{
547 struct ath_hw *ah = common->ah;
548 struct ath9k_keyval hk;
549 const u8 *mac = NULL;
550 int ret = 0;
551 int idx;
552
553 memset(&hk, 0, sizeof(hk));
554
555 switch (key->alg) {
556 case ALG_WEP:
557 hk.kv_type = ATH9K_CIPHER_WEP;
558 break;
559 case ALG_TKIP:
560 hk.kv_type = ATH9K_CIPHER_TKIP;
561 break;
562 case ALG_CCMP:
563 hk.kv_type = ATH9K_CIPHER_AES_CCM;
564 break;
565 default:
566 return -EOPNOTSUPP;
567 }
568
569 hk.kv_len = key->keylen;
570 memcpy(hk.kv_val, key->key, key->keylen);
571
572 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
573 /* For now, use the default keys for broadcast keys. This may
574 * need to change with virtual interfaces. */
575 idx = key->keyidx;
576 } else if (key->keyidx) {
577 if (WARN_ON(!sta))
578 return -EOPNOTSUPP;
579 mac = sta->addr;
580
581 if (vif->type != NL80211_IFTYPE_AP) {
582 /* Only keyidx 0 should be used with unicast key, but
583 * allow this for client mode for now. */
584 idx = key->keyidx;
585 } else
586 return -EIO;
587 } else {
588 if (WARN_ON(!sta))
589 return -EOPNOTSUPP;
590 mac = sta->addr;
591
592 if (key->alg == ALG_TKIP)
593 idx = ath_reserve_key_cache_slot_tkip(common);
594 else
595 idx = ath_reserve_key_cache_slot(common);
596 if (idx < 0)
597 return -ENOSPC; /* no free key cache entries */
598 }
599
600 if (key->alg == ALG_TKIP)
601 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
602 vif->type == NL80211_IFTYPE_AP);
603 else
604 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
605
606 if (!ret)
607 return -EIO;
608
609 set_bit(idx, common->keymap);
610 if (key->alg == ALG_TKIP) {
611 set_bit(idx + 64, common->keymap);
612 if (common->splitmic) {
613 set_bit(idx + 32, common->keymap);
614 set_bit(idx + 64 + 32, common->keymap);
615 }
616 }
617
618 return idx;
619}
620EXPORT_SYMBOL(ath9k_cmn_key_config);
621
622/*
623 * Delete Key.
624 */
625void ath9k_cmn_key_delete(struct ath_common *common,
626 struct ieee80211_key_conf *key)
627{
628 struct ath_hw *ah = common->ah;
629
630 ath9k_hw_keyreset(ah, key->hw_key_idx);
631 if (key->hw_key_idx < IEEE80211_WEP_NKID)
632 return;
633
634 clear_bit(key->hw_key_idx, common->keymap);
635 if (key->alg != ALG_TKIP)
636 return;
637
638 clear_bit(key->hw_key_idx + 64, common->keymap);
639 if (common->splitmic) {
640 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
641 clear_bit(key->hw_key_idx + 32, common->keymap);
642 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
643 }
644}
645EXPORT_SYMBOL(ath9k_cmn_key_delete);
646
289static int __init ath9k_cmn_init(void) 647static int __init ath9k_cmn_init(void)
290{ 648{
291 return 0; 649 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 042999c2fe9c..e08f7e5a26e0 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -20,9 +20,12 @@
20#include "../debug.h" 20#include "../debug.h"
21 21
22#include "hw.h" 22#include "hw.h"
23#include "hw-ops.h"
23 24
24/* Common header for Atheros 802.11n base driver cores */ 25/* Common header for Atheros 802.11n base driver cores */
25 26
27#define IEEE80211_WEP_NKID 4
28
26#define WME_NUM_TID 16 29#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 30#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 31#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -74,11 +77,12 @@ struct ath_buf {
74 an aggregate) */ 77 an aggregate) */
75 struct ath_buf *bf_next; /* next subframe in the aggregate */ 78 struct ath_buf *bf_next; /* next subframe in the aggregate */
76 struct sk_buff *bf_mpdu; /* enclosing frame structure */ 79 struct sk_buff *bf_mpdu; /* enclosing frame structure */
77 struct ath_desc *bf_desc; /* virtual addr of desc */ 80 void *bf_desc; /* virtual addr of desc */
78 dma_addr_t bf_daddr; /* physical addr of desc */ 81 dma_addr_t bf_daddr; /* physical addr of desc */
79 dma_addr_t bf_buf_addr; /* physical addr of data buffer */ 82 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
80 bool bf_stale; 83 bool bf_stale;
81 bool bf_isnullfunc; 84 bool bf_isnullfunc;
85 bool bf_tx_aborted;
82 u16 bf_flags; 86 u16 bf_flags;
83 struct ath_buf_state bf_state; 87 struct ath_buf_state bf_state;
84 dma_addr_t bf_dmacontext; 88 dma_addr_t bf_dmacontext;
@@ -125,3 +129,14 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
125 bool decrypt_error); 129 bool decrypt_error);
126 130
127int ath9k_cmn_padpos(__le16 frame_control); 131int ath9k_cmn_padpos(__le16 frame_control);
132int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
133void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
134 struct ath9k_channel *ichan);
135struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
136 struct ath_hw *ah);
137int ath9k_cmn_key_config(struct ath_common *common,
138 struct ieee80211_vif *vif,
139 struct ieee80211_sta *sta,
140 struct ieee80211_key_conf *key);
141void ath9k_cmn_key_delete(struct ath_common *common,
142 struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 081e0085ed4c..29898f8d1893 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -78,6 +78,90 @@ static const struct file_operations fops_debug = {
78 78
79#define DMA_BUF_LEN 1024 79#define DMA_BUF_LEN 1024
80 80
81static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
82 size_t count, loff_t *ppos)
83{
84 struct ath_softc *sc = file->private_data;
85 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
86 char buf[32];
87 unsigned int len;
88
89 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask);
90 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
91}
92
93static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf,
94 size_t count, loff_t *ppos)
95{
96 struct ath_softc *sc = file->private_data;
97 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
98 unsigned long mask;
99 char buf[32];
100 ssize_t len;
101
102 len = min(count, sizeof(buf) - 1);
103 if (copy_from_user(buf, user_buf, len))
104 return -EINVAL;
105
106 buf[len] = '\0';
107 if (strict_strtoul(buf, 0, &mask))
108 return -EINVAL;
109
110 common->tx_chainmask = mask;
111 sc->sc_ah->caps.tx_chainmask = mask;
112 return count;
113}
114
115static const struct file_operations fops_tx_chainmask = {
116 .read = read_file_tx_chainmask,
117 .write = write_file_tx_chainmask,
118 .open = ath9k_debugfs_open,
119 .owner = THIS_MODULE
120};
121
122
123static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
124 size_t count, loff_t *ppos)
125{
126 struct ath_softc *sc = file->private_data;
127 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
128 char buf[32];
129 unsigned int len;
130
131 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask);
132 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
133}
134
135static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf,
136 size_t count, loff_t *ppos)
137{
138 struct ath_softc *sc = file->private_data;
139 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
140 unsigned long mask;
141 char buf[32];
142 ssize_t len;
143
144 len = min(count, sizeof(buf) - 1);
145 if (copy_from_user(buf, user_buf, len))
146 return -EINVAL;
147
148 buf[len] = '\0';
149 if (strict_strtoul(buf, 0, &mask))
150 return -EINVAL;
151
152 common->rx_chainmask = mask;
153 sc->sc_ah->caps.rx_chainmask = mask;
154 return count;
155}
156
157static const struct file_operations fops_rx_chainmask = {
158 .read = read_file_rx_chainmask,
159 .write = write_file_rx_chainmask,
160 .open = ath9k_debugfs_open,
161 .owner = THIS_MODULE
162};
163
164
81static ssize_t read_file_dma(struct file *file, char __user *user_buf, 165static ssize_t read_file_dma(struct file *file, char __user *user_buf,
82 size_t count, loff_t *ppos) 166 size_t count, loff_t *ppos)
83{ 167{
@@ -157,10 +241,10 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
157 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 241 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
158 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 242 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
159 243
160 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n", 244 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n",
161 REG_READ_D(ah, AR_OBS_BUS_1)); 245 REG_READ_D(ah, AR_OBS_BUS_1));
162 len += snprintf(buf + len, DMA_BUF_LEN - len, 246 len += snprintf(buf + len, DMA_BUF_LEN - len,
163 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); 247 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR));
164 248
165 ath9k_ps_restore(sc); 249 ath9k_ps_restore(sc);
166 250
@@ -180,8 +264,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
180{ 264{
181 if (status) 265 if (status)
182 sc->debug.stats.istats.total++; 266 sc->debug.stats.istats.total++;
183 if (status & ATH9K_INT_RX) 267 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
184 sc->debug.stats.istats.rxok++; 268 if (status & ATH9K_INT_RXLP)
269 sc->debug.stats.istats.rxlp++;
270 if (status & ATH9K_INT_RXHP)
271 sc->debug.stats.istats.rxhp++;
272 } else {
273 if (status & ATH9K_INT_RX)
274 sc->debug.stats.istats.rxok++;
275 }
185 if (status & ATH9K_INT_RXEOL) 276 if (status & ATH9K_INT_RXEOL)
186 sc->debug.stats.istats.rxeol++; 277 sc->debug.stats.istats.rxeol++;
187 if (status & ATH9K_INT_RXORN) 278 if (status & ATH9K_INT_RXORN)
@@ -223,8 +314,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
223 char buf[512]; 314 char buf[512];
224 unsigned int len = 0; 315 unsigned int len = 0;
225 316
226 len += snprintf(buf + len, sizeof(buf) - len, 317 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
227 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); 318 len += snprintf(buf + len, sizeof(buf) - len,
319 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
320 len += snprintf(buf + len, sizeof(buf) - len,
321 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
322 } else {
323 len += snprintf(buf + len, sizeof(buf) - len,
324 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
325 }
228 len += snprintf(buf + len, sizeof(buf) - len, 326 len += snprintf(buf + len, sizeof(buf) - len,
229 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); 327 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
230 len += snprintf(buf + len, sizeof(buf) - len, 328 len += snprintf(buf + len, sizeof(buf) - len,
@@ -557,10 +655,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
557} 655}
558 656
559void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 657void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
560 struct ath_buf *bf) 658 struct ath_buf *bf, struct ath_tx_status *ts)
561{ 659{
562 struct ath_desc *ds = bf->bf_desc;
563
564 if (bf_isampdu(bf)) { 660 if (bf_isampdu(bf)) {
565 if (bf_isxretried(bf)) 661 if (bf_isxretried(bf))
566 TX_STAT_INC(txq->axq_qnum, a_xretries); 662 TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -570,17 +666,17 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
570 TX_STAT_INC(txq->axq_qnum, completed); 666 TX_STAT_INC(txq->axq_qnum, completed);
571 } 667 }
572 668
573 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO) 669 if (ts->ts_status & ATH9K_TXERR_FIFO)
574 TX_STAT_INC(txq->axq_qnum, fifo_underrun); 670 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
575 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP) 671 if (ts->ts_status & ATH9K_TXERR_XTXOP)
576 TX_STAT_INC(txq->axq_qnum, xtxop); 672 TX_STAT_INC(txq->axq_qnum, xtxop);
577 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED) 673 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
578 TX_STAT_INC(txq->axq_qnum, timer_exp); 674 TX_STAT_INC(txq->axq_qnum, timer_exp);
579 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR) 675 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
580 TX_STAT_INC(txq->axq_qnum, desc_cfg_err); 676 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
581 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN) 677 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
582 TX_STAT_INC(txq->axq_qnum, data_underrun); 678 TX_STAT_INC(txq->axq_qnum, data_underrun);
583 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN) 679 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
584 TX_STAT_INC(txq->axq_qnum, delim_underrun); 680 TX_STAT_INC(txq->axq_qnum, delim_underrun);
585} 681}
586 682
@@ -663,30 +759,29 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
663#undef PHY_ERR 759#undef PHY_ERR
664} 760}
665 761
666void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) 762void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
667{ 763{
668#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ 764#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
669#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 765#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
670 766
671 struct ath_desc *ds = bf->bf_desc;
672 u32 phyerr; 767 u32 phyerr;
673 768
674 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) 769 if (rs->rs_status & ATH9K_RXERR_CRC)
675 RX_STAT_INC(crc_err); 770 RX_STAT_INC(crc_err);
676 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) 771 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
677 RX_STAT_INC(decrypt_crc_err); 772 RX_STAT_INC(decrypt_crc_err);
678 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) 773 if (rs->rs_status & ATH9K_RXERR_MIC)
679 RX_STAT_INC(mic_err); 774 RX_STAT_INC(mic_err);
680 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) 775 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
681 RX_STAT_INC(pre_delim_crc_err); 776 RX_STAT_INC(pre_delim_crc_err);
682 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) 777 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
683 RX_STAT_INC(post_delim_crc_err); 778 RX_STAT_INC(post_delim_crc_err);
684 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) 779 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
685 RX_STAT_INC(decrypt_busy_err); 780 RX_STAT_INC(decrypt_busy_err);
686 781
687 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { 782 if (rs->rs_status & ATH9K_RXERR_PHY) {
688 RX_STAT_INC(phy_err); 783 RX_STAT_INC(phy_err);
689 phyerr = ds->ds_rxstat.rs_phyerr & 0x24; 784 phyerr = rs->rs_phyerr & 0x24;
690 RX_PHY_ERR_INC(phyerr); 785 RX_PHY_ERR_INC(phyerr);
691 } 786 }
692 787
@@ -700,6 +795,86 @@ static const struct file_operations fops_recv = {
700 .owner = THIS_MODULE 795 .owner = THIS_MODULE
701}; 796};
702 797
798static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
799 size_t count, loff_t *ppos)
800{
801 struct ath_softc *sc = file->private_data;
802 char buf[32];
803 unsigned int len;
804
805 len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx);
806 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
807}
808
809static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
810 size_t count, loff_t *ppos)
811{
812 struct ath_softc *sc = file->private_data;
813 unsigned long regidx;
814 char buf[32];
815 ssize_t len;
816
817 len = min(count, sizeof(buf) - 1);
818 if (copy_from_user(buf, user_buf, len))
819 return -EINVAL;
820
821 buf[len] = '\0';
822 if (strict_strtoul(buf, 0, &regidx))
823 return -EINVAL;
824
825 sc->debug.regidx = regidx;
826 return count;
827}
828
829static const struct file_operations fops_regidx = {
830 .read = read_file_regidx,
831 .write = write_file_regidx,
832 .open = ath9k_debugfs_open,
833 .owner = THIS_MODULE
834};
835
836static ssize_t read_file_regval(struct file *file, char __user *user_buf,
837 size_t count, loff_t *ppos)
838{
839 struct ath_softc *sc = file->private_data;
840 struct ath_hw *ah = sc->sc_ah;
841 char buf[32];
842 unsigned int len;
843 u32 regval;
844
845 regval = REG_READ_D(ah, sc->debug.regidx);
846 len = snprintf(buf, sizeof(buf), "0x%08x\n", regval);
847 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
848}
849
850static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
851 size_t count, loff_t *ppos)
852{
853 struct ath_softc *sc = file->private_data;
854 struct ath_hw *ah = sc->sc_ah;
855 unsigned long regval;
856 char buf[32];
857 ssize_t len;
858
859 len = min(count, sizeof(buf) - 1);
860 if (copy_from_user(buf, user_buf, len))
861 return -EINVAL;
862
863 buf[len] = '\0';
864 if (strict_strtoul(buf, 0, &regval))
865 return -EINVAL;
866
867 REG_WRITE_D(ah, sc->debug.regidx, regval);
868 return count;
869}
870
871static const struct file_operations fops_regval = {
872 .read = read_file_regval,
873 .write = write_file_regval,
874 .open = ath9k_debugfs_open,
875 .owner = THIS_MODULE
876};
877
703int ath9k_init_debug(struct ath_hw *ah) 878int ath9k_init_debug(struct ath_hw *ah)
704{ 879{
705 struct ath_common *common = ath9k_hw_common(ah); 880 struct ath_common *common = ath9k_hw_common(ah);
@@ -711,54 +886,55 @@ int ath9k_init_debug(struct ath_hw *ah)
711 sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), 886 sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
712 ath9k_debugfs_root); 887 ath9k_debugfs_root);
713 if (!sc->debug.debugfs_phy) 888 if (!sc->debug.debugfs_phy)
714 goto err; 889 return -ENOMEM;
715 890
716#ifdef CONFIG_ATH_DEBUG 891#ifdef CONFIG_ATH_DEBUG
717 sc->debug.debugfs_debug = debugfs_create_file("debug", 892 if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
718 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); 893 sc->debug.debugfs_phy, sc, &fops_debug))
719 if (!sc->debug.debugfs_debug)
720 goto err; 894 goto err;
721#endif 895#endif
722 896
723 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, 897 if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
724 sc->debug.debugfs_phy, sc, &fops_dma); 898 sc, &fops_dma))
725 if (!sc->debug.debugfs_dma) 899 goto err;
900
901 if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy,
902 sc, &fops_interrupt))
903 goto err;
904
905 if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
906 sc, &fops_rcstat))
907 goto err;
908
909 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
910 sc->debug.debugfs_phy, sc, &fops_wiphy))
911 goto err;
912
913 if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy,
914 sc, &fops_xmit))
726 goto err; 915 goto err;
727 916
728 sc->debug.debugfs_interrupt = debugfs_create_file("interrupt", 917 if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
729 S_IRUSR, 918 sc, &fops_recv))
730 sc->debug.debugfs_phy,
731 sc, &fops_interrupt);
732 if (!sc->debug.debugfs_interrupt)
733 goto err; 919 goto err;
734 920
735 sc->debug.debugfs_rcstat = debugfs_create_file("rcstat", 921 if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
736 S_IRUSR, 922 sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
737 sc->debug.debugfs_phy,
738 sc, &fops_rcstat);
739 if (!sc->debug.debugfs_rcstat)
740 goto err; 923 goto err;
741 924
742 sc->debug.debugfs_wiphy = debugfs_create_file( 925 if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
743 "wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, 926 sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
744 &fops_wiphy);
745 if (!sc->debug.debugfs_wiphy)
746 goto err; 927 goto err;
747 928
748 sc->debug.debugfs_xmit = debugfs_create_file("xmit", 929 if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
749 S_IRUSR, 930 sc->debug.debugfs_phy, sc, &fops_regidx))
750 sc->debug.debugfs_phy,
751 sc, &fops_xmit);
752 if (!sc->debug.debugfs_xmit)
753 goto err; 931 goto err;
754 932
755 sc->debug.debugfs_recv = debugfs_create_file("recv", 933 if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
756 S_IRUSR, 934 sc->debug.debugfs_phy, sc, &fops_regval))
757 sc->debug.debugfs_phy,
758 sc, &fops_recv);
759 if (!sc->debug.debugfs_recv)
760 goto err; 935 goto err;
761 936
937 sc->debug.regidx = 0;
762 return 0; 938 return 0;
763err: 939err:
764 ath9k_exit_debug(ah); 940 ath9k_exit_debug(ah);
@@ -770,14 +946,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
770 struct ath_common *common = ath9k_hw_common(ah); 946 struct ath_common *common = ath9k_hw_common(ah);
771 struct ath_softc *sc = (struct ath_softc *) common->priv; 947 struct ath_softc *sc = (struct ath_softc *) common->priv;
772 948
773 debugfs_remove(sc->debug.debugfs_recv); 949 debugfs_remove_recursive(sc->debug.debugfs_phy);
774 debugfs_remove(sc->debug.debugfs_xmit);
775 debugfs_remove(sc->debug.debugfs_wiphy);
776 debugfs_remove(sc->debug.debugfs_rcstat);
777 debugfs_remove(sc->debug.debugfs_interrupt);
778 debugfs_remove(sc->debug.debugfs_dma);
779 debugfs_remove(sc->debug.debugfs_debug);
780 debugfs_remove(sc->debug.debugfs_phy);
781} 950}
782 951
783int ath9k_debug_create_root(void) 952int ath9k_debug_create_root(void)
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 86780e68b31e..5147b8709e10 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -35,6 +35,8 @@ struct ath_buf;
35 * struct ath_interrupt_stats - Contains statistics about interrupts 35 * struct ath_interrupt_stats - Contains statistics about interrupts
36 * @total: Total no. of interrupts generated so far 36 * @total: Total no. of interrupts generated so far
37 * @rxok: RX with no errors 37 * @rxok: RX with no errors
38 * @rxlp: RX with low priority RX
39 * @rxhp: RX with high priority, uapsd only
38 * @rxeol: RX with no more RXDESC available 40 * @rxeol: RX with no more RXDESC available
39 * @rxorn: RX FIFO overrun 41 * @rxorn: RX FIFO overrun
40 * @txok: TX completed at the requested rate 42 * @txok: TX completed at the requested rate
@@ -55,6 +57,8 @@ struct ath_buf;
55struct ath_interrupt_stats { 57struct ath_interrupt_stats {
56 u32 total; 58 u32 total;
57 u32 rxok; 59 u32 rxok;
60 u32 rxlp;
61 u32 rxhp;
58 u32 rxeol; 62 u32 rxeol;
59 u32 rxorn; 63 u32 rxorn;
60 u32 txok; 64 u32 txok;
@@ -149,13 +153,7 @@ struct ath_stats {
149 153
150struct ath9k_debug { 154struct ath9k_debug {
151 struct dentry *debugfs_phy; 155 struct dentry *debugfs_phy;
152 struct dentry *debugfs_debug; 156 u32 regidx;
153 struct dentry *debugfs_dma;
154 struct dentry *debugfs_interrupt;
155 struct dentry *debugfs_rcstat;
156 struct dentry *debugfs_wiphy;
157 struct dentry *debugfs_xmit;
158 struct dentry *debugfs_recv;
159 struct ath_stats stats; 157 struct ath_stats stats;
160}; 158};
161 159
@@ -167,8 +165,8 @@ void ath9k_debug_remove_root(void);
167void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 165void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); 166void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 167void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
170 struct ath_buf *bf); 168 struct ath_buf *bf, struct ath_tx_status *ts);
171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); 169void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
172void ath_debug_stat_retries(struct ath_softc *sc, int rix, 170void ath_debug_stat_retries(struct ath_softc *sc, int rix,
173 int xretries, int retries, u8 per); 171 int xretries, int retries, u8 per);
174 172
@@ -204,12 +202,13 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc,
204 202
205static inline void ath_debug_stat_tx(struct ath_softc *sc, 203static inline void ath_debug_stat_tx(struct ath_softc *sc,
206 struct ath_txq *txq, 204 struct ath_txq *txq,
207 struct ath_buf *bf) 205 struct ath_buf *bf,
206 struct ath_tx_status *ts)
208{ 207{
209} 208}
210 209
211static inline void ath_debug_stat_rx(struct ath_softc *sc, 210static inline void ath_debug_stat_rx(struct ath_softc *sc,
212 struct ath_buf *bf) 211 struct ath_rx_status *rs)
213{ 212{
214} 213}
215 214
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index dacaae934148..ca8704a9d7ac 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -36,8 +36,6 @@ void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
36 36
37 if (ah->config.analog_shiftreg) 37 if (ah->config.analog_shiftreg)
38 udelay(100); 38 udelay(100);
39
40 return;
41} 39}
42 40
43int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, 41int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
@@ -256,14 +254,13 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah)
256{ 254{
257 int status; 255 int status;
258 256
259 if (AR_SREV_9287(ah)) { 257 if (AR_SREV_9300_20_OR_LATER(ah))
260 ah->eep_map = EEP_MAP_AR9287; 258 ah->eep_ops = &eep_ar9300_ops;
261 ah->eep_ops = &eep_AR9287_ops; 259 else if (AR_SREV_9287(ah)) {
260 ah->eep_ops = &eep_ar9287_ops;
262 } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { 261 } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
263 ah->eep_map = EEP_MAP_4KBITS;
264 ah->eep_ops = &eep_4k_ops; 262 ah->eep_ops = &eep_4k_ops;
265 } else { 263 } else {
266 ah->eep_map = EEP_MAP_DEFAULT;
267 ah->eep_ops = &eep_def_ops; 264 ah->eep_ops = &eep_def_ops;
268 } 265 }
269 266
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 2f2993b50e2f..21354c15a9a9 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -19,6 +19,7 @@
19 19
20#include "../ath.h" 20#include "../ath.h"
21#include <net/cfg80211.h> 21#include <net/cfg80211.h>
22#include "ar9003_eeprom.h"
22 23
23#define AH_USE_EEPROM 0x1 24#define AH_USE_EEPROM 0x1
24 25
@@ -93,7 +94,6 @@
93 */ 94 */
94#define AR9285_RDEXT_DEFAULT 0x1F 95#define AR9285_RDEXT_DEFAULT 0x1F
95 96
96#define AR_EEPROM_MAC(i) (0x1d+(i))
97#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 97#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
98#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) 98#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
99#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) 99#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
@@ -155,6 +155,7 @@
155#define AR5416_BCHAN_UNUSED 0xFF 155#define AR5416_BCHAN_UNUSED 0xFF
156#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 156#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
157#define AR5416_MAX_CHAINS 3 157#define AR5416_MAX_CHAINS 3
158#define AR9300_MAX_CHAINS 3
158#define AR5416_PWR_TABLE_OFFSET_DB -5 159#define AR5416_PWR_TABLE_OFFSET_DB -5
159 160
160/* Rx gain type values */ 161/* Rx gain type values */
@@ -249,16 +250,20 @@ enum eeprom_param {
249 EEP_MINOR_REV, 250 EEP_MINOR_REV,
250 EEP_TX_MASK, 251 EEP_TX_MASK,
251 EEP_RX_MASK, 252 EEP_RX_MASK,
253 EEP_FSTCLK_5G,
252 EEP_RXGAIN_TYPE, 254 EEP_RXGAIN_TYPE,
253 EEP_TXGAIN_TYPE,
254 EEP_OL_PWRCTRL, 255 EEP_OL_PWRCTRL,
256 EEP_TXGAIN_TYPE,
255 EEP_RC_CHAIN_MASK, 257 EEP_RC_CHAIN_MASK,
256 EEP_DAC_HPWR_5G, 258 EEP_DAC_HPWR_5G,
257 EEP_FRAC_N_5G, 259 EEP_FRAC_N_5G,
258 EEP_DEV_TYPE, 260 EEP_DEV_TYPE,
259 EEP_TEMPSENSE_SLOPE, 261 EEP_TEMPSENSE_SLOPE,
260 EEP_TEMPSENSE_SLOPE_PAL_ON, 262 EEP_TEMPSENSE_SLOPE_PAL_ON,
261 EEP_PWR_TABLE_OFFSET 263 EEP_PWR_TABLE_OFFSET,
264 EEP_DRIVE_STRENGTH,
265 EEP_INTERNAL_REGULATOR,
266 EEP_SWREG
262}; 267};
263 268
264enum ar5416_rates { 269enum ar5416_rates {
@@ -295,7 +300,8 @@ struct base_eep_header {
295 u32 binBuildNumber; 300 u32 binBuildNumber;
296 u8 deviceType; 301 u8 deviceType;
297 u8 pwdclkind; 302 u8 pwdclkind;
298 u8 futureBase_1[2]; 303 u8 fastClk5g;
304 u8 divChain;
299 u8 rxGainType; 305 u8 rxGainType;
300 u8 dacHiPwrMode_5G; 306 u8 dacHiPwrMode_5G;
301 u8 openLoopPwrCntl; 307 u8 openLoopPwrCntl;
@@ -656,13 +662,6 @@ struct ath9k_country_entry {
656 u8 iso[3]; 662 u8 iso[3];
657}; 663};
658 664
659enum ath9k_eep_map {
660 EEP_MAP_DEFAULT = 0x0,
661 EEP_MAP_4KBITS,
662 EEP_MAP_AR9287,
663 EEP_MAP_MAX
664};
665
666struct eeprom_ops { 665struct eeprom_ops {
667 int (*check_eeprom)(struct ath_hw *hw); 666 int (*check_eeprom)(struct ath_hw *hw);
668 u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param); 667 u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
@@ -713,6 +712,8 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
713 712
714extern const struct eeprom_ops eep_def_ops; 713extern const struct eeprom_ops eep_def_ops;
715extern const struct eeprom_ops eep_4k_ops; 714extern const struct eeprom_ops eep_4k_ops;
716extern const struct eeprom_ops eep_AR9287_ops; 715extern const struct eeprom_ops eep_ar9287_ops;
716extern const struct eeprom_ops eep_ar9287_ops;
717extern const struct eeprom_ops eep_ar9300_ops;
717 718
718#endif /* EEPROM_H */ 719#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 68db16690abf..41a77d1bd439 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9002_phy.h"
18 19
19static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) 20static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
20{ 21{
@@ -43,7 +44,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
43 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { 44 for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
44 if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { 45 if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) {
45 ath_print(common, ATH_DBG_EEPROM, 46 ath_print(common, ATH_DBG_EEPROM,
46 "Unable to read eeprom region \n"); 47 "Unable to read eeprom region\n");
47 return false; 48 return false;
48 } 49 }
49 eep_data++; 50 eep_data++;
@@ -182,11 +183,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
182 switch (param) { 183 switch (param) {
183 case EEP_NFTHRESH_2: 184 case EEP_NFTHRESH_2:
184 return pModal->noiseFloorThreshCh[0]; 185 return pModal->noiseFloorThreshCh[0];
185 case AR_EEPROM_MAC(0): 186 case EEP_MAC_LSW:
186 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 187 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
187 case AR_EEPROM_MAC(1): 188 case EEP_MAC_MID:
188 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 189 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
189 case AR_EEPROM_MAC(2): 190 case EEP_MAC_MSW:
190 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 191 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
191 case EEP_REG_0: 192 case EEP_REG_0:
192 return pBase->regDmn[0]; 193 return pBase->regDmn[0];
@@ -453,6 +454,8 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
453 &tMinCalPower, gainBoundaries, 454 &tMinCalPower, gainBoundaries,
454 pdadcValues, numXpdGain); 455 pdadcValues, numXpdGain);
455 456
457 ENABLE_REGWRITE_BUFFER(ah);
458
456 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { 459 if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
457 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 460 REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
458 SM(pdGainOverlap_t2, 461 SM(pdGainOverlap_t2,
@@ -493,6 +496,9 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
493 496
494 regOffset += 4; 497 regOffset += 4;
495 } 498 }
499
500 REGWRITE_BUFFER_FLUSH(ah);
501 DISABLE_REGWRITE_BUFFER(ah);
496 } 502 }
497 } 503 }
498 504
@@ -758,6 +764,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
758 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; 764 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
759 } 765 }
760 766
767 ENABLE_REGWRITE_BUFFER(ah);
768
761 /* OFDM power per rate */ 769 /* OFDM power per rate */
762 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 770 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
763 ATH9K_POW_SM(ratesArray[rate18mb], 24) 771 ATH9K_POW_SM(ratesArray[rate18mb], 24)
@@ -820,6 +828,9 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
820 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 828 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
821 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 829 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
822 } 830 }
831
832 REGWRITE_BUFFER_FLUSH(ah);
833 DISABLE_REGWRITE_BUFFER(ah);
823} 834}
824 835
825static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 836static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 839d05a1df29..b471db5fb82d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9002_phy.h"
18 19
19static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) 20static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
20{ 21{
@@ -44,7 +45,7 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
44 if (!ath9k_hw_nvram_read(common, 45 if (!ath9k_hw_nvram_read(common,
45 addr + eep_start_loc, eep_data)) { 46 addr + eep_start_loc, eep_data)) {
46 ath_print(common, ATH_DBG_EEPROM, 47 ath_print(common, ATH_DBG_EEPROM,
47 "Unable to read eeprom region \n"); 48 "Unable to read eeprom region\n");
48 return false; 49 return false;
49 } 50 }
50 eep_data++; 51 eep_data++;
@@ -172,11 +173,11 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
172 switch (param) { 173 switch (param) {
173 case EEP_NFTHRESH_2: 174 case EEP_NFTHRESH_2:
174 return pModal->noiseFloorThreshCh[0]; 175 return pModal->noiseFloorThreshCh[0];
175 case AR_EEPROM_MAC(0): 176 case EEP_MAC_LSW:
176 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 177 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
177 case AR_EEPROM_MAC(1): 178 case EEP_MAC_MID:
178 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 179 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
179 case AR_EEPROM_MAC(2): 180 case EEP_MAC_MSW:
180 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 181 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
181 case EEP_REG_0: 182 case EEP_REG_0:
182 return pBase->regDmn[0]; 183 return pBase->regDmn[0];
@@ -1169,7 +1170,7 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
1169#undef EEP_MAP9287_SPURCHAN 1170#undef EEP_MAP9287_SPURCHAN
1170} 1171}
1171 1172
1172const struct eeprom_ops eep_AR9287_ops = { 1173const struct eeprom_ops eep_ar9287_ops = {
1173 .check_eeprom = ath9k_hw_AR9287_check_eeprom, 1174 .check_eeprom = ath9k_hw_AR9287_check_eeprom,
1174 .get_eeprom = ath9k_hw_AR9287_get_eeprom, 1175 .get_eeprom = ath9k_hw_AR9287_get_eeprom,
1175 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, 1176 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 404a0341242c..7e1ed78d0e64 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9002_phy.h"
18 19
19static void ath9k_get_txgain_index(struct ath_hw *ah, 20static void ath9k_get_txgain_index(struct ath_hw *ah,
20 struct ath9k_channel *chan, 21 struct ath9k_channel *chan,
@@ -49,7 +50,6 @@ static void ath9k_get_txgain_index(struct ath_hw *ah,
49 i++; 50 i++;
50 51
51 *pcdacIdx = i; 52 *pcdacIdx = i;
52 return;
53} 53}
54 54
55static void ath9k_olc_get_pdadcs(struct ath_hw *ah, 55static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
@@ -222,6 +222,12 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 /* Enable fixup for AR_AN_TOP2 if necessary */
226 if (AR_SREV_9280_10_OR_LATER(ah) &&
227 (eep->baseEepHeader.version & 0xff) > 0x0a &&
228 eep->baseEepHeader.pwdclkind == 0)
229 ah->need_an_top2_fixup = 1;
230
225 return 0; 231 return 0;
226} 232}
227 233
@@ -237,11 +243,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
237 return pModal[0].noiseFloorThreshCh[0]; 243 return pModal[0].noiseFloorThreshCh[0];
238 case EEP_NFTHRESH_2: 244 case EEP_NFTHRESH_2:
239 return pModal[1].noiseFloorThreshCh[0]; 245 return pModal[1].noiseFloorThreshCh[0];
240 case AR_EEPROM_MAC(0): 246 case EEP_MAC_LSW:
241 return pBase->macAddr[0] << 8 | pBase->macAddr[1]; 247 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
242 case AR_EEPROM_MAC(1): 248 case EEP_MAC_MID:
243 return pBase->macAddr[2] << 8 | pBase->macAddr[3]; 249 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
244 case AR_EEPROM_MAC(2): 250 case EEP_MAC_MSW:
245 return pBase->macAddr[4] << 8 | pBase->macAddr[5]; 251 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
246 case EEP_REG_0: 252 case EEP_REG_0:
247 return pBase->regDmn[0]; 253 return pBase->regDmn[0];
@@ -267,6 +273,8 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
267 return pBase->txMask; 273 return pBase->txMask;
268 case EEP_RX_MASK: 274 case EEP_RX_MASK:
269 return pBase->rxMask; 275 return pBase->rxMask;
276 case EEP_FSTCLK_5G:
277 return pBase->fastClk5g;
270 case EEP_RXGAIN_TYPE: 278 case EEP_RXGAIN_TYPE:
271 return pBase->rxGainType; 279 return pBase->rxGainType;
272 case EEP_TXGAIN_TYPE: 280 case EEP_TXGAIN_TYPE:
@@ -742,8 +750,6 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
742 pPDADCValues[k] = pPDADCValues[k - 1]; 750 pPDADCValues[k] = pPDADCValues[k - 1];
743 k++; 751 k++;
744 } 752 }
745
746 return;
747} 753}
748 754
749static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, 755static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index deab8beb0680..0ee75e79fe35 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -283,22 +283,17 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
283 u32 timer_next, 283 u32 timer_next,
284 u32 timer_period) 284 u32 timer_period)
285{ 285{
286 struct ath_common *common = ath9k_hw_common(ah);
287 struct ath_softc *sc = (struct ath_softc *) common->priv;
288
289 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); 286 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
290 287
291 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { 288 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
292 ath9k_hw_set_interrupts(ah, 0); 289 ath9k_hw_set_interrupts(ah, 0);
293 sc->imask |= ATH9K_INT_GENTIMER; 290 ah->imask |= ATH9K_INT_GENTIMER;
294 ath9k_hw_set_interrupts(ah, sc->imask); 291 ath9k_hw_set_interrupts(ah, ah->imask);
295 } 292 }
296} 293}
297 294
298static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) 295static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
299{ 296{
300 struct ath_common *common = ath9k_hw_common(ah);
301 struct ath_softc *sc = (struct ath_softc *) common->priv;
302 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 297 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
303 298
304 ath9k_hw_gen_timer_stop(ah, timer); 299 ath9k_hw_gen_timer_stop(ah, timer);
@@ -306,8 +301,8 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
306 /* if no timer is enabled, turn off interrupt mask */ 301 /* if no timer is enabled, turn off interrupt mask */
307 if (timer_table->timer_mask.val == 0) { 302 if (timer_table->timer_mask.val == 0) {
308 ath9k_hw_set_interrupts(ah, 0); 303 ath9k_hw_set_interrupts(ah, 0);
309 sc->imask &= ~ATH9K_INT_GENTIMER; 304 ah->imask &= ~ATH9K_INT_GENTIMER;
310 ath9k_hw_set_interrupts(ah, sc->imask); 305 ath9k_hw_set_interrupts(ah, ah->imask);
311 } 306 }
312} 307}
313 308
@@ -364,7 +359,7 @@ static void ath_btcoex_no_stomp_timer(void *arg)
364 bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; 359 bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
365 360
366 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, 361 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
367 "no stomp timer running \n"); 362 "no stomp timer running\n");
368 363
369 spin_lock_bh(&btcoex->btcoex_lock); 364 spin_lock_bh(&btcoex->btcoex_lock);
370 365
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
new file mode 100644
index 000000000000..46dc41a16faa
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -0,0 +1,1008 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define ATH9K_FW_USB_DEV(devid, fw) \
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
21
22static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"),
24 ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"),
25 { },
26};
27
28MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
29
30static int __hif_usb_tx(struct hif_device_usb *hif_dev);
31
32static void hif_usb_regout_cb(struct urb *urb)
33{
34 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
35
36 switch (urb->status) {
37 case 0:
38 break;
39 case -ENOENT:
40 case -ECONNRESET:
41 case -ENODEV:
42 case -ESHUTDOWN:
43 goto free;
44 default:
45 break;
46 }
47
48 if (cmd) {
49 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
50 cmd->skb, 1);
51 kfree(cmd);
52 }
53
54 return;
55free:
56 kfree_skb(cmd->skb);
57 kfree(cmd);
58}
59
60static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
61 struct sk_buff *skb)
62{
63 struct urb *urb;
64 struct cmd_buf *cmd;
65 int ret = 0;
66
67 urb = usb_alloc_urb(0, GFP_KERNEL);
68 if (urb == NULL)
69 return -ENOMEM;
70
71 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
72 if (cmd == NULL) {
73 usb_free_urb(urb);
74 return -ENOMEM;
75 }
76
77 cmd->skb = skb;
78 cmd->hif_dev = hif_dev;
79
80 usb_fill_int_urb(urb, hif_dev->udev,
81 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
82 skb->data, skb->len,
83 hif_usb_regout_cb, cmd, 1);
84
85 usb_anchor_urb(urb, &hif_dev->regout_submitted);
86 ret = usb_submit_urb(urb, GFP_KERNEL);
87 if (ret) {
88 usb_unanchor_urb(urb);
89 kfree(cmd);
90 }
91 usb_free_urb(urb);
92
93 return ret;
94}
95
96static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
97 struct sk_buff_head *list)
98{
99 struct sk_buff *skb;
100
101 while ((skb = __skb_dequeue(list)) != NULL) {
102 dev_kfree_skb_any(skb);
103 TX_STAT_INC(skb_dropped);
104 }
105}
106
107static void hif_usb_tx_cb(struct urb *urb)
108{
109 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
110 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
111 struct sk_buff *skb;
112
113 if (!hif_dev || !tx_buf)
114 return;
115
116 switch (urb->status) {
117 case 0:
118 break;
119 case -ENOENT:
120 case -ECONNRESET:
121 case -ENODEV:
122 case -ESHUTDOWN:
123 /*
124 * The URB has been killed, free the SKBs
125 * and return.
126 */
127 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
128 return;
129 default:
130 break;
131 }
132
133 /* Check if TX has been stopped */
134 spin_lock(&hif_dev->tx.tx_lock);
135 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
136 spin_unlock(&hif_dev->tx.tx_lock);
137 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
138 goto add_free;
139 }
140 spin_unlock(&hif_dev->tx.tx_lock);
141
142 /* Complete the queued SKBs. */
143 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
144 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
145 skb, 1);
146 TX_STAT_INC(skb_completed);
147 }
148
149add_free:
150 /* Re-initialize the SKB queue */
151 tx_buf->len = tx_buf->offset = 0;
152 __skb_queue_head_init(&tx_buf->skb_queue);
153
154 /* Add this TX buffer to the free list */
155 spin_lock(&hif_dev->tx.tx_lock);
156 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
157 hif_dev->tx.tx_buf_cnt++;
158 if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
159 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
160 TX_STAT_INC(buf_completed);
161 spin_unlock(&hif_dev->tx.tx_lock);
162}
163
164/* TX lock has to be taken */
165static int __hif_usb_tx(struct hif_device_usb *hif_dev)
166{
167 struct tx_buf *tx_buf = NULL;
168 struct sk_buff *nskb = NULL;
169 int ret = 0, i;
170 u16 *hdr, tx_skb_cnt = 0;
171 u8 *buf;
172
173 if (hif_dev->tx.tx_skb_cnt == 0)
174 return 0;
175
176 /* Check if a free TX buffer is available */
177 if (list_empty(&hif_dev->tx.tx_buf))
178 return 0;
179
180 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
181 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
182 hif_dev->tx.tx_buf_cnt--;
183
184 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
185
186 for (i = 0; i < tx_skb_cnt; i++) {
187 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
188
189 /* Should never be NULL */
190 BUG_ON(!nskb);
191
192 hif_dev->tx.tx_skb_cnt--;
193
194 buf = tx_buf->buf;
195 buf += tx_buf->offset;
196 hdr = (u16 *)buf;
197 *hdr++ = nskb->len;
198 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
199 buf += 4;
200 memcpy(buf, nskb->data, nskb->len);
201 tx_buf->len = nskb->len + 4;
202
203 if (i < (tx_skb_cnt - 1))
204 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
205
206 if (i == (tx_skb_cnt - 1))
207 tx_buf->len += tx_buf->offset;
208
209 __skb_queue_tail(&tx_buf->skb_queue, nskb);
210 TX_STAT_INC(skb_queued);
211 }
212
213 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
214 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
215 tx_buf->buf, tx_buf->len,
216 hif_usb_tx_cb, tx_buf);
217
218 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
219 if (ret) {
220 tx_buf->len = tx_buf->offset = 0;
221 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
222 __skb_queue_head_init(&tx_buf->skb_queue);
223 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
224 hif_dev->tx.tx_buf_cnt++;
225 }
226
227 if (!ret)
228 TX_STAT_INC(buf_queued);
229
230 return ret;
231}
232
233static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
234 struct ath9k_htc_tx_ctl *tx_ctl)
235{
236 unsigned long flags;
237
238 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
239
240 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
241 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
242 return -ENODEV;
243 }
244
245 /* Check if the max queue count has been reached */
246 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
247 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
248 return -ENOMEM;
249 }
250
251 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
252 hif_dev->tx.tx_skb_cnt++;
253
254 /* Send normal frames immediately */
255 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
256 __hif_usb_tx(hif_dev);
257
258 /* Check if AMPDUs have to be sent immediately */
259 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
260 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
261 (hif_dev->tx.tx_skb_cnt < 2)) {
262 __hif_usb_tx(hif_dev);
263 }
264
265 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
266
267 return 0;
268}
269
270static void hif_usb_start(void *hif_handle, u8 pipe_id)
271{
272 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
273 unsigned long flags;
274
275 hif_dev->flags |= HIF_USB_START;
276
277 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
278 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
279 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
280}
281
282static void hif_usb_stop(void *hif_handle, u8 pipe_id)
283{
284 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
285 unsigned long flags;
286
287 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
288 ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
289 hif_dev->tx.tx_skb_cnt = 0;
290 hif_dev->tx.flags |= HIF_USB_TX_STOP;
291 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
292}
293
294static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
295 struct ath9k_htc_tx_ctl *tx_ctl)
296{
297 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
298 int ret = 0;
299
300 switch (pipe_id) {
301 case USB_WLAN_TX_PIPE:
302 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
303 break;
304 case USB_REG_OUT_PIPE:
305 ret = hif_usb_send_regout(hif_dev, skb);
306 break;
307 default:
308 dev_err(&hif_dev->udev->dev,
309 "ath9k_htc: Invalid TX pipe: %d\n", pipe_id);
310 ret = -EINVAL;
311 break;
312 }
313
314 return ret;
315}
316
317static struct ath9k_htc_hif hif_usb = {
318 .transport = ATH9K_HIF_USB,
319 .name = "ath9k_hif_usb",
320
321 .control_ul_pipe = USB_REG_OUT_PIPE,
322 .control_dl_pipe = USB_REG_IN_PIPE,
323
324 .start = hif_usb_start,
325 .stop = hif_usb_stop,
326 .send = hif_usb_send,
327};
328
329static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
330 struct sk_buff *skb)
331{
332 struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
333 int index = 0, i = 0, chk_idx, len = skb->len;
334 int rx_remain_len = 0, rx_pkt_len = 0;
335 u16 pkt_len, pkt_tag, pool_index = 0;
336 u8 *ptr;
337
338 spin_lock(&hif_dev->rx_lock);
339
340 rx_remain_len = hif_dev->rx_remain_len;
341 rx_pkt_len = hif_dev->rx_transfer_len;
342
343 if (rx_remain_len != 0) {
344 struct sk_buff *remain_skb = hif_dev->remain_skb;
345
346 if (remain_skb) {
347 ptr = (u8 *) remain_skb->data;
348
349 index = rx_remain_len;
350 rx_remain_len -= hif_dev->rx_pad_len;
351 ptr += rx_pkt_len;
352
353 memcpy(ptr, skb->data, rx_remain_len);
354
355 rx_pkt_len += rx_remain_len;
356 hif_dev->rx_remain_len = 0;
357 skb_put(remain_skb, rx_pkt_len);
358
359 skb_pool[pool_index++] = remain_skb;
360
361 } else {
362 index = rx_remain_len;
363 }
364 }
365
366 spin_unlock(&hif_dev->rx_lock);
367
368 while (index < len) {
369 ptr = (u8 *) skb->data;
370
371 pkt_len = ptr[index] + (ptr[index+1] << 8);
372 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
373
374 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
375 u16 pad_len;
376
377 pad_len = 4 - (pkt_len & 0x3);
378 if (pad_len == 4)
379 pad_len = 0;
380
381 chk_idx = index;
382 index = index + 4 + pkt_len + pad_len;
383
384 if (index > MAX_RX_BUF_SIZE) {
385 spin_lock(&hif_dev->rx_lock);
386 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
387 hif_dev->rx_transfer_len =
388 MAX_RX_BUF_SIZE - chk_idx - 4;
389 hif_dev->rx_pad_len = pad_len;
390
391 nskb = __dev_alloc_skb(pkt_len + 32,
392 GFP_ATOMIC);
393 if (!nskb) {
394 dev_err(&hif_dev->udev->dev,
395 "ath9k_htc: RX memory allocation"
396 " error\n");
397 spin_unlock(&hif_dev->rx_lock);
398 goto err;
399 }
400 skb_reserve(nskb, 32);
401 RX_STAT_INC(skb_allocated);
402
403 memcpy(nskb->data, &(skb->data[chk_idx+4]),
404 hif_dev->rx_transfer_len);
405
406 /* Record the buffer pointer */
407 hif_dev->remain_skb = nskb;
408 spin_unlock(&hif_dev->rx_lock);
409 } else {
410 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
411 if (!nskb) {
412 dev_err(&hif_dev->udev->dev,
413 "ath9k_htc: RX memory allocation"
414 " error\n");
415 goto err;
416 }
417 skb_reserve(nskb, 32);
418 RX_STAT_INC(skb_allocated);
419
420 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
421 skb_put(nskb, pkt_len);
422 skb_pool[pool_index++] = nskb;
423 }
424 } else {
425 RX_STAT_INC(skb_dropped);
426 return;
427 }
428 }
429
430err:
431 for (i = 0; i < pool_index; i++) {
432 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
433 skb_pool[i]->len, USB_WLAN_RX_PIPE);
434 RX_STAT_INC(skb_completed);
435 }
436}
437
438static void ath9k_hif_usb_rx_cb(struct urb *urb)
439{
440 struct sk_buff *skb = (struct sk_buff *) urb->context;
441 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
442 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
443 int ret;
444
445 if (!skb)
446 return;
447
448 if (!hif_dev)
449 goto free;
450
451 switch (urb->status) {
452 case 0:
453 break;
454 case -ENOENT:
455 case -ECONNRESET:
456 case -ENODEV:
457 case -ESHUTDOWN:
458 goto free;
459 default:
460 goto resubmit;
461 }
462
463 if (likely(urb->actual_length != 0)) {
464 skb_put(skb, urb->actual_length);
465 ath9k_hif_usb_rx_stream(hif_dev, skb);
466 }
467
468resubmit:
469 skb_reset_tail_pointer(skb);
470 skb_trim(skb, 0);
471
472 usb_anchor_urb(urb, &hif_dev->rx_submitted);
473 ret = usb_submit_urb(urb, GFP_ATOMIC);
474 if (ret) {
475 usb_unanchor_urb(urb);
476 goto free;
477 }
478
479 return;
480free:
481 kfree_skb(skb);
482}
483
484static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
485{
486 struct sk_buff *skb = (struct sk_buff *) urb->context;
487 struct sk_buff *nskb;
488 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
489 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
490 int ret;
491
492 if (!skb)
493 return;
494
495 if (!hif_dev)
496 goto free;
497
498 switch (urb->status) {
499 case 0:
500 break;
501 case -ENOENT:
502 case -ECONNRESET:
503 case -ENODEV:
504 case -ESHUTDOWN:
505 goto free;
506 default:
507 goto resubmit;
508 }
509
510 if (likely(urb->actual_length != 0)) {
511 skb_put(skb, urb->actual_length);
512
513 /* Process the command first */
514 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
515 skb->len, USB_REG_IN_PIPE);
516
517
518 nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
519 if (!nskb) {
520 dev_err(&hif_dev->udev->dev,
521 "ath9k_htc: REG_IN memory allocation failure\n");
522 urb->context = NULL;
523 return;
524 }
525
526 usb_fill_int_urb(urb, hif_dev->udev,
527 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
528 nskb->data, MAX_REG_IN_BUF_SIZE,
529 ath9k_hif_usb_reg_in_cb, nskb, 1);
530
531 ret = usb_submit_urb(urb, GFP_ATOMIC);
532 if (ret) {
533 kfree_skb(nskb);
534 urb->context = NULL;
535 }
536
537 return;
538 }
539
540resubmit:
541 skb_reset_tail_pointer(skb);
542 skb_trim(skb, 0);
543
544 ret = usb_submit_urb(urb, GFP_ATOMIC);
545 if (ret)
546 goto free;
547
548 return;
549free:
550 kfree_skb(skb);
551 urb->context = NULL;
552}
553
554static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
555{
556 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
557
558 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
559 &hif_dev->tx.tx_buf, list) {
560 usb_kill_urb(tx_buf->urb);
561 list_del(&tx_buf->list);
562 usb_free_urb(tx_buf->urb);
563 kfree(tx_buf->buf);
564 kfree(tx_buf);
565 }
566
567 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
568 &hif_dev->tx.tx_pending, list) {
569 usb_kill_urb(tx_buf->urb);
570 list_del(&tx_buf->list);
571 usb_free_urb(tx_buf->urb);
572 kfree(tx_buf->buf);
573 kfree(tx_buf);
574 }
575}
576
577static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
578{
579 struct tx_buf *tx_buf;
580 int i;
581
582 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
583 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
584 spin_lock_init(&hif_dev->tx.tx_lock);
585 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
586
587 for (i = 0; i < MAX_TX_URB_NUM; i++) {
588 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
589 if (!tx_buf)
590 goto err;
591
592 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
593 if (!tx_buf->buf)
594 goto err;
595
596 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
597 if (!tx_buf->urb)
598 goto err;
599
600 tx_buf->hif_dev = hif_dev;
601 __skb_queue_head_init(&tx_buf->skb_queue);
602
603 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
604 }
605
606 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
607
608 return 0;
609err:
610 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
611 return -ENOMEM;
612}
613
614static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
615{
616 usb_kill_anchored_urbs(&hif_dev->rx_submitted);
617}
618
619static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
620{
621 struct urb *urb = NULL;
622 struct sk_buff *skb = NULL;
623 int i, ret;
624
625 init_usb_anchor(&hif_dev->rx_submitted);
626 spin_lock_init(&hif_dev->rx_lock);
627
628 for (i = 0; i < MAX_RX_URB_NUM; i++) {
629
630 /* Allocate URB */
631 urb = usb_alloc_urb(0, GFP_KERNEL);
632 if (urb == NULL) {
633 ret = -ENOMEM;
634 goto err_urb;
635 }
636
637 /* Allocate buffer */
638 skb = alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
639 if (!skb) {
640 ret = -ENOMEM;
641 goto err_skb;
642 }
643
644 usb_fill_bulk_urb(urb, hif_dev->udev,
645 usb_rcvbulkpipe(hif_dev->udev,
646 USB_WLAN_RX_PIPE),
647 skb->data, MAX_RX_BUF_SIZE,
648 ath9k_hif_usb_rx_cb, skb);
649
650 /* Anchor URB */
651 usb_anchor_urb(urb, &hif_dev->rx_submitted);
652
653 /* Submit URB */
654 ret = usb_submit_urb(urb, GFP_KERNEL);
655 if (ret) {
656 usb_unanchor_urb(urb);
657 goto err_submit;
658 }
659
660 /*
661 * Drop reference count.
662 * This ensures that the URB is freed when killing them.
663 */
664 usb_free_urb(urb);
665 }
666
667 return 0;
668
669err_submit:
670 kfree_skb(skb);
671err_skb:
672 usb_free_urb(urb);
673err_urb:
674 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
675 return ret;
676}
677
678static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
679{
680 if (hif_dev->reg_in_urb) {
681 usb_kill_urb(hif_dev->reg_in_urb);
682 if (hif_dev->reg_in_urb->context)
683 kfree_skb((void *)hif_dev->reg_in_urb->context);
684 usb_free_urb(hif_dev->reg_in_urb);
685 hif_dev->reg_in_urb = NULL;
686 }
687}
688
689static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
690{
691 struct sk_buff *skb;
692
693 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
694 if (hif_dev->reg_in_urb == NULL)
695 return -ENOMEM;
696
697 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
698 if (!skb)
699 goto err;
700
701 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
702 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
703 skb->data, MAX_REG_IN_BUF_SIZE,
704 ath9k_hif_usb_reg_in_cb, skb, 1);
705
706 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
707 goto err;
708
709 return 0;
710
711err:
712 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
713 return -ENOMEM;
714}
715
716static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
717{
718 /* Register Write */
719 init_usb_anchor(&hif_dev->regout_submitted);
720
721 /* TX */
722 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
723 goto err;
724
725 /* RX */
726 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
727 goto err;
728
729 /* Register Read */
730 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
731 goto err;
732
733 return 0;
734err:
735 return -ENOMEM;
736}
737
738static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
739{
740 usb_kill_anchored_urbs(&hif_dev->regout_submitted);
741 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
742 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
743 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
744}
745
746static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
747{
748 int transfer, err;
749 const void *data = hif_dev->firmware->data;
750 size_t len = hif_dev->firmware->size;
751 u32 addr = AR9271_FIRMWARE;
752 u8 *buf = kzalloc(4096, GFP_KERNEL);
753
754 if (!buf)
755 return -ENOMEM;
756
757 while (len) {
758 transfer = min_t(int, len, 4096);
759 memcpy(buf, data, transfer);
760
761 err = usb_control_msg(hif_dev->udev,
762 usb_sndctrlpipe(hif_dev->udev, 0),
763 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
764 addr >> 8, 0, buf, transfer, HZ);
765 if (err < 0) {
766 kfree(buf);
767 return err;
768 }
769
770 len -= transfer;
771 data += transfer;
772 addr += transfer;
773 }
774 kfree(buf);
775
776 /*
777 * Issue FW download complete command to firmware.
778 */
779 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
780 FIRMWARE_DOWNLOAD_COMP,
781 0x40 | USB_DIR_OUT,
782 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
783 if (err)
784 return -EIO;
785
786 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
787 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
788
789 return 0;
790}
791
792static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
793 const char *fw_name)
794{
795 int ret;
796
797 /* Request firmware */
798 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
799 if (ret) {
800 dev_err(&hif_dev->udev->dev,
801 "ath9k_htc: Firmware - %s not found\n", fw_name);
802 goto err_fw_req;
803 }
804
805 /* Alloc URBs */
806 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
807 if (ret) {
808 dev_err(&hif_dev->udev->dev,
809 "ath9k_htc: Unable to allocate URBs\n");
810 goto err_urb;
811 }
812
813 /* Download firmware */
814 ret = ath9k_hif_usb_download_fw(hif_dev);
815 if (ret) {
816 dev_err(&hif_dev->udev->dev,
817 "ath9k_htc: Firmware - %s download failed\n", fw_name);
818 goto err_fw_download;
819 }
820
821 return 0;
822
823err_fw_download:
824 ath9k_hif_usb_dealloc_urbs(hif_dev);
825err_urb:
826 release_firmware(hif_dev->firmware);
827err_fw_req:
828 hif_dev->firmware = NULL;
829 return ret;
830}
831
832static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
833{
834 ath9k_hif_usb_dealloc_urbs(hif_dev);
835 if (hif_dev->firmware)
836 release_firmware(hif_dev->firmware);
837}
838
839static int ath9k_hif_usb_probe(struct usb_interface *interface,
840 const struct usb_device_id *id)
841{
842 struct usb_device *udev = interface_to_usbdev(interface);
843 struct hif_device_usb *hif_dev;
844 const char *fw_name = (const char *) id->driver_info;
845 int ret = 0;
846
847 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
848 if (!hif_dev) {
849 ret = -ENOMEM;
850 goto err_alloc;
851 }
852
853 usb_get_dev(udev);
854 hif_dev->udev = udev;
855 hif_dev->interface = interface;
856 hif_dev->device_id = id->idProduct;
857#ifdef CONFIG_PM
858 udev->reset_resume = 1;
859#endif
860 usb_set_intfdata(interface, hif_dev);
861
862 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
863 &hif_dev->udev->dev);
864 if (hif_dev->htc_handle == NULL) {
865 ret = -ENOMEM;
866 goto err_htc_hw_alloc;
867 }
868
869 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
870 if (ret) {
871 ret = -EINVAL;
872 goto err_hif_init_usb;
873 }
874
875 ret = ath9k_htc_hw_init(hif_dev->htc_handle,
876 &hif_dev->udev->dev, hif_dev->device_id);
877 if (ret) {
878 ret = -EINVAL;
879 goto err_htc_hw_init;
880 }
881
882 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
883
884 return 0;
885
886err_htc_hw_init:
887 ath9k_hif_usb_dev_deinit(hif_dev);
888err_hif_init_usb:
889 ath9k_htc_hw_free(hif_dev->htc_handle);
890err_htc_hw_alloc:
891 usb_set_intfdata(interface, NULL);
892 kfree(hif_dev);
893 usb_put_dev(udev);
894err_alloc:
895 return ret;
896}
897
898static void ath9k_hif_usb_reboot(struct usb_device *udev)
899{
900 u32 reboot_cmd = 0xffffffff;
901 void *buf;
902 int ret;
903
904 buf = kmalloc(4, GFP_KERNEL);
905 if (!buf)
906 return;
907
908 memcpy(buf, &reboot_cmd, 4);
909
910 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE),
911 buf, 4, NULL, HZ);
912 if (ret)
913 dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n");
914
915 kfree(buf);
916}
917
918static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
919{
920 struct usb_device *udev = interface_to_usbdev(interface);
921 struct hif_device_usb *hif_dev =
922 (struct hif_device_usb *) usb_get_intfdata(interface);
923
924 if (hif_dev) {
925 ath9k_htc_hw_deinit(hif_dev->htc_handle,
926 (udev->state == USB_STATE_NOTATTACHED) ? true : false);
927 ath9k_htc_hw_free(hif_dev->htc_handle);
928 ath9k_hif_usb_dev_deinit(hif_dev);
929 usb_set_intfdata(interface, NULL);
930 }
931
932 if (hif_dev->flags & HIF_USB_START)
933 ath9k_hif_usb_reboot(udev);
934
935 kfree(hif_dev);
936 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
937 usb_put_dev(udev);
938}
939
940#ifdef CONFIG_PM
941static int ath9k_hif_usb_suspend(struct usb_interface *interface,
942 pm_message_t message)
943{
944 struct hif_device_usb *hif_dev =
945 (struct hif_device_usb *) usb_get_intfdata(interface);
946
947 ath9k_hif_usb_dealloc_urbs(hif_dev);
948
949 return 0;
950}
951
952static int ath9k_hif_usb_resume(struct usb_interface *interface)
953{
954 struct hif_device_usb *hif_dev =
955 (struct hif_device_usb *) usb_get_intfdata(interface);
956 int ret;
957
958 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
959 if (ret)
960 return ret;
961
962 if (hif_dev->firmware) {
963 ret = ath9k_hif_usb_download_fw(hif_dev);
964 if (ret)
965 goto fail_resume;
966 } else {
967 ath9k_hif_usb_dealloc_urbs(hif_dev);
968 return -EIO;
969 }
970
971 mdelay(100);
972
973 ret = ath9k_htc_resume(hif_dev->htc_handle);
974
975 if (ret)
976 goto fail_resume;
977
978 return 0;
979
980fail_resume:
981 ath9k_hif_usb_dealloc_urbs(hif_dev);
982
983 return ret;
984}
985#endif
986
987static struct usb_driver ath9k_hif_usb_driver = {
988 .name = "ath9k_hif_usb",
989 .probe = ath9k_hif_usb_probe,
990 .disconnect = ath9k_hif_usb_disconnect,
991#ifdef CONFIG_PM
992 .suspend = ath9k_hif_usb_suspend,
993 .resume = ath9k_hif_usb_resume,
994 .reset_resume = ath9k_hif_usb_resume,
995#endif
996 .id_table = ath9k_hif_usb_ids,
997 .soft_unbind = 1,
998};
999
1000int ath9k_hif_usb_init(void)
1001{
1002 return usb_register(&ath9k_hif_usb_driver);
1003}
1004
1005void ath9k_hif_usb_exit(void)
1006{
1007 usb_deregister(&ath9k_hif_usb_driver);
1008}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
new file mode 100644
index 000000000000..0aca49b6fcb6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_USB_H
18#define HTC_USB_H
19
20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000
22
23#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31
25
26#define ATH_USB_RX_STREAM_MODE_TAG 0x4e00
27#define ATH_USB_TX_STREAM_MODE_TAG 0x697e
28
29/* FIXME: Verify these numbers (with Windows) */
30#define MAX_TX_URB_NUM 8
31#define MAX_TX_BUF_NUM 1024
32#define MAX_TX_BUF_SIZE 32768
33#define MAX_TX_AGGR_NUM 20
34
35#define MAX_RX_URB_NUM 8
36#define MAX_RX_BUF_SIZE 16384
37#define MAX_PKT_NUM_IN_TRANSFER 10
38
39#define MAX_REG_OUT_URB_NUM 1
40#define MAX_REG_OUT_BUF_NUM 8
41
42#define MAX_REG_IN_BUF_SIZE 64
43
44/* USB Endpoint definition */
45#define USB_WLAN_TX_PIPE 1
46#define USB_WLAN_RX_PIPE 2
47#define USB_REG_IN_PIPE 3
48#define USB_REG_OUT_PIPE 4
49
50#define HIF_USB_MAX_RXPIPES 2
51#define HIF_USB_MAX_TXPIPES 4
52
53struct tx_buf {
54 u8 *buf;
55 u16 len;
56 u16 offset;
57 struct urb *urb;
58 struct sk_buff_head skb_queue;
59 struct hif_device_usb *hif_dev;
60 struct list_head list;
61};
62
63#define HIF_USB_TX_STOP BIT(0)
64
65struct hif_usb_tx {
66 u8 flags;
67 u8 tx_buf_cnt;
68 u16 tx_skb_cnt;
69 struct sk_buff_head tx_skb_queue;
70 struct list_head tx_buf;
71 struct list_head tx_pending;
72 spinlock_t tx_lock;
73};
74
75struct cmd_buf {
76 struct sk_buff *skb;
77 struct hif_device_usb *hif_dev;
78};
79
80#define HIF_USB_START BIT(0)
81
82struct hif_device_usb {
83 u16 device_id;
84 struct usb_device *udev;
85 struct usb_interface *interface;
86 const struct firmware *firmware;
87 struct htc_target *htc_handle;
88 struct hif_usb_tx tx;
89 struct urb *reg_in_urb;
90 struct usb_anchor regout_submitted;
91 struct usb_anchor rx_submitted;
92 struct sk_buff *remain_skb;
93 int rx_remain_len;
94 int rx_pkt_len;
95 int rx_transfer_len;
96 int rx_pad_len;
97 spinlock_t rx_lock;
98 u8 flags; /* HIF_USB_* */
99};
100
101int ath9k_hif_usb_init(void);
102void ath9k_hif_usb_exit(void);
103
104#endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
new file mode 100644
index 000000000000..ad556aa8da39
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -0,0 +1,464 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_H
18#define HTC_H
19
20#include <linux/module.h>
21#include <linux/usb.h>
22#include <linux/firmware.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/leds.h>
26#include <net/mac80211.h>
27
28#include "common.h"
29#include "htc_hst.h"
30#include "hif_usb.h"
31#include "wmi.h"
32
33#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
34#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
35#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
36#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
37
38#define ATH_DEFAULT_BMISS_LIMIT 10
39#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
40#define TSF_TO_TU(_h, _l) \
41 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
42
43extern struct ieee80211_ops ath9k_htc_ops;
44extern int htc_modparam_nohwcrypt;
45
46enum htc_phymode {
47 HTC_MODE_AUTO = 0,
48 HTC_MODE_11A = 1,
49 HTC_MODE_11B = 2,
50 HTC_MODE_11G = 3,
51 HTC_MODE_FH = 4,
52 HTC_MODE_TURBO_A = 5,
53 HTC_MODE_TURBO_G = 6,
54 HTC_MODE_11NA = 7,
55 HTC_MODE_11NG = 8
56};
57
58enum htc_opmode {
59 HTC_M_STA = 1,
60 HTC_M_IBSS = 0,
61 HTC_M_AHDEMO = 3,
62 HTC_M_HOSTAP = 6,
63 HTC_M_MONITOR = 8,
64 HTC_M_WDS = 2
65};
66
67#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
68#define ATH9K_HTC_AMPDU 1
69#define ATH9K_HTC_NORMAL 2
70
71#define ATH9K_HTC_TX_CTSONLY 0x1
72#define ATH9K_HTC_TX_RTSCTS 0x2
73#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
74
75struct tx_frame_hdr {
76 u8 data_type;
77 u8 node_idx;
78 u8 vif_idx;
79 u8 tidno;
80 u32 flags; /* ATH9K_HTC_TX_* */
81 u8 key_type;
82 u8 keyix;
83 u8 reserved[26];
84} __packed;
85
86struct tx_mgmt_hdr {
87 u8 node_idx;
88 u8 vif_idx;
89 u8 tidno;
90 u8 flags;
91 u8 key_type;
92 u8 keyix;
93 u16 reserved;
94} __packed;
95
96struct tx_beacon_header {
97 u8 len_changed;
98 u8 vif_index;
99 u16 rev;
100} __packed;
101
102struct ath9k_htc_target_hw {
103 u32 flags;
104 u32 flags_ext;
105 u32 ampdu_limit;
106 u8 ampdu_subframes;
107 u8 tx_chainmask;
108 u8 tx_chainmask_legacy;
109 u8 rtscts_ratecode;
110 u8 protmode;
111} __packed;
112
113struct ath9k_htc_cap_target {
114 u32 flags;
115 u32 flags_ext;
116 u32 ampdu_limit;
117 u8 ampdu_subframes;
118 u8 tx_chainmask;
119 u8 tx_chainmask_legacy;
120 u8 rtscts_ratecode;
121 u8 protmode;
122} __packed;
123
124struct ath9k_htc_target_vif {
125 u8 index;
126 u8 des_bssid[ETH_ALEN];
127 __be32 opmode;
128 u8 myaddr[ETH_ALEN];
129 u8 bssid[ETH_ALEN];
130 u32 flags;
131 u32 flags_ext;
132 u16 ps_sta;
133 __be16 rtsthreshold;
134 u8 ath_cap;
135 u8 node;
136 s8 mcast_rate;
137} __packed;
138
139#define ATH_HTC_STA_AUTH 0x0001
140#define ATH_HTC_STA_QOS 0x0002
141#define ATH_HTC_STA_ERP 0x0004
142#define ATH_HTC_STA_HT 0x0008
143
144/* FIXME: UAPSD variables */
145struct ath9k_htc_target_sta {
146 u16 associd;
147 u16 txpower;
148 u32 ucastkey;
149 u8 macaddr[ETH_ALEN];
150 u8 bssid[ETH_ALEN];
151 u8 sta_index;
152 u8 vif_index;
153 u8 vif_sta;
154 __be16 flags; /* ATH_HTC_STA_* */
155 u16 htcap;
156 u8 valid;
157 u16 capinfo;
158 struct ath9k_htc_target_hw *hw;
159 struct ath9k_htc_target_vif *vif;
160 u16 txseqmgmt;
161 u8 is_vif_sta;
162 u16 maxampdu;
163 u16 iv16;
164 u32 iv32;
165} __packed;
166
167struct ath9k_htc_target_aggr {
168 u8 sta_index;
169 u8 tidno;
170 u8 aggr_enable;
171 u8 padding;
172} __packed;
173
174#define ATH_HTC_RATE_MAX 30
175
176#define WLAN_RC_DS_FLAG 0x01
177#define WLAN_RC_40_FLAG 0x02
178#define WLAN_RC_SGI_FLAG 0x04
179#define WLAN_RC_HT_FLAG 0x08
180
181struct ath9k_htc_rateset {
182 u8 rs_nrates;
183 u8 rs_rates[ATH_HTC_RATE_MAX];
184};
185
186struct ath9k_htc_rate {
187 struct ath9k_htc_rateset legacy_rates;
188 struct ath9k_htc_rateset ht_rates;
189} __packed;
190
191struct ath9k_htc_target_rate {
192 u8 sta_index;
193 u8 isnew;
194 __be32 capflags;
195 struct ath9k_htc_rate rates;
196};
197
198struct ath9k_htc_target_stats {
199 __be32 tx_shortretry;
200 __be32 tx_longretry;
201 __be32 tx_xretries;
202 __be32 ht_txunaggr_xretry;
203 __be32 ht_tx_xretries;
204} __packed;
205
206struct ath9k_htc_vif {
207 u8 index;
208};
209
210#define ATH9K_HTC_MAX_STA 8
211#define ATH9K_HTC_MAX_TID 8
212
213enum tid_aggr_state {
214 AGGR_STOP = 0,
215 AGGR_PROGRESS,
216 AGGR_START,
217 AGGR_OPERATIONAL
218};
219
220struct ath9k_htc_sta {
221 u8 index;
222 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
223};
224
225struct ath9k_htc_aggr_work {
226 u16 tid;
227 u8 sta_addr[ETH_ALEN];
228 struct ieee80211_hw *hw;
229 struct ieee80211_vif *vif;
230 enum ieee80211_ampdu_mlme_action action;
231 struct mutex mutex;
232};
233
234#define ATH9K_HTC_RXBUF 256
235#define HTC_RX_FRAME_HEADER_SIZE 40
236
237struct ath9k_htc_rxbuf {
238 bool in_process;
239 struct sk_buff *skb;
240 struct ath_htc_rx_status rxstatus;
241 struct list_head list;
242};
243
244struct ath9k_htc_rx {
245 int last_rssi; /* FIXME: per-STA */
246 struct list_head rxbuf;
247 spinlock_t rxbuflock;
248};
249
250struct ath9k_htc_tx_ctl {
251 u8 type; /* ATH9K_HTC_* */
252};
253
254#ifdef CONFIG_ATH9K_HTC_DEBUGFS
255
256#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
257#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
258
259struct ath_tx_stats {
260 u32 buf_queued;
261 u32 buf_completed;
262 u32 skb_queued;
263 u32 skb_completed;
264 u32 skb_dropped;
265};
266
267struct ath_rx_stats {
268 u32 skb_allocated;
269 u32 skb_completed;
270 u32 skb_dropped;
271};
272
273struct ath9k_debug {
274 struct dentry *debugfs_phy;
275 struct dentry *debugfs_tgt_stats;
276 struct dentry *debugfs_xmit;
277 struct dentry *debugfs_recv;
278 struct ath_tx_stats tx_stats;
279 struct ath_rx_stats rx_stats;
280 u32 txrate;
281};
282
283#else
284
285#define TX_STAT_INC(c) do { } while (0)
286#define RX_STAT_INC(c) do { } while (0)
287
288#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
289
290#define ATH_LED_PIN_DEF 1
291#define ATH_LED_PIN_9287 8
292#define ATH_LED_PIN_9271 15
293#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
294#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
295
296enum ath_led_type {
297 ATH_LED_RADIO,
298 ATH_LED_ASSOC,
299 ATH_LED_TX,
300 ATH_LED_RX
301};
302
303struct ath_led {
304 struct ath9k_htc_priv *priv;
305 struct led_classdev led_cdev;
306 enum ath_led_type led_type;
307 struct delayed_work brightness_work;
308 char name[32];
309 bool registered;
310 int brightness;
311};
312
313struct htc_beacon_config {
314 u16 beacon_interval;
315 u16 listen_interval;
316 u16 dtim_period;
317 u16 bmiss_timeout;
318 u8 dtim_count;
319};
320
321#define OP_INVALID BIT(0)
322#define OP_SCANNING BIT(1)
323#define OP_FULL_RESET BIT(2)
324#define OP_LED_ASSOCIATED BIT(3)
325#define OP_LED_ON BIT(4)
326#define OP_PREAMBLE_SHORT BIT(5)
327#define OP_PROTECT_ENABLE BIT(6)
328#define OP_TXAGGR BIT(7)
329#define OP_ASSOCIATED BIT(8)
330#define OP_ENABLE_BEACON BIT(9)
331#define OP_LED_DEINIT BIT(10)
332#define OP_UNPLUGGED BIT(11)
333
334struct ath9k_htc_priv {
335 struct device *dev;
336 struct ieee80211_hw *hw;
337 struct ath_hw *ah;
338 struct htc_target *htc;
339 struct wmi *wmi;
340
341 enum htc_endpoint_id wmi_cmd_ep;
342 enum htc_endpoint_id beacon_ep;
343 enum htc_endpoint_id cab_ep;
344 enum htc_endpoint_id uapsd_ep;
345 enum htc_endpoint_id mgmt_ep;
346 enum htc_endpoint_id data_be_ep;
347 enum htc_endpoint_id data_bk_ep;
348 enum htc_endpoint_id data_vi_ep;
349 enum htc_endpoint_id data_vo_ep;
350
351 u16 op_flags;
352 u16 curtxpow;
353 u16 txpowlimit;
354 u16 nvifs;
355 u16 nstations;
356 u16 seq_no;
357 u32 bmiss_cnt;
358
359 spinlock_t beacon_lock;
360
361 bool tx_queues_stop;
362 spinlock_t tx_lock;
363
364 struct ieee80211_vif *vif;
365 struct htc_beacon_config cur_beacon_conf;
366 unsigned int rxfilter;
367 struct tasklet_struct wmi_tasklet;
368 struct tasklet_struct rx_tasklet;
369 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
370 struct ath9k_htc_rx rx;
371 struct tasklet_struct tx_tasklet;
372 struct sk_buff_head tx_queue;
373 struct ath9k_htc_aggr_work aggr_work;
374 struct delayed_work ath9k_aggr_work;
375 struct delayed_work ath9k_ani_work;
376 struct work_struct ps_work;
377
378 struct mutex htc_pm_lock;
379 unsigned long ps_usecount;
380 bool ps_enabled;
381 bool ps_idle;
382
383 struct ath_led radio_led;
384 struct ath_led assoc_led;
385 struct ath_led tx_led;
386 struct ath_led rx_led;
387 struct delayed_work ath9k_led_blink_work;
388 int led_on_duration;
389 int led_off_duration;
390 int led_on_cnt;
391 int led_off_cnt;
392 int hwq_map[ATH9K_WME_AC_VO+1];
393
394#ifdef CONFIG_ATH9K_HTC_DEBUGFS
395 struct ath9k_debug debug;
396#endif
397 struct ath9k_htc_target_rate tgt_rate;
398
399 struct mutex mutex;
400};
401
402static inline void ath_read_cachesize(struct ath_common *common, int *csz)
403{
404 common->bus_ops->read_cachesize(common, csz);
405}
406
407void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
408 struct ieee80211_vif *vif);
409void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
410
411void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
412 enum htc_endpoint_id ep_id);
413void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
414 bool txok);
415void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
416 enum htc_endpoint_id ep_id, bool txok);
417
418void ath9k_htc_station_work(struct work_struct *work);
419void ath9k_htc_aggr_work(struct work_struct *work);
420void ath9k_ani_work(struct work_struct *work);;
421
422int ath9k_tx_init(struct ath9k_htc_priv *priv);
423void ath9k_tx_tasklet(unsigned long data);
424int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
425void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
426bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
427 enum ath9k_tx_queue_subtype qtype);
428int get_hw_qnum(u16 queue, int *hwq_map);
429int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
430 struct ath9k_tx_queue_info *qinfo);
431
432int ath9k_rx_init(struct ath9k_htc_priv *priv);
433void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
434void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
435void ath9k_rx_tasklet(unsigned long data);
436u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
437
438void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
439void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
440void ath9k_ps_work(struct work_struct *work);
441
442void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
443void ath9k_init_leds(struct ath9k_htc_priv *priv);
444void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
445
446int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
447 u16 devid);
448void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
449#ifdef CONFIG_PM
450int ath9k_htc_resume(struct htc_target *htc_handle);
451#endif
452#ifdef CONFIG_ATH9K_HTC_DEBUGFS
453int ath9k_htc_debug_create_root(void);
454void ath9k_htc_debug_remove_root(void);
455int ath9k_htc_init_debug(struct ath_hw *ah);
456void ath9k_htc_exit_debug(struct ath_hw *ah);
457#else
458static inline int ath9k_htc_debug_create_root(void) { return 0; };
459static inline void ath9k_htc_debug_remove_root(void) {};
460static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
461static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
462#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
463
464#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
new file mode 100644
index 000000000000..c10c7d002eb7
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -0,0 +1,255 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define FUDGE 2
20
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct htc_beacon_config *bss_conf)
23{
24 struct ath_common *common = ath9k_hw_common(priv->ah);
25 struct ath9k_beacon_state bs;
26 enum ath9k_int imask = 0;
27 int dtimperiod, dtimcount, sleepduration;
28 int cfpperiod, cfpcount, bmiss_timeout;
29 u32 nexttbtt = 0, intval, tsftu;
30 __be32 htc_imask = 0;
31 u64 tsf;
32 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
33 int ret;
34 u8 cmd_rsp;
35
36 memset(&bs, 0, sizeof(bs));
37
38 intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
39 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
40
41 /*
42 * Setup dtim and cfp parameters according to
43 * last beacon we received (which may be none).
44 */
45 dtimperiod = bss_conf->dtim_period;
46 if (dtimperiod <= 0) /* NB: 0 if not known */
47 dtimperiod = 1;
48 dtimcount = 1;
49 if (dtimcount >= dtimperiod) /* NB: sanity check */
50 dtimcount = 0;
51 cfpperiod = 1; /* NB: no PCF support yet */
52 cfpcount = 0;
53
54 sleepduration = intval;
55 if (sleepduration <= 0)
56 sleepduration = intval;
57
58 /*
59 * Pull nexttbtt forward to reflect the current
60 * TSF and calculate dtim+cfp state for the result.
61 */
62 tsf = ath9k_hw_gettsf64(priv->ah);
63 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
64
65 num_beacons = tsftu / intval + 1;
66 offset = tsftu % intval;
67 nexttbtt = tsftu - offset;
68 if (offset)
69 nexttbtt += intval;
70
71 /* DTIM Beacon every dtimperiod Beacon */
72 dtim_dec_count = num_beacons % dtimperiod;
73 /* CFP every cfpperiod DTIM Beacon */
74 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
75 if (dtim_dec_count)
76 cfp_dec_count++;
77
78 dtimcount -= dtim_dec_count;
79 if (dtimcount < 0)
80 dtimcount += dtimperiod;
81
82 cfpcount -= cfp_dec_count;
83 if (cfpcount < 0)
84 cfpcount += cfpperiod;
85
86 bs.bs_intval = intval;
87 bs.bs_nexttbtt = nexttbtt;
88 bs.bs_dtimperiod = dtimperiod*intval;
89 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
90 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
91 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
92 bs.bs_cfpmaxduration = 0;
93
94 /*
95 * Calculate the number of consecutive beacons to miss* before taking
96 * a BMISS interrupt. The configuration is specified in TU so we only
97 * need calculate based on the beacon interval. Note that we clamp the
98 * result to at most 15 beacons.
99 */
100 if (sleepduration > intval) {
101 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
102 } else {
103 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
104 if (bs.bs_bmissthreshold > 15)
105 bs.bs_bmissthreshold = 15;
106 else if (bs.bs_bmissthreshold <= 0)
107 bs.bs_bmissthreshold = 1;
108 }
109
110 /*
111 * Calculate sleep duration. The configuration is given in ms.
112 * We ensure a multiple of the beacon period is used. Also, if the sleep
113 * duration is greater than the DTIM period then it makes senses
114 * to make it a multiple of that.
115 *
116 * XXX fixed at 100ms
117 */
118
119 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
120 if (bs.bs_sleepduration > bs.bs_dtimperiod)
121 bs.bs_sleepduration = bs.bs_dtimperiod;
122
123 /* TSF out of range threshold fixed at 1 second */
124 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
125
126 ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
127 ath_print(common, ATH_DBG_BEACON,
128 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
129 bs.bs_bmissthreshold, bs.bs_sleepduration,
130 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
131
132 /* Set the computed STA beacon timers */
133
134 WMI_CMD(WMI_DISABLE_INTR_CMDID);
135 ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
136 imask |= ATH9K_INT_BMISS;
137 htc_imask = cpu_to_be32(imask);
138 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
139}
140
141static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
142 struct htc_beacon_config *bss_conf)
143{
144 struct ath_common *common = ath9k_hw_common(priv->ah);
145 enum ath9k_int imask = 0;
146 u32 nexttbtt, intval;
147 __be32 htc_imask = 0;
148 int ret;
149 u8 cmd_rsp;
150
151 intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
152 nexttbtt = intval;
153 intval |= ATH9K_BEACON_ENA;
154 if (priv->op_flags & OP_ENABLE_BEACON)
155 imask |= ATH9K_INT_SWBA;
156
157 ath_print(common, ATH_DBG_BEACON,
158 "IBSS Beacon config, intval: %d, imask: 0x%x\n",
159 bss_conf->beacon_interval, imask);
160
161 WMI_CMD(WMI_DISABLE_INTR_CMDID);
162 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
163 priv->bmiss_cnt = 0;
164 htc_imask = cpu_to_be32(imask);
165 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
166}
167
168void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
169 enum htc_endpoint_id ep_id, bool txok)
170{
171 dev_kfree_skb_any(skb);
172}
173
174void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
175{
176 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
177 struct tx_beacon_header beacon_hdr;
178 struct ath9k_htc_tx_ctl tx_ctl;
179 struct ieee80211_tx_info *info;
180 struct sk_buff *beacon;
181 u8 *tx_fhdr;
182
183 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
184 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
185
186 /* FIXME: Handle BMISS */
187 if (beacon_pending != 0) {
188 priv->bmiss_cnt++;
189 return;
190 }
191
192 spin_lock_bh(&priv->beacon_lock);
193
194 if (unlikely(priv->op_flags & OP_SCANNING)) {
195 spin_unlock_bh(&priv->beacon_lock);
196 return;
197 }
198
199 /* Get a new beacon */
200 beacon = ieee80211_beacon_get(priv->hw, priv->vif);
201 if (!beacon) {
202 spin_unlock_bh(&priv->beacon_lock);
203 return;
204 }
205
206 info = IEEE80211_SKB_CB(beacon);
207 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
208 struct ieee80211_hdr *hdr =
209 (struct ieee80211_hdr *) beacon->data;
210 priv->seq_no += 0x10;
211 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
212 hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
213 }
214
215 tx_ctl.type = ATH9K_HTC_NORMAL;
216 beacon_hdr.vif_index = avp->index;
217 tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
218 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
219
220 htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl);
221
222 spin_unlock_bh(&priv->beacon_lock);
223}
224
225
226void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
227 struct ieee80211_vif *vif)
228{
229 struct ath_common *common = ath9k_hw_common(priv->ah);
230 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
231 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
232
233 cur_conf->beacon_interval = bss_conf->beacon_int;
234 if (cur_conf->beacon_interval == 0)
235 cur_conf->beacon_interval = 100;
236
237 cur_conf->dtim_period = bss_conf->dtim_period;
238 cur_conf->listen_interval = 1;
239 cur_conf->dtim_count = 1;
240 cur_conf->bmiss_timeout =
241 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
242
243 switch (vif->type) {
244 case NL80211_IFTYPE_STATION:
245 ath9k_htc_beacon_config_sta(priv, cur_conf);
246 break;
247 case NL80211_IFTYPE_ADHOC:
248 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
249 break;
250 default:
251 ath_print(common, ATH_DBG_CONFIG,
252 "Unsupported beaconing mode\n");
253 return;
254 }
255}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
new file mode 100644
index 000000000000..dc015077a8d9
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -0,0 +1,834 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19MODULE_AUTHOR("Atheros Communications");
20MODULE_LICENSE("Dual BSD/GPL");
21MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22
23static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24module_param_named(debug, ath9k_debug, uint, 0);
25MODULE_PARM_DESC(debug, "Debugging mask");
26
27int htc_modparam_nohwcrypt;
28module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
29MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30
31#define CHAN2G(_freq, _idx) { \
32 .center_freq = (_freq), \
33 .hw_value = (_idx), \
34 .max_power = 20, \
35}
36
37static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */
40 CHAN2G(2422, 2), /* Channel 3 */
41 CHAN2G(2427, 3), /* Channel 4 */
42 CHAN2G(2432, 4), /* Channel 5 */
43 CHAN2G(2437, 5), /* Channel 6 */
44 CHAN2G(2442, 6), /* Channel 7 */
45 CHAN2G(2447, 7), /* Channel 8 */
46 CHAN2G(2452, 8), /* Channel 9 */
47 CHAN2G(2457, 9), /* Channel 10 */
48 CHAN2G(2462, 10), /* Channel 11 */
49 CHAN2G(2467, 11), /* Channel 12 */
50 CHAN2G(2472, 12), /* Channel 13 */
51 CHAN2G(2484, 13), /* Channel 14 */
52};
53
54/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
57
58#define RATE(_bitrate, _hw_rate, _flags) { \
59 .bitrate = (_bitrate), \
60 .flags = (_flags), \
61 .hw_value = (_hw_rate), \
62 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
63}
64
65static struct ieee80211_rate ath9k_legacy_rates[] = {
66 RATE(10, 0x1b, 0),
67 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
68 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
69 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
70 RATE(60, 0x0b, 0),
71 RATE(90, 0x0f, 0),
72 RATE(120, 0x0a, 0),
73 RATE(180, 0x0e, 0),
74 RATE(240, 0x09, 0),
75 RATE(360, 0x0d, 0),
76 RATE(480, 0x08, 0),
77 RATE(540, 0x0c, 0),
78};
79
80static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
81{
82 int time_left;
83
84 if (atomic_read(&priv->htc->tgt_ready) > 0) {
85 atomic_dec(&priv->htc->tgt_ready);
86 return 0;
87 }
88
89 /* Firmware can take up to 50ms to get ready, to be safe use 1 second */
90 time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
91 if (!time_left) {
92 dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
93 return -ETIMEDOUT;
94 }
95
96 atomic_dec(&priv->htc->tgt_ready);
97
98 return 0;
99}
100
101static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
102{
103 ath9k_htc_exit_debug(priv->ah);
104 ath9k_hw_deinit(priv->ah);
105 tasklet_kill(&priv->wmi_tasklet);
106 tasklet_kill(&priv->rx_tasklet);
107 tasklet_kill(&priv->tx_tasklet);
108 kfree(priv->ah);
109 priv->ah = NULL;
110}
111
112static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
113{
114 struct ieee80211_hw *hw = priv->hw;
115
116 wiphy_rfkill_stop_polling(hw->wiphy);
117 ath9k_deinit_leds(priv);
118 ieee80211_unregister_hw(hw);
119 ath9k_rx_cleanup(priv);
120 ath9k_tx_cleanup(priv);
121 ath9k_deinit_priv(priv);
122}
123
124static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
125 u16 service_id,
126 void (*tx) (void *,
127 struct sk_buff *,
128 enum htc_endpoint_id,
129 bool txok),
130 enum htc_endpoint_id *ep_id)
131{
132 struct htc_service_connreq req;
133
134 memset(&req, 0, sizeof(struct htc_service_connreq));
135
136 req.service_id = service_id;
137 req.ep_callbacks.priv = priv;
138 req.ep_callbacks.rx = ath9k_htc_rxep;
139 req.ep_callbacks.tx = tx;
140
141 return htc_connect_service(priv->htc, &req, ep_id);
142}
143
144static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
145{
146 int ret;
147
148 /* WMI CMD*/
149 ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
150 if (ret)
151 goto err;
152
153 /* Beacon */
154 ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, ath9k_htc_beaconep,
155 &priv->beacon_ep);
156 if (ret)
157 goto err;
158
159 /* CAB */
160 ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
161 &priv->cab_ep);
162 if (ret)
163 goto err;
164
165
166 /* UAPSD */
167 ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
168 &priv->uapsd_ep);
169 if (ret)
170 goto err;
171
172 /* MGMT */
173 ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
174 &priv->mgmt_ep);
175 if (ret)
176 goto err;
177
178 /* DATA BE */
179 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
180 &priv->data_be_ep);
181 if (ret)
182 goto err;
183
184 /* DATA BK */
185 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
186 &priv->data_bk_ep);
187 if (ret)
188 goto err;
189
190 /* DATA VI */
191 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
192 &priv->data_vi_ep);
193 if (ret)
194 goto err;
195
196 /* DATA VO */
197 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
198 &priv->data_vo_ep);
199 if (ret)
200 goto err;
201
202 ret = htc_init(priv->htc);
203 if (ret)
204 goto err;
205
206 return 0;
207
208err:
209 dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
210 return ret;
211}
212
213static int ath9k_reg_notifier(struct wiphy *wiphy,
214 struct regulatory_request *request)
215{
216 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
217 struct ath9k_htc_priv *priv = hw->priv;
218
219 return ath_reg_notifier_apply(wiphy, request,
220 ath9k_hw_regulatory(priv->ah));
221}
222
223static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
224{
225 struct ath_hw *ah = (struct ath_hw *) hw_priv;
226 struct ath_common *common = ath9k_hw_common(ah);
227 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
228 __be32 val, reg = cpu_to_be32(reg_offset);
229 int r;
230
231 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
232 (u8 *) &reg, sizeof(reg),
233 (u8 *) &val, sizeof(val),
234 100);
235 if (unlikely(r)) {
236 ath_print(common, ATH_DBG_WMI,
237 "REGISTER READ FAILED: (0x%04x, %d)\n",
238 reg_offset, r);
239 return -EIO;
240 }
241
242 return be32_to_cpu(val);
243}
244
245static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
246{
247 struct ath_hw *ah = (struct ath_hw *) hw_priv;
248 struct ath_common *common = ath9k_hw_common(ah);
249 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
250 __be32 buf[2] = {
251 cpu_to_be32(reg_offset),
252 cpu_to_be32(val),
253 };
254 int r;
255
256 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
257 (u8 *) &buf, sizeof(buf),
258 (u8 *) &val, sizeof(val),
259 100);
260 if (unlikely(r)) {
261 ath_print(common, ATH_DBG_WMI,
262 "REGISTER WRITE FAILED:(0x%04x, %d)\n",
263 reg_offset, r);
264 }
265}
266
267static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
268{
269 struct ath_hw *ah = (struct ath_hw *) hw_priv;
270 struct ath_common *common = ath9k_hw_common(ah);
271 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
272 u32 rsp_status;
273 int r;
274
275 mutex_lock(&priv->wmi->multi_write_mutex);
276
277 /* Store the register/value */
278 priv->wmi->multi_write[priv->wmi->multi_write_idx].reg =
279 cpu_to_be32(reg_offset);
280 priv->wmi->multi_write[priv->wmi->multi_write_idx].val =
281 cpu_to_be32(val);
282
283 priv->wmi->multi_write_idx++;
284
285 /* If the buffer is full, send it out. */
286 if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) {
287 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
288 (u8 *) &priv->wmi->multi_write,
289 sizeof(struct register_write) * priv->wmi->multi_write_idx,
290 (u8 *) &rsp_status, sizeof(rsp_status),
291 100);
292 if (unlikely(r)) {
293 ath_print(common, ATH_DBG_WMI,
294 "REGISTER WRITE FAILED, multi len: %d\n",
295 priv->wmi->multi_write_idx);
296 }
297 priv->wmi->multi_write_idx = 0;
298 }
299
300 mutex_unlock(&priv->wmi->multi_write_mutex);
301}
302
303static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset)
304{
305 struct ath_hw *ah = (struct ath_hw *) hw_priv;
306 struct ath_common *common = ath9k_hw_common(ah);
307 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
308
309 if (atomic_read(&priv->wmi->mwrite_cnt))
310 ath9k_regwrite_buffer(hw_priv, val, reg_offset);
311 else
312 ath9k_regwrite_single(hw_priv, val, reg_offset);
313}
314
315static void ath9k_enable_regwrite_buffer(void *hw_priv)
316{
317 struct ath_hw *ah = (struct ath_hw *) hw_priv;
318 struct ath_common *common = ath9k_hw_common(ah);
319 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
320
321 atomic_inc(&priv->wmi->mwrite_cnt);
322}
323
324static void ath9k_disable_regwrite_buffer(void *hw_priv)
325{
326 struct ath_hw *ah = (struct ath_hw *) hw_priv;
327 struct ath_common *common = ath9k_hw_common(ah);
328 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
329
330 atomic_dec(&priv->wmi->mwrite_cnt);
331}
332
333static void ath9k_regwrite_flush(void *hw_priv)
334{
335 struct ath_hw *ah = (struct ath_hw *) hw_priv;
336 struct ath_common *common = ath9k_hw_common(ah);
337 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
338 u32 rsp_status;
339 int r;
340
341 mutex_lock(&priv->wmi->multi_write_mutex);
342
343 if (priv->wmi->multi_write_idx) {
344 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
345 (u8 *) &priv->wmi->multi_write,
346 sizeof(struct register_write) * priv->wmi->multi_write_idx,
347 (u8 *) &rsp_status, sizeof(rsp_status),
348 100);
349 if (unlikely(r)) {
350 ath_print(common, ATH_DBG_WMI,
351 "REGISTER WRITE FAILED, multi len: %d\n",
352 priv->wmi->multi_write_idx);
353 }
354 priv->wmi->multi_write_idx = 0;
355 }
356
357 mutex_unlock(&priv->wmi->multi_write_mutex);
358}
359
360static const struct ath_ops ath9k_common_ops = {
361 .read = ath9k_regread,
362 .write = ath9k_regwrite,
363 .enable_write_buffer = ath9k_enable_regwrite_buffer,
364 .disable_write_buffer = ath9k_disable_regwrite_buffer,
365 .write_flush = ath9k_regwrite_flush,
366};
367
368static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
369{
370 *csz = L1_CACHE_BYTES >> 2;
371}
372
373static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
374{
375 struct ath_hw *ah = (struct ath_hw *) common->ah;
376
377 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
378
379 if (!ath9k_hw_wait(ah,
380 AR_EEPROM_STATUS_DATA,
381 AR_EEPROM_STATUS_DATA_BUSY |
382 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
383 AH_WAIT_TIMEOUT))
384 return false;
385
386 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
387 AR_EEPROM_STATUS_DATA_VAL);
388
389 return true;
390}
391
392static const struct ath_bus_ops ath9k_usb_bus_ops = {
393 .ath_bus_type = ATH_USB,
394 .read_cachesize = ath_usb_read_cachesize,
395 .eeprom_read = ath_usb_eeprom_read,
396};
397
398static void setup_ht_cap(struct ath9k_htc_priv *priv,
399 struct ieee80211_sta_ht_cap *ht_info)
400{
401 ht_info->ht_supported = true;
402 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
403 IEEE80211_HT_CAP_SM_PS |
404 IEEE80211_HT_CAP_SGI_40 |
405 IEEE80211_HT_CAP_DSSSCCK40;
406
407 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
408 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
409
410 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
411 ht_info->mcs.rx_mask[0] = 0xff;
412 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
413}
414
415static int ath9k_init_queues(struct ath9k_htc_priv *priv)
416{
417 struct ath_common *common = ath9k_hw_common(priv->ah);
418 int i;
419
420 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
421 priv->hwq_map[i] = -1;
422
423 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
424 ath_print(common, ATH_DBG_FATAL,
425 "Unable to setup xmit queue for BE traffic\n");
426 goto err;
427 }
428
429 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
430 ath_print(common, ATH_DBG_FATAL,
431 "Unable to setup xmit queue for BK traffic\n");
432 goto err;
433 }
434 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
435 ath_print(common, ATH_DBG_FATAL,
436 "Unable to setup xmit queue for VI traffic\n");
437 goto err;
438 }
439 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
440 ath_print(common, ATH_DBG_FATAL,
441 "Unable to setup xmit queue for VO traffic\n");
442 goto err;
443 }
444
445 return 0;
446
447err:
448 return -EINVAL;
449}
450
451static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
452{
453 struct ath_common *common = ath9k_hw_common(priv->ah);
454 int i = 0;
455
456 /* Get the hardware key cache size. */
457 common->keymax = priv->ah->caps.keycache_size;
458 if (common->keymax > ATH_KEYMAX) {
459 ath_print(common, ATH_DBG_ANY,
460 "Warning, using only %u entries in %u key cache\n",
461 ATH_KEYMAX, common->keymax);
462 common->keymax = ATH_KEYMAX;
463 }
464
465 /*
466 * Reset the key cache since some parts do not
467 * reset the contents on initial power up.
468 */
469 for (i = 0; i < common->keymax; i++)
470 ath9k_hw_keyreset(priv->ah, (u16) i);
471
472 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
473 ATH9K_CIPHER_TKIP, NULL)) {
474 /*
475 * Whether we should enable h/w TKIP MIC.
476 * XXX: if we don't support WME TKIP MIC, then we wouldn't
477 * report WMM capable, so it's always safe to turn on
478 * TKIP MIC in this case.
479 */
480 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
481 }
482
483 /*
484 * Check whether the separate key cache entries
485 * are required to handle both tx+rx MIC keys.
486 * With split mic keys the number of stations is limited
487 * to 27 otherwise 59.
488 */
489 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
490 ATH9K_CIPHER_TKIP, NULL)
491 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
492 ATH9K_CIPHER_MIC, NULL)
493 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
494 0, NULL))
495 common->splitmic = 1;
496
497 /* turn on mcast key search if possible */
498 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
499 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
500 1, 1, NULL);
501}
502
503static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
504{
505 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
506 priv->sbands[IEEE80211_BAND_2GHZ].channels =
507 ath9k_2ghz_channels;
508 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
509 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
510 ARRAY_SIZE(ath9k_2ghz_channels);
511 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
512 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
513 ARRAY_SIZE(ath9k_legacy_rates);
514 }
515}
516
517static void ath9k_init_misc(struct ath9k_htc_priv *priv)
518{
519 struct ath_common *common = ath9k_hw_common(priv->ah);
520
521 common->tx_chainmask = priv->ah->caps.tx_chainmask;
522 common->rx_chainmask = priv->ah->caps.rx_chainmask;
523
524 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
525 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
526
527 priv->op_flags |= OP_TXAGGR;
528 priv->ah->opmode = NL80211_IFTYPE_STATION;
529}
530
531static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
532{
533 struct ath_hw *ah = NULL;
534 struct ath_common *common;
535 int ret = 0, csz = 0;
536
537 priv->op_flags |= OP_INVALID;
538
539 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
540 if (!ah)
541 return -ENOMEM;
542
543 ah->hw_version.devid = devid;
544 ah->hw_version.subsysid = 0; /* FIXME */
545 priv->ah = ah;
546
547 common = ath9k_hw_common(ah);
548 common->ops = &ath9k_common_ops;
549 common->bus_ops = &ath9k_usb_bus_ops;
550 common->ah = ah;
551 common->hw = priv->hw;
552 common->priv = priv;
553 common->debug_mask = ath9k_debug;
554
555 spin_lock_init(&priv->wmi->wmi_lock);
556 spin_lock_init(&priv->beacon_lock);
557 spin_lock_init(&priv->tx_lock);
558 mutex_init(&priv->mutex);
559 mutex_init(&priv->aggr_work.mutex);
560 mutex_init(&priv->htc_pm_lock);
561 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
562 (unsigned long)priv);
563 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
564 (unsigned long)priv);
565 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
566 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
567 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
568 INIT_WORK(&priv->ps_work, ath9k_ps_work);
569
570 /*
571 * Cache line size is used to size and align various
572 * structures used to communicate with the hardware.
573 */
574 ath_read_cachesize(common, &csz);
575 common->cachelsz = csz << 2; /* convert to bytes */
576
577 ret = ath9k_hw_init(ah);
578 if (ret) {
579 ath_print(common, ATH_DBG_FATAL,
580 "Unable to initialize hardware; "
581 "initialization status: %d\n", ret);
582 goto err_hw;
583 }
584
585 ret = ath9k_htc_init_debug(ah);
586 if (ret) {
587 ath_print(common, ATH_DBG_FATAL,
588 "Unable to create debugfs files\n");
589 goto err_debug;
590 }
591
592 ret = ath9k_init_queues(priv);
593 if (ret)
594 goto err_queues;
595
596 ath9k_init_crypto(priv);
597 ath9k_init_channels_rates(priv);
598 ath9k_init_misc(priv);
599
600 return 0;
601
602err_queues:
603 ath9k_htc_exit_debug(ah);
604err_debug:
605 ath9k_hw_deinit(ah);
606err_hw:
607
608 kfree(ah);
609 priv->ah = NULL;
610
611 return ret;
612}
613
614static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
615 struct ieee80211_hw *hw)
616{
617 struct ath_common *common = ath9k_hw_common(priv->ah);
618
619 hw->flags = IEEE80211_HW_SIGNAL_DBM |
620 IEEE80211_HW_AMPDU_AGGREGATION |
621 IEEE80211_HW_SPECTRUM_MGMT |
622 IEEE80211_HW_HAS_RATE_CONTROL |
623 IEEE80211_HW_RX_INCLUDES_FCS |
624 IEEE80211_HW_SUPPORTS_PS |
625 IEEE80211_HW_PS_NULLFUNC_STACK;
626
627 hw->wiphy->interface_modes =
628 BIT(NL80211_IFTYPE_STATION) |
629 BIT(NL80211_IFTYPE_ADHOC);
630
631 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
632
633 hw->queues = 4;
634 hw->channel_change_time = 5000;
635 hw->max_listen_interval = 10;
636 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
637 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
638
639 /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
640 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
641 sizeof(struct htc_frame_hdr) + 4;
642
643 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
644 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
645 &priv->sbands[IEEE80211_BAND_2GHZ];
646
647 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
648 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
649 setup_ht_cap(priv,
650 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
651 }
652
653 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
654}
655
656static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
657{
658 struct ieee80211_hw *hw = priv->hw;
659 struct ath_common *common;
660 struct ath_hw *ah;
661 int error = 0;
662 struct ath_regulatory *reg;
663
664 /* Bring up device */
665 error = ath9k_init_priv(priv, devid);
666 if (error != 0)
667 goto err_init;
668
669 ah = priv->ah;
670 common = ath9k_hw_common(ah);
671 ath9k_set_hw_capab(priv, hw);
672
673 /* Initialize regulatory */
674 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
675 ath9k_reg_notifier);
676 if (error)
677 goto err_regd;
678
679 reg = &common->regulatory;
680
681 /* Setup TX */
682 error = ath9k_tx_init(priv);
683 if (error != 0)
684 goto err_tx;
685
686 /* Setup RX */
687 error = ath9k_rx_init(priv);
688 if (error != 0)
689 goto err_rx;
690
691 /* Register with mac80211 */
692 error = ieee80211_register_hw(hw);
693 if (error)
694 goto err_register;
695
696 /* Handle world regulatory */
697 if (!ath_is_world_regd(reg)) {
698 error = regulatory_hint(hw->wiphy, reg->alpha2);
699 if (error)
700 goto err_world;
701 }
702
703 ath9k_init_leds(priv);
704 ath9k_start_rfkill_poll(priv);
705
706 return 0;
707
708err_world:
709 ieee80211_unregister_hw(hw);
710err_register:
711 ath9k_rx_cleanup(priv);
712err_rx:
713 ath9k_tx_cleanup(priv);
714err_tx:
715 /* Nothing */
716err_regd:
717 ath9k_deinit_priv(priv);
718err_init:
719 return error;
720}
721
722int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
723 u16 devid)
724{
725 struct ieee80211_hw *hw;
726 struct ath9k_htc_priv *priv;
727 int ret;
728
729 hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
730 if (!hw)
731 return -ENOMEM;
732
733 priv = hw->priv;
734 priv->hw = hw;
735 priv->htc = htc_handle;
736 priv->dev = dev;
737 htc_handle->drv_priv = priv;
738 SET_IEEE80211_DEV(hw, priv->dev);
739
740 ret = ath9k_htc_wait_for_target(priv);
741 if (ret)
742 goto err_free;
743
744 priv->wmi = ath9k_init_wmi(priv);
745 if (!priv->wmi) {
746 ret = -EINVAL;
747 goto err_free;
748 }
749
750 ret = ath9k_init_htc_services(priv);
751 if (ret)
752 goto err_init;
753
754 /* The device may have been unplugged earlier. */
755 priv->op_flags &= ~OP_UNPLUGGED;
756
757 ret = ath9k_init_device(priv, devid);
758 if (ret)
759 goto err_init;
760
761 return 0;
762
763err_init:
764 ath9k_deinit_wmi(priv);
765err_free:
766 ieee80211_free_hw(hw);
767 return ret;
768}
769
770void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
771{
772 if (htc_handle->drv_priv) {
773
774 /* Check if the device has been yanked out. */
775 if (hotunplug)
776 htc_handle->drv_priv->op_flags |= OP_UNPLUGGED;
777
778 ath9k_deinit_device(htc_handle->drv_priv);
779 ath9k_deinit_wmi(htc_handle->drv_priv);
780 ieee80211_free_hw(htc_handle->drv_priv->hw);
781 }
782}
783
784#ifdef CONFIG_PM
785int ath9k_htc_resume(struct htc_target *htc_handle)
786{
787 int ret;
788
789 ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
790 if (ret)
791 return ret;
792
793 ret = ath9k_init_htc_services(htc_handle->drv_priv);
794 return ret;
795}
796#endif
797
798static int __init ath9k_htc_init(void)
799{
800 int error;
801
802 error = ath9k_htc_debug_create_root();
803 if (error < 0) {
804 printk(KERN_ERR
805 "ath9k_htc: Unable to create debugfs root: %d\n",
806 error);
807 goto err_dbg;
808 }
809
810 error = ath9k_hif_usb_init();
811 if (error < 0) {
812 printk(KERN_ERR
813 "ath9k_htc: No USB devices found,"
814 " driver not installed.\n");
815 error = -ENODEV;
816 goto err_usb;
817 }
818
819 return 0;
820
821err_usb:
822 ath9k_htc_debug_remove_root();
823err_dbg:
824 return error;
825}
826module_init(ath9k_htc_init);
827
828static void __exit ath9k_htc_exit(void)
829{
830 ath9k_hif_usb_exit();
831 ath9k_htc_debug_remove_root();
832 printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
833}
834module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
new file mode 100644
index 000000000000..9d371c18eb41
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -0,0 +1,1775 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31
32 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
36 priv->curtxpow = txpow;
37 }
38}
39
40/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
41static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
42 struct ath9k_channel *ichan)
43{
44 enum htc_phymode mode;
45
46 mode = HTC_MODE_AUTO;
47
48 switch (ichan->chanmode) {
49 case CHANNEL_G:
50 case CHANNEL_G_HT20:
51 case CHANNEL_G_HT40PLUS:
52 case CHANNEL_G_HT40MINUS:
53 mode = HTC_MODE_11NG;
54 break;
55 case CHANNEL_A:
56 case CHANNEL_A_HT20:
57 case CHANNEL_A_HT40PLUS:
58 case CHANNEL_A_HT40MINUS:
59 mode = HTC_MODE_11NA;
60 break;
61 default:
62 break;
63 }
64
65 return mode;
66}
67
68static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
69 enum ath9k_power_mode mode)
70{
71 bool ret;
72
73 mutex_lock(&priv->htc_pm_lock);
74 ret = ath9k_hw_setpower(priv->ah, mode);
75 mutex_unlock(&priv->htc_pm_lock);
76
77 return ret;
78}
79
80void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
81{
82 mutex_lock(&priv->htc_pm_lock);
83 if (++priv->ps_usecount != 1)
84 goto unlock;
85 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
86
87unlock:
88 mutex_unlock(&priv->htc_pm_lock);
89}
90
91void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
92{
93 mutex_lock(&priv->htc_pm_lock);
94 if (--priv->ps_usecount != 0)
95 goto unlock;
96
97 if (priv->ps_idle)
98 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
99 else if (priv->ps_enabled)
100 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
101
102unlock:
103 mutex_unlock(&priv->htc_pm_lock);
104}
105
106void ath9k_ps_work(struct work_struct *work)
107{
108 struct ath9k_htc_priv *priv =
109 container_of(work, struct ath9k_htc_priv,
110 ps_work);
111 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
112
113 /* The chip wakes up after receiving the first beacon
114 while network sleep is enabled. For the driver to
115 be in sync with the hw, set the chip to awake and
116 only then set it to sleep.
117 */
118 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
119}
120
121static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
122 struct ieee80211_hw *hw,
123 struct ath9k_channel *hchan)
124{
125 struct ath_hw *ah = priv->ah;
126 struct ath_common *common = ath9k_hw_common(ah);
127 struct ieee80211_conf *conf = &common->hw->conf;
128 bool fastcc = true;
129 struct ieee80211_channel *channel = hw->conf.channel;
130 enum htc_phymode mode;
131 __be16 htc_mode;
132 u8 cmd_rsp;
133 int ret;
134
135 if (priv->op_flags & OP_INVALID)
136 return -EIO;
137
138 if (priv->op_flags & OP_FULL_RESET)
139 fastcc = false;
140
141 /* Fiddle around with fastcc later on, for now just use full reset */
142 fastcc = false;
143 ath9k_htc_ps_wakeup(priv);
144 htc_stop(priv->htc);
145 WMI_CMD(WMI_DISABLE_INTR_CMDID);
146 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
147 WMI_CMD(WMI_STOP_RECV_CMDID);
148
149 ath_print(common, ATH_DBG_CONFIG,
150 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
151 priv->ah->curchan->channel,
152 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
153
154 ret = ath9k_hw_reset(ah, hchan, fastcc);
155 if (ret) {
156 ath_print(common, ATH_DBG_FATAL,
157 "Unable to reset channel (%u Mhz) "
158 "reset status %d\n", channel->center_freq, ret);
159 goto err;
160 }
161
162 ath_update_txpow(priv);
163
164 WMI_CMD(WMI_START_RECV_CMDID);
165 if (ret)
166 goto err;
167
168 ath9k_host_rx_init(priv);
169
170 mode = ath9k_htc_get_curmode(priv, hchan);
171 htc_mode = cpu_to_be16(mode);
172 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
173 if (ret)
174 goto err;
175
176 WMI_CMD(WMI_ENABLE_INTR_CMDID);
177 if (ret)
178 goto err;
179
180 htc_start(priv->htc);
181
182 priv->op_flags &= ~OP_FULL_RESET;
183err:
184 ath9k_htc_ps_restore(priv);
185 return ret;
186}
187
188static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
189{
190 struct ath_common *common = ath9k_hw_common(priv->ah);
191 struct ath9k_htc_target_vif hvif;
192 int ret = 0;
193 u8 cmd_rsp;
194
195 if (priv->nvifs > 0)
196 return -ENOBUFS;
197
198 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
199 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
200
201 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
202 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
203 hvif.index = priv->nvifs;
204
205 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
206 if (ret)
207 return ret;
208
209 priv->nvifs++;
210 return 0;
211}
212
213static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
214{
215 struct ath_common *common = ath9k_hw_common(priv->ah);
216 struct ath9k_htc_target_vif hvif;
217 int ret = 0;
218 u8 cmd_rsp;
219
220 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
221 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
222 hvif.index = 0; /* Should do for now */
223 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
224 priv->nvifs--;
225
226 return ret;
227}
228
229static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
230 struct ieee80211_vif *vif,
231 struct ieee80211_sta *sta)
232{
233 struct ath_common *common = ath9k_hw_common(priv->ah);
234 struct ath9k_htc_target_sta tsta;
235 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
236 struct ath9k_htc_sta *ista;
237 int ret;
238 u8 cmd_rsp;
239
240 if (priv->nstations >= ATH9K_HTC_MAX_STA)
241 return -ENOBUFS;
242
243 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
244
245 if (sta) {
246 ista = (struct ath9k_htc_sta *) sta->drv_priv;
247 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
248 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
249 tsta.associd = common->curaid;
250 tsta.is_vif_sta = 0;
251 tsta.valid = true;
252 ista->index = priv->nstations;
253 } else {
254 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
255 tsta.is_vif_sta = 1;
256 }
257
258 tsta.sta_index = priv->nstations;
259 tsta.vif_index = avp->index;
260 tsta.maxampdu = 0xffff;
261 if (sta && sta->ht_cap.ht_supported)
262 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
263
264 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
265 if (ret) {
266 if (sta)
267 ath_print(common, ATH_DBG_FATAL,
268 "Unable to add station entry for: %pM\n", sta->addr);
269 return ret;
270 }
271
272 if (sta)
273 ath_print(common, ATH_DBG_CONFIG,
274 "Added a station entry for: %pM (idx: %d)\n",
275 sta->addr, tsta.sta_index);
276
277 priv->nstations++;
278 return 0;
279}
280
281static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
282 struct ieee80211_vif *vif,
283 struct ieee80211_sta *sta)
284{
285 struct ath_common *common = ath9k_hw_common(priv->ah);
286 struct ath9k_htc_sta *ista;
287 int ret;
288 u8 cmd_rsp, sta_idx;
289
290 if (sta) {
291 ista = (struct ath9k_htc_sta *) sta->drv_priv;
292 sta_idx = ista->index;
293 } else {
294 sta_idx = 0;
295 }
296
297 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
298 if (ret) {
299 if (sta)
300 ath_print(common, ATH_DBG_FATAL,
301 "Unable to remove station entry for: %pM\n",
302 sta->addr);
303 return ret;
304 }
305
306 if (sta)
307 ath_print(common, ATH_DBG_CONFIG,
308 "Removed a station entry for: %pM (idx: %d)\n",
309 sta->addr, sta_idx);
310
311 priv->nstations--;
312 return 0;
313}
314
315static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
316{
317 struct ath9k_htc_cap_target tcap;
318 int ret;
319 u8 cmd_rsp;
320
321 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
322
323 /* FIXME: Values are hardcoded */
324 tcap.flags = 0x240c40;
325 tcap.flags_ext = 0x80601000;
326 tcap.ampdu_limit = 0xffff0000;
327 tcap.ampdu_subframes = 20;
328 tcap.tx_chainmask_legacy = 1;
329 tcap.protmode = 1;
330 tcap.tx_chainmask = 1;
331
332 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
333
334 return ret;
335}
336
337static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
338 struct ieee80211_vif *vif,
339 struct ieee80211_sta *sta)
340{
341 struct ath_common *common = ath9k_hw_common(priv->ah);
342 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
343 struct ieee80211_supported_band *sband;
344 struct ath9k_htc_target_rate trate;
345 u32 caps = 0;
346 u8 cmd_rsp;
347 int i, j, ret;
348
349 memset(&trate, 0, sizeof(trate));
350
351 /* Only 2GHz is supported */
352 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
353
354 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
355 if (sta->supp_rates[sband->band] & BIT(i)) {
356 priv->tgt_rate.rates.legacy_rates.rs_rates[j]
357 = (sband->bitrates[i].bitrate * 2) / 10;
358 j++;
359 }
360 }
361 priv->tgt_rate.rates.legacy_rates.rs_nrates = j;
362
363 if (sta->ht_cap.ht_supported) {
364 for (i = 0, j = 0; i < 77; i++) {
365 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
366 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i;
367 if (j == ATH_HTC_RATE_MAX)
368 break;
369 }
370 priv->tgt_rate.rates.ht_rates.rs_nrates = j;
371
372 caps = WLAN_RC_HT_FLAG;
373 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
374 caps |= WLAN_RC_40_FLAG;
375 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
376 caps |= WLAN_RC_SGI_FLAG;
377
378 }
379
380 priv->tgt_rate.sta_index = ista->index;
381 priv->tgt_rate.isnew = 1;
382 trate = priv->tgt_rate;
383 priv->tgt_rate.capflags = cpu_to_be32(caps);
384 trate.capflags = cpu_to_be32(caps);
385
386 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
387 if (ret) {
388 ath_print(common, ATH_DBG_FATAL,
389 "Unable to initialize Rate information on target\n");
390 return ret;
391 }
392
393 ath_print(common, ATH_DBG_CONFIG,
394 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
395 return 0;
396}
397
398static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40)
399{
400 struct ath9k_htc_priv *priv = hw->priv;
401 struct ieee80211_conf *conf = &hw->conf;
402
403 if (!conf_is_ht(conf))
404 return false;
405
406 if (!(priv->op_flags & OP_ASSOCIATED) ||
407 (priv->op_flags & OP_SCANNING))
408 return false;
409
410 if (conf_is_ht40(conf)) {
411 if (priv->ah->curchan->chanmode &
412 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) {
413 return false;
414 } else {
415 *cw40 = true;
416 return true;
417 }
418 } else { /* ht20 */
419 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
420 return false;
421 else
422 return true;
423 }
424}
425
426static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
427{
428 struct ath9k_htc_target_rate trate;
429 struct ath_common *common = ath9k_hw_common(priv->ah);
430 int ret;
431 u32 caps = be32_to_cpu(priv->tgt_rate.capflags);
432 u8 cmd_rsp;
433
434 memset(&trate, 0, sizeof(trate));
435
436 trate = priv->tgt_rate;
437
438 if (is_cw40)
439 caps |= WLAN_RC_40_FLAG;
440 else
441 caps &= ~WLAN_RC_40_FLAG;
442
443 priv->tgt_rate.capflags = cpu_to_be32(caps);
444 trate.capflags = cpu_to_be32(caps);
445
446 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
447 if (ret) {
448 ath_print(common, ATH_DBG_FATAL,
449 "Unable to update Rate information on target\n");
450 return;
451 }
452
453 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with "
454 "caps:0x%x on target\n", priv->tgt_rate.capflags);
455}
456
457static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
458 struct ieee80211_vif *vif,
459 u8 *sta_addr, u8 tid, bool oper)
460{
461 struct ath_common *common = ath9k_hw_common(priv->ah);
462 struct ath9k_htc_target_aggr aggr;
463 struct ieee80211_sta *sta = NULL;
464 struct ath9k_htc_sta *ista;
465 int ret = 0;
466 u8 cmd_rsp;
467
468 if (tid >= ATH9K_HTC_MAX_TID)
469 return -EINVAL;
470
471 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
472
473 rcu_read_lock();
474
475 /* Check if we are able to retrieve the station */
476 sta = ieee80211_find_sta(vif, sta_addr);
477 if (!sta) {
478 rcu_read_unlock();
479 return -EINVAL;
480 }
481
482 ista = (struct ath9k_htc_sta *) sta->drv_priv;
483
484 if (oper)
485 ista->tid_state[tid] = AGGR_START;
486 else
487 ista->tid_state[tid] = AGGR_STOP;
488
489 aggr.sta_index = ista->index;
490
491 rcu_read_unlock();
492
493 aggr.tidno = tid;
494 aggr.aggr_enable = oper;
495
496 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
497 if (ret)
498 ath_print(common, ATH_DBG_CONFIG,
499 "Unable to %s TX aggregation for (%pM, %d)\n",
500 (oper) ? "start" : "stop", sta->addr, tid);
501 else
502 ath_print(common, ATH_DBG_CONFIG,
503 "%s aggregation for (%pM, %d)\n",
504 (oper) ? "Starting" : "Stopping", sta->addr, tid);
505
506 return ret;
507}
508
509void ath9k_htc_aggr_work(struct work_struct *work)
510{
511 int ret = 0;
512 struct ath9k_htc_priv *priv =
513 container_of(work, struct ath9k_htc_priv,
514 ath9k_aggr_work.work);
515 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
516
517 mutex_lock(&wk->mutex);
518
519 switch (wk->action) {
520 case IEEE80211_AMPDU_TX_START:
521 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
522 wk->tid, true);
523 if (!ret)
524 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
525 wk->tid);
526 break;
527 case IEEE80211_AMPDU_TX_STOP:
528 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
529 wk->tid, false);
530 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
531 break;
532 default:
533 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
534 "Unknown AMPDU action\n");
535 }
536
537 mutex_unlock(&wk->mutex);
538}
539
540/*********/
541/* DEBUG */
542/*********/
543
544#ifdef CONFIG_ATH9K_HTC_DEBUGFS
545
546static int ath9k_debugfs_open(struct inode *inode, struct file *file)
547{
548 file->private_data = inode->i_private;
549 return 0;
550}
551
552static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
553 size_t count, loff_t *ppos)
554{
555 struct ath9k_htc_priv *priv =
556 (struct ath9k_htc_priv *) file->private_data;
557 struct ath9k_htc_target_stats cmd_rsp;
558 char buf[512];
559 unsigned int len = 0;
560 int ret = 0;
561
562 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
563
564 WMI_CMD(WMI_TGT_STATS_CMDID);
565 if (ret)
566 return -EINVAL;
567
568
569 len += snprintf(buf + len, sizeof(buf) - len,
570 "%19s : %10u\n", "TX Short Retries",
571 be32_to_cpu(cmd_rsp.tx_shortretry));
572 len += snprintf(buf + len, sizeof(buf) - len,
573 "%19s : %10u\n", "TX Long Retries",
574 be32_to_cpu(cmd_rsp.tx_longretry));
575 len += snprintf(buf + len, sizeof(buf) - len,
576 "%19s : %10u\n", "TX Xretries",
577 be32_to_cpu(cmd_rsp.tx_xretries));
578 len += snprintf(buf + len, sizeof(buf) - len,
579 "%19s : %10u\n", "TX Unaggr. Xretries",
580 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
581 len += snprintf(buf + len, sizeof(buf) - len,
582 "%19s : %10u\n", "TX Xretries (HT)",
583 be32_to_cpu(cmd_rsp.ht_tx_xretries));
584 len += snprintf(buf + len, sizeof(buf) - len,
585 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
586
587 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
588}
589
590static const struct file_operations fops_tgt_stats = {
591 .read = read_file_tgt_stats,
592 .open = ath9k_debugfs_open,
593 .owner = THIS_MODULE
594};
595
596static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
597 size_t count, loff_t *ppos)
598{
599 struct ath9k_htc_priv *priv =
600 (struct ath9k_htc_priv *) file->private_data;
601 char buf[512];
602 unsigned int len = 0;
603
604 len += snprintf(buf + len, sizeof(buf) - len,
605 "%20s : %10u\n", "Buffers queued",
606 priv->debug.tx_stats.buf_queued);
607 len += snprintf(buf + len, sizeof(buf) - len,
608 "%20s : %10u\n", "Buffers completed",
609 priv->debug.tx_stats.buf_completed);
610 len += snprintf(buf + len, sizeof(buf) - len,
611 "%20s : %10u\n", "SKBs queued",
612 priv->debug.tx_stats.skb_queued);
613 len += snprintf(buf + len, sizeof(buf) - len,
614 "%20s : %10u\n", "SKBs completed",
615 priv->debug.tx_stats.skb_completed);
616 len += snprintf(buf + len, sizeof(buf) - len,
617 "%20s : %10u\n", "SKBs dropped",
618 priv->debug.tx_stats.skb_dropped);
619
620 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
621}
622
623static const struct file_operations fops_xmit = {
624 .read = read_file_xmit,
625 .open = ath9k_debugfs_open,
626 .owner = THIS_MODULE
627};
628
629static ssize_t read_file_recv(struct file *file, char __user *user_buf,
630 size_t count, loff_t *ppos)
631{
632 struct ath9k_htc_priv *priv =
633 (struct ath9k_htc_priv *) file->private_data;
634 char buf[512];
635 unsigned int len = 0;
636
637 len += snprintf(buf + len, sizeof(buf) - len,
638 "%20s : %10u\n", "SKBs allocated",
639 priv->debug.rx_stats.skb_allocated);
640 len += snprintf(buf + len, sizeof(buf) - len,
641 "%20s : %10u\n", "SKBs completed",
642 priv->debug.rx_stats.skb_completed);
643 len += snprintf(buf + len, sizeof(buf) - len,
644 "%20s : %10u\n", "SKBs Dropped",
645 priv->debug.rx_stats.skb_dropped);
646
647 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
648}
649
650static const struct file_operations fops_recv = {
651 .read = read_file_recv,
652 .open = ath9k_debugfs_open,
653 .owner = THIS_MODULE
654};
655
656int ath9k_htc_init_debug(struct ath_hw *ah)
657{
658 struct ath_common *common = ath9k_hw_common(ah);
659 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
660
661 if (!ath9k_debugfs_root)
662 return -ENOENT;
663
664 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
665 ath9k_debugfs_root);
666 if (!priv->debug.debugfs_phy)
667 goto err;
668
669 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
670 priv->debug.debugfs_phy,
671 priv, &fops_tgt_stats);
672 if (!priv->debug.debugfs_tgt_stats)
673 goto err;
674
675
676 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
677 priv->debug.debugfs_phy,
678 priv, &fops_xmit);
679 if (!priv->debug.debugfs_xmit)
680 goto err;
681
682 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
683 priv->debug.debugfs_phy,
684 priv, &fops_recv);
685 if (!priv->debug.debugfs_recv)
686 goto err;
687
688 return 0;
689
690err:
691 ath9k_htc_exit_debug(ah);
692 return -ENOMEM;
693}
694
695void ath9k_htc_exit_debug(struct ath_hw *ah)
696{
697 struct ath_common *common = ath9k_hw_common(ah);
698 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
699
700 debugfs_remove(priv->debug.debugfs_recv);
701 debugfs_remove(priv->debug.debugfs_xmit);
702 debugfs_remove(priv->debug.debugfs_tgt_stats);
703 debugfs_remove(priv->debug.debugfs_phy);
704}
705
706int ath9k_htc_debug_create_root(void)
707{
708 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
709 if (!ath9k_debugfs_root)
710 return -ENOENT;
711
712 return 0;
713}
714
715void ath9k_htc_debug_remove_root(void)
716{
717 debugfs_remove(ath9k_debugfs_root);
718 ath9k_debugfs_root = NULL;
719}
720
721#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
722
723/*******/
724/* ANI */
725/*******/
726
727static void ath_start_ani(struct ath9k_htc_priv *priv)
728{
729 struct ath_common *common = ath9k_hw_common(priv->ah);
730 unsigned long timestamp = jiffies_to_msecs(jiffies);
731
732 common->ani.longcal_timer = timestamp;
733 common->ani.shortcal_timer = timestamp;
734 common->ani.checkani_timer = timestamp;
735
736 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
737 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
738}
739
740void ath9k_ani_work(struct work_struct *work)
741{
742 struct ath9k_htc_priv *priv =
743 container_of(work, struct ath9k_htc_priv,
744 ath9k_ani_work.work);
745 struct ath_hw *ah = priv->ah;
746 struct ath_common *common = ath9k_hw_common(ah);
747 bool longcal = false;
748 bool shortcal = false;
749 bool aniflag = false;
750 unsigned int timestamp = jiffies_to_msecs(jiffies);
751 u32 cal_interval, short_cal_interval;
752
753 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
754
755 /* Only calibrate if awake */
756 if (ah->power_mode != ATH9K_PM_AWAKE)
757 goto set_timer;
758
759 /* Long calibration runs independently of short calibration. */
760 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
761 longcal = true;
762 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
763 common->ani.longcal_timer = timestamp;
764 }
765
766 /* Short calibration applies only while caldone is false */
767 if (!common->ani.caldone) {
768 if ((timestamp - common->ani.shortcal_timer) >=
769 short_cal_interval) {
770 shortcal = true;
771 ath_print(common, ATH_DBG_ANI,
772 "shortcal @%lu\n", jiffies);
773 common->ani.shortcal_timer = timestamp;
774 common->ani.resetcal_timer = timestamp;
775 }
776 } else {
777 if ((timestamp - common->ani.resetcal_timer) >=
778 ATH_RESTART_CALINTERVAL) {
779 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
780 if (common->ani.caldone)
781 common->ani.resetcal_timer = timestamp;
782 }
783 }
784
785 /* Verify whether we must check ANI */
786 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
787 aniflag = true;
788 common->ani.checkani_timer = timestamp;
789 }
790
791 /* Skip all processing if there's nothing to do. */
792 if (longcal || shortcal || aniflag) {
793
794 ath9k_htc_ps_wakeup(priv);
795
796 /* Call ANI routine if necessary */
797 if (aniflag)
798 ath9k_hw_ani_monitor(ah, ah->curchan);
799
800 /* Perform calibration if necessary */
801 if (longcal || shortcal) {
802 common->ani.caldone =
803 ath9k_hw_calibrate(ah, ah->curchan,
804 common->rx_chainmask,
805 longcal);
806
807 if (longcal)
808 common->ani.noise_floor =
809 ath9k_hw_getchan_noise(ah, ah->curchan);
810
811 ath_print(common, ATH_DBG_ANI,
812 " calibrate chan %u/%x nf: %d\n",
813 ah->curchan->channel,
814 ah->curchan->channelFlags,
815 common->ani.noise_floor);
816 }
817
818 ath9k_htc_ps_restore(priv);
819 }
820
821set_timer:
822 /*
823 * Set timer interval based on previous results.
824 * The interval must be the shortest necessary to satisfy ANI,
825 * short calibration and long calibration.
826 */
827 cal_interval = ATH_LONG_CALINTERVAL;
828 if (priv->ah->config.enable_ani)
829 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
830 if (!common->ani.caldone)
831 cal_interval = min(cal_interval, (u32)short_cal_interval);
832
833 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
834 msecs_to_jiffies(cal_interval));
835}
836
837/*******/
838/* LED */
839/*******/
840
841static void ath9k_led_blink_work(struct work_struct *work)
842{
843 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
844 ath9k_led_blink_work.work);
845
846 if (!(priv->op_flags & OP_LED_ASSOCIATED))
847 return;
848
849 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
850 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
851 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
852 else
853 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
854 (priv->op_flags & OP_LED_ON) ? 1 : 0);
855
856 ieee80211_queue_delayed_work(priv->hw,
857 &priv->ath9k_led_blink_work,
858 (priv->op_flags & OP_LED_ON) ?
859 msecs_to_jiffies(priv->led_off_duration) :
860 msecs_to_jiffies(priv->led_on_duration));
861
862 priv->led_on_duration = priv->led_on_cnt ?
863 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
864 ATH_LED_ON_DURATION_IDLE;
865 priv->led_off_duration = priv->led_off_cnt ?
866 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
867 ATH_LED_OFF_DURATION_IDLE;
868 priv->led_on_cnt = priv->led_off_cnt = 0;
869
870 if (priv->op_flags & OP_LED_ON)
871 priv->op_flags &= ~OP_LED_ON;
872 else
873 priv->op_flags |= OP_LED_ON;
874}
875
876static void ath9k_led_brightness_work(struct work_struct *work)
877{
878 struct ath_led *led = container_of(work, struct ath_led,
879 brightness_work.work);
880 struct ath9k_htc_priv *priv = led->priv;
881
882 switch (led->brightness) {
883 case LED_OFF:
884 if (led->led_type == ATH_LED_ASSOC ||
885 led->led_type == ATH_LED_RADIO) {
886 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
887 (led->led_type == ATH_LED_RADIO));
888 priv->op_flags &= ~OP_LED_ASSOCIATED;
889 if (led->led_type == ATH_LED_RADIO)
890 priv->op_flags &= ~OP_LED_ON;
891 } else {
892 priv->led_off_cnt++;
893 }
894 break;
895 case LED_FULL:
896 if (led->led_type == ATH_LED_ASSOC) {
897 priv->op_flags |= OP_LED_ASSOCIATED;
898 ieee80211_queue_delayed_work(priv->hw,
899 &priv->ath9k_led_blink_work, 0);
900 } else if (led->led_type == ATH_LED_RADIO) {
901 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
902 priv->op_flags |= OP_LED_ON;
903 } else {
904 priv->led_on_cnt++;
905 }
906 break;
907 default:
908 break;
909 }
910}
911
912static void ath9k_led_brightness(struct led_classdev *led_cdev,
913 enum led_brightness brightness)
914{
915 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
916 struct ath9k_htc_priv *priv = led->priv;
917
918 led->brightness = brightness;
919 if (!(priv->op_flags & OP_LED_DEINIT))
920 ieee80211_queue_delayed_work(priv->hw,
921 &led->brightness_work, 0);
922}
923
924static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
925{
926 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
927 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
928 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
929 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
930}
931
932static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
933 char *trigger)
934{
935 int ret;
936
937 led->priv = priv;
938 led->led_cdev.name = led->name;
939 led->led_cdev.default_trigger = trigger;
940 led->led_cdev.brightness_set = ath9k_led_brightness;
941
942 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
943 if (ret)
944 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
945 "Failed to register led:%s", led->name);
946 else
947 led->registered = 1;
948
949 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
950
951 return ret;
952}
953
954static void ath9k_unregister_led(struct ath_led *led)
955{
956 if (led->registered) {
957 led_classdev_unregister(&led->led_cdev);
958 led->registered = 0;
959 }
960}
961
962void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
963{
964 priv->op_flags |= OP_LED_DEINIT;
965 ath9k_unregister_led(&priv->assoc_led);
966 priv->op_flags &= ~OP_LED_ASSOCIATED;
967 ath9k_unregister_led(&priv->tx_led);
968 ath9k_unregister_led(&priv->rx_led);
969 ath9k_unregister_led(&priv->radio_led);
970}
971
972void ath9k_init_leds(struct ath9k_htc_priv *priv)
973{
974 char *trigger;
975 int ret;
976
977 if (AR_SREV_9287(priv->ah))
978 priv->ah->led_pin = ATH_LED_PIN_9287;
979 else if (AR_SREV_9271(priv->ah))
980 priv->ah->led_pin = ATH_LED_PIN_9271;
981 else
982 priv->ah->led_pin = ATH_LED_PIN_DEF;
983
984 /* Configure gpio 1 for output */
985 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
986 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
987 /* LED off, active low */
988 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
989
990 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
991
992 trigger = ieee80211_get_radio_led_name(priv->hw);
993 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
994 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
995 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
996 priv->radio_led.led_type = ATH_LED_RADIO;
997 if (ret)
998 goto fail;
999
1000 trigger = ieee80211_get_assoc_led_name(priv->hw);
1001 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
1002 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
1003 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
1004 priv->assoc_led.led_type = ATH_LED_ASSOC;
1005 if (ret)
1006 goto fail;
1007
1008 trigger = ieee80211_get_tx_led_name(priv->hw);
1009 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
1010 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
1011 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
1012 priv->tx_led.led_type = ATH_LED_TX;
1013 if (ret)
1014 goto fail;
1015
1016 trigger = ieee80211_get_rx_led_name(priv->hw);
1017 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
1018 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
1019 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
1020 priv->rx_led.led_type = ATH_LED_RX;
1021 if (ret)
1022 goto fail;
1023
1024 priv->op_flags &= ~OP_LED_DEINIT;
1025
1026 return;
1027
1028fail:
1029 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1030 ath9k_deinit_leds(priv);
1031}
1032
1033/*******************/
1034/* Rfkill */
1035/*******************/
1036
1037static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
1038{
1039 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
1040 priv->ah->rfkill_polarity;
1041}
1042
1043static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
1044{
1045 struct ath9k_htc_priv *priv = hw->priv;
1046 bool blocked = !!ath_is_rfkill_set(priv);
1047
1048 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1049}
1050
1051void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1052{
1053 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1054 wiphy_rfkill_start_polling(priv->hw->wiphy);
1055}
1056
1057/**********************/
1058/* mac80211 Callbacks */
1059/**********************/
1060
1061static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1062{
1063 struct ieee80211_hdr *hdr;
1064 struct ath9k_htc_priv *priv = hw->priv;
1065 int padpos, padsize, ret;
1066
1067 hdr = (struct ieee80211_hdr *) skb->data;
1068
1069 /* Add the padding after the header if this is not already done */
1070 padpos = ath9k_cmn_padpos(hdr->frame_control);
1071 padsize = padpos & 3;
1072 if (padsize && skb->len > padpos) {
1073 if (skb_headroom(skb) < padsize)
1074 return -1;
1075 skb_push(skb, padsize);
1076 memmove(skb->data, skb->data + padsize, padpos);
1077 }
1078
1079 ret = ath9k_htc_tx_start(priv, skb);
1080 if (ret != 0) {
1081 if (ret == -ENOMEM) {
1082 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1083 "Stopping TX queues\n");
1084 ieee80211_stop_queues(hw);
1085 spin_lock_bh(&priv->tx_lock);
1086 priv->tx_queues_stop = true;
1087 spin_unlock_bh(&priv->tx_lock);
1088 } else {
1089 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1090 "Tx failed");
1091 }
1092 goto fail_tx;
1093 }
1094
1095 return 0;
1096
1097fail_tx:
1098 dev_kfree_skb_any(skb);
1099 return 0;
1100}
1101
1102static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1103{
1104 struct ath9k_htc_priv *priv = hw->priv;
1105 struct ath_hw *ah = priv->ah;
1106 struct ath_common *common = ath9k_hw_common(ah);
1107 struct ieee80211_channel *curchan = hw->conf.channel;
1108 struct ath9k_channel *init_channel;
1109 int ret = 0;
1110 enum htc_phymode mode;
1111 __be16 htc_mode;
1112 u8 cmd_rsp;
1113
1114 ath_print(common, ATH_DBG_CONFIG,
1115 "Starting driver with initial channel: %d MHz\n",
1116 curchan->center_freq);
1117
1118 /* setup initial channel */
1119 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1120
1121 /* Reset SERDES registers */
1122 ath9k_hw_configpcipowersave(ah, 0, 0);
1123
1124 ath9k_hw_htc_resetinit(ah);
1125 ret = ath9k_hw_reset(ah, init_channel, false);
1126 if (ret) {
1127 ath_print(common, ATH_DBG_FATAL,
1128 "Unable to reset hardware; reset status %d "
1129 "(freq %u MHz)\n", ret, curchan->center_freq);
1130 return ret;
1131 }
1132
1133 ath_update_txpow(priv);
1134
1135 mode = ath9k_htc_get_curmode(priv, init_channel);
1136 htc_mode = cpu_to_be16(mode);
1137 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1138 WMI_CMD(WMI_ATH_INIT_CMDID);
1139 WMI_CMD(WMI_START_RECV_CMDID);
1140
1141 ath9k_host_rx_init(priv);
1142
1143 priv->op_flags &= ~OP_INVALID;
1144 htc_start(priv->htc);
1145
1146 spin_lock_bh(&priv->tx_lock);
1147 priv->tx_queues_stop = false;
1148 spin_unlock_bh(&priv->tx_lock);
1149
1150 if (led) {
1151 /* Enable LED */
1152 ath9k_hw_cfg_output(ah, ah->led_pin,
1153 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1154 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1155 }
1156
1157 ieee80211_wake_queues(hw);
1158
1159 return ret;
1160}
1161
1162static int ath9k_htc_start(struct ieee80211_hw *hw)
1163{
1164 struct ath9k_htc_priv *priv = hw->priv;
1165 int ret = 0;
1166
1167 mutex_lock(&priv->mutex);
1168 ret = ath9k_htc_radio_enable(hw, false);
1169 mutex_unlock(&priv->mutex);
1170
1171 return ret;
1172}
1173
1174static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1175{
1176 struct ath9k_htc_priv *priv = hw->priv;
1177 struct ath_hw *ah = priv->ah;
1178 struct ath_common *common = ath9k_hw_common(ah);
1179 int ret = 0;
1180 u8 cmd_rsp;
1181
1182 if (priv->op_flags & OP_INVALID) {
1183 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1184 return;
1185 }
1186
1187 if (led) {
1188 /* Disable LED */
1189 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1190 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1191 }
1192
1193 /* Cancel all the running timers/work .. */
1194 cancel_work_sync(&priv->ps_work);
1195 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1196 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1197 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1198 ath9k_led_stop_brightness(priv);
1199
1200 ath9k_htc_ps_wakeup(priv);
1201 htc_stop(priv->htc);
1202 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1203 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1204 WMI_CMD(WMI_STOP_RECV_CMDID);
1205 ath9k_hw_phy_disable(ah);
1206 ath9k_hw_disable(ah);
1207 ath9k_hw_configpcipowersave(ah, 1, 1);
1208 ath9k_htc_ps_restore(priv);
1209 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1210
1211 skb_queue_purge(&priv->tx_queue);
1212
1213 /* Remove monitor interface here */
1214 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1215 if (ath9k_htc_remove_monitor_interface(priv))
1216 ath_print(common, ATH_DBG_FATAL,
1217 "Unable to remove monitor interface\n");
1218 else
1219 ath_print(common, ATH_DBG_CONFIG,
1220 "Monitor interface removed\n");
1221 }
1222
1223 priv->op_flags |= OP_INVALID;
1224
1225 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1226}
1227
1228static void ath9k_htc_stop(struct ieee80211_hw *hw)
1229{
1230 struct ath9k_htc_priv *priv = hw->priv;
1231
1232 mutex_lock(&priv->mutex);
1233 ath9k_htc_radio_disable(hw, false);
1234 mutex_unlock(&priv->mutex);
1235}
1236
1237
1238static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1239 struct ieee80211_vif *vif)
1240{
1241 struct ath9k_htc_priv *priv = hw->priv;
1242 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1243 struct ath_common *common = ath9k_hw_common(priv->ah);
1244 struct ath9k_htc_target_vif hvif;
1245 int ret = 0;
1246 u8 cmd_rsp;
1247
1248 mutex_lock(&priv->mutex);
1249
1250 /* Only one interface for now */
1251 if (priv->nvifs > 0) {
1252 ret = -ENOBUFS;
1253 goto out;
1254 }
1255
1256 ath9k_htc_ps_wakeup(priv);
1257 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1258 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1259
1260 switch (vif->type) {
1261 case NL80211_IFTYPE_STATION:
1262 hvif.opmode = cpu_to_be32(HTC_M_STA);
1263 break;
1264 case NL80211_IFTYPE_ADHOC:
1265 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1266 break;
1267 default:
1268 ath_print(common, ATH_DBG_FATAL,
1269 "Interface type %d not yet supported\n", vif->type);
1270 ret = -EOPNOTSUPP;
1271 goto out;
1272 }
1273
1274 ath_print(common, ATH_DBG_CONFIG,
1275 "Attach a VIF of type: %d\n", vif->type);
1276
1277 priv->ah->opmode = vif->type;
1278
1279 /* Index starts from zero on the target */
1280 avp->index = hvif.index = priv->nvifs;
1281 hvif.rtsthreshold = cpu_to_be16(2304);
1282 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1283 if (ret)
1284 goto out;
1285
1286 priv->nvifs++;
1287
1288 /*
1289 * We need a node in target to tx mgmt frames
1290 * before association.
1291 */
1292 ret = ath9k_htc_add_station(priv, vif, NULL);
1293 if (ret)
1294 goto out;
1295
1296 ret = ath9k_htc_update_cap_target(priv);
1297 if (ret)
1298 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1299 " capability in target \n");
1300
1301 priv->vif = vif;
1302out:
1303 ath9k_htc_ps_restore(priv);
1304 mutex_unlock(&priv->mutex);
1305 return ret;
1306}
1307
1308static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1309 struct ieee80211_vif *vif)
1310{
1311 struct ath9k_htc_priv *priv = hw->priv;
1312 struct ath_common *common = ath9k_hw_common(priv->ah);
1313 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1314 struct ath9k_htc_target_vif hvif;
1315 int ret = 0;
1316 u8 cmd_rsp;
1317
1318 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1319
1320 mutex_lock(&priv->mutex);
1321
1322 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1323 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1324 hvif.index = avp->index;
1325 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1326 priv->nvifs--;
1327
1328 ath9k_htc_remove_station(priv, vif, NULL);
1329 priv->vif = NULL;
1330
1331 mutex_unlock(&priv->mutex);
1332}
1333
1334static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1335{
1336 struct ath9k_htc_priv *priv = hw->priv;
1337 struct ath_common *common = ath9k_hw_common(priv->ah);
1338 struct ieee80211_conf *conf = &hw->conf;
1339
1340 mutex_lock(&priv->mutex);
1341
1342 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1343 bool enable_radio = false;
1344 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1345
1346 if (!idle && priv->ps_idle)
1347 enable_radio = true;
1348
1349 priv->ps_idle = idle;
1350
1351 if (enable_radio) {
1352 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1353 ath9k_htc_radio_enable(hw, true);
1354 ath_print(common, ATH_DBG_CONFIG,
1355 "not-idle: enabling radio\n");
1356 }
1357 }
1358
1359 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1360 struct ieee80211_channel *curchan = hw->conf.channel;
1361 int pos = curchan->hw_value;
1362 bool is_cw40 = false;
1363
1364 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1365 curchan->center_freq);
1366
1367 if (check_rc_update(hw, &is_cw40))
1368 ath9k_htc_rc_update(priv, is_cw40);
1369
1370 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1371
1372 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1373 ath_print(common, ATH_DBG_FATAL,
1374 "Unable to set channel\n");
1375 mutex_unlock(&priv->mutex);
1376 return -EINVAL;
1377 }
1378
1379 }
1380 if (changed & IEEE80211_CONF_CHANGE_PS) {
1381 if (conf->flags & IEEE80211_CONF_PS) {
1382 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1383 priv->ps_enabled = true;
1384 } else {
1385 priv->ps_enabled = false;
1386 cancel_work_sync(&priv->ps_work);
1387 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1388 }
1389 }
1390
1391 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1392 if (conf->flags & IEEE80211_CONF_MONITOR) {
1393 if (ath9k_htc_add_monitor_interface(priv))
1394 ath_print(common, ATH_DBG_FATAL,
1395 "Failed to set monitor mode\n");
1396 else
1397 ath_print(common, ATH_DBG_CONFIG,
1398 "HW opmode set to Monitor mode\n");
1399 }
1400 }
1401
1402 if (priv->ps_idle) {
1403 ath_print(common, ATH_DBG_CONFIG,
1404 "idle: disabling radio\n");
1405 ath9k_htc_radio_disable(hw, true);
1406 }
1407
1408 mutex_unlock(&priv->mutex);
1409
1410 return 0;
1411}
1412
1413#define SUPPORTED_FILTERS \
1414 (FIF_PROMISC_IN_BSS | \
1415 FIF_ALLMULTI | \
1416 FIF_CONTROL | \
1417 FIF_PSPOLL | \
1418 FIF_OTHER_BSS | \
1419 FIF_BCN_PRBRESP_PROMISC | \
1420 FIF_FCSFAIL)
1421
1422static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1423 unsigned int changed_flags,
1424 unsigned int *total_flags,
1425 u64 multicast)
1426{
1427 struct ath9k_htc_priv *priv = hw->priv;
1428 u32 rfilt;
1429
1430 mutex_lock(&priv->mutex);
1431
1432 ath9k_htc_ps_wakeup(priv);
1433 changed_flags &= SUPPORTED_FILTERS;
1434 *total_flags &= SUPPORTED_FILTERS;
1435
1436 priv->rxfilter = *total_flags;
1437 rfilt = ath9k_htc_calcrxfilter(priv);
1438 ath9k_hw_setrxfilter(priv->ah, rfilt);
1439
1440 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1441 "Set HW RX filter: 0x%x\n", rfilt);
1442
1443 ath9k_htc_ps_restore(priv);
1444 mutex_unlock(&priv->mutex);
1445}
1446
1447static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
1448 struct ieee80211_vif *vif,
1449 enum sta_notify_cmd cmd,
1450 struct ieee80211_sta *sta)
1451{
1452 struct ath9k_htc_priv *priv = hw->priv;
1453 int ret;
1454
1455 mutex_lock(&priv->mutex);
1456
1457 switch (cmd) {
1458 case STA_NOTIFY_ADD:
1459 ret = ath9k_htc_add_station(priv, vif, sta);
1460 if (!ret)
1461 ath9k_htc_init_rate(priv, vif, sta);
1462 break;
1463 case STA_NOTIFY_REMOVE:
1464 ath9k_htc_remove_station(priv, vif, sta);
1465 break;
1466 default:
1467 break;
1468 }
1469
1470 mutex_unlock(&priv->mutex);
1471}
1472
1473static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1474 const struct ieee80211_tx_queue_params *params)
1475{
1476 struct ath9k_htc_priv *priv = hw->priv;
1477 struct ath_common *common = ath9k_hw_common(priv->ah);
1478 struct ath9k_tx_queue_info qi;
1479 int ret = 0, qnum;
1480
1481 if (queue >= WME_NUM_AC)
1482 return 0;
1483
1484 mutex_lock(&priv->mutex);
1485
1486 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1487
1488 qi.tqi_aifs = params->aifs;
1489 qi.tqi_cwmin = params->cw_min;
1490 qi.tqi_cwmax = params->cw_max;
1491 qi.tqi_burstTime = params->txop;
1492
1493 qnum = get_hw_qnum(queue, priv->hwq_map);
1494
1495 ath_print(common, ATH_DBG_CONFIG,
1496 "Configure tx [queue/hwq] [%d/%d], "
1497 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1498 queue, qnum, params->aifs, params->cw_min,
1499 params->cw_max, params->txop);
1500
1501 ret = ath_htc_txq_update(priv, qnum, &qi);
1502 if (ret)
1503 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1504
1505 mutex_unlock(&priv->mutex);
1506
1507 return ret;
1508}
1509
1510static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1511 enum set_key_cmd cmd,
1512 struct ieee80211_vif *vif,
1513 struct ieee80211_sta *sta,
1514 struct ieee80211_key_conf *key)
1515{
1516 struct ath9k_htc_priv *priv = hw->priv;
1517 struct ath_common *common = ath9k_hw_common(priv->ah);
1518 int ret = 0;
1519
1520 if (htc_modparam_nohwcrypt)
1521 return -ENOSPC;
1522
1523 mutex_lock(&priv->mutex);
1524 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1525 ath9k_htc_ps_wakeup(priv);
1526
1527 switch (cmd) {
1528 case SET_KEY:
1529 ret = ath9k_cmn_key_config(common, vif, sta, key);
1530 if (ret >= 0) {
1531 key->hw_key_idx = ret;
1532 /* push IV and Michael MIC generation to stack */
1533 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1534 if (key->alg == ALG_TKIP)
1535 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1536 if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
1537 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1538 ret = 0;
1539 }
1540 break;
1541 case DISABLE_KEY:
1542 ath9k_cmn_key_delete(common, key);
1543 break;
1544 default:
1545 ret = -EINVAL;
1546 }
1547
1548 ath9k_htc_ps_restore(priv);
1549 mutex_unlock(&priv->mutex);
1550
1551 return ret;
1552}
1553
1554static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1555 struct ieee80211_vif *vif,
1556 struct ieee80211_bss_conf *bss_conf,
1557 u32 changed)
1558{
1559 struct ath9k_htc_priv *priv = hw->priv;
1560 struct ath_hw *ah = priv->ah;
1561 struct ath_common *common = ath9k_hw_common(ah);
1562
1563 mutex_lock(&priv->mutex);
1564 ath9k_htc_ps_wakeup(priv);
1565
1566 if (changed & BSS_CHANGED_ASSOC) {
1567 common->curaid = bss_conf->assoc ?
1568 bss_conf->aid : 0;
1569 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1570 bss_conf->assoc);
1571
1572 if (bss_conf->assoc) {
1573 priv->op_flags |= OP_ASSOCIATED;
1574 ath_start_ani(priv);
1575 } else {
1576 priv->op_flags &= ~OP_ASSOCIATED;
1577 cancel_work_sync(&priv->ps_work);
1578 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1579 }
1580 }
1581
1582 if (changed & BSS_CHANGED_BSSID) {
1583 /* Set BSSID */
1584 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1585 ath9k_hw_write_associd(ah);
1586
1587 ath_print(common, ATH_DBG_CONFIG,
1588 "BSSID: %pM aid: 0x%x\n",
1589 common->curbssid, common->curaid);
1590 }
1591
1592 if ((changed & BSS_CHANGED_BEACON_INT) ||
1593 (changed & BSS_CHANGED_BEACON) ||
1594 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1595 bss_conf->enable_beacon)) {
1596 priv->op_flags |= OP_ENABLE_BEACON;
1597 ath9k_htc_beacon_config(priv, vif);
1598 }
1599
1600 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1601 !bss_conf->enable_beacon) {
1602 priv->op_flags &= ~OP_ENABLE_BEACON;
1603 ath9k_htc_beacon_config(priv, vif);
1604 }
1605
1606 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1607 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1608 bss_conf->use_short_preamble);
1609 if (bss_conf->use_short_preamble)
1610 priv->op_flags |= OP_PREAMBLE_SHORT;
1611 else
1612 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1613 }
1614
1615 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1616 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1617 bss_conf->use_cts_prot);
1618 if (bss_conf->use_cts_prot &&
1619 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1620 priv->op_flags |= OP_PROTECT_ENABLE;
1621 else
1622 priv->op_flags &= ~OP_PROTECT_ENABLE;
1623 }
1624
1625 if (changed & BSS_CHANGED_ERP_SLOT) {
1626 if (bss_conf->use_short_slot)
1627 ah->slottime = 9;
1628 else
1629 ah->slottime = 20;
1630
1631 ath9k_hw_init_global_settings(ah);
1632 }
1633
1634 ath9k_htc_ps_restore(priv);
1635 mutex_unlock(&priv->mutex);
1636}
1637
1638static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1639{
1640 struct ath9k_htc_priv *priv = hw->priv;
1641 u64 tsf;
1642
1643 mutex_lock(&priv->mutex);
1644 tsf = ath9k_hw_gettsf64(priv->ah);
1645 mutex_unlock(&priv->mutex);
1646
1647 return tsf;
1648}
1649
1650static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1651{
1652 struct ath9k_htc_priv *priv = hw->priv;
1653
1654 mutex_lock(&priv->mutex);
1655 ath9k_hw_settsf64(priv->ah, tsf);
1656 mutex_unlock(&priv->mutex);
1657}
1658
1659static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1660{
1661 struct ath9k_htc_priv *priv = hw->priv;
1662
1663 ath9k_htc_ps_wakeup(priv);
1664 mutex_lock(&priv->mutex);
1665 ath9k_hw_reset_tsf(priv->ah);
1666 mutex_unlock(&priv->mutex);
1667 ath9k_htc_ps_restore(priv);
1668}
1669
1670static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1671 struct ieee80211_vif *vif,
1672 enum ieee80211_ampdu_mlme_action action,
1673 struct ieee80211_sta *sta,
1674 u16 tid, u16 *ssn)
1675{
1676 struct ath9k_htc_priv *priv = hw->priv;
1677 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1678 struct ath9k_htc_sta *ista;
1679
1680 switch (action) {
1681 case IEEE80211_AMPDU_RX_START:
1682 break;
1683 case IEEE80211_AMPDU_RX_STOP:
1684 break;
1685 case IEEE80211_AMPDU_TX_START:
1686 case IEEE80211_AMPDU_TX_STOP:
1687 if (!(priv->op_flags & OP_TXAGGR))
1688 return -ENOTSUPP;
1689 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1690 work->hw = hw;
1691 work->vif = vif;
1692 work->action = action;
1693 work->tid = tid;
1694 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1695 break;
1696 case IEEE80211_AMPDU_TX_OPERATIONAL:
1697 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1698 ista->tid_state[tid] = AGGR_OPERATIONAL;
1699 break;
1700 default:
1701 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1702 "Unknown AMPDU action\n");
1703 }
1704
1705 return 0;
1706}
1707
1708static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1709{
1710 struct ath9k_htc_priv *priv = hw->priv;
1711
1712 mutex_lock(&priv->mutex);
1713 spin_lock_bh(&priv->beacon_lock);
1714 priv->op_flags |= OP_SCANNING;
1715 spin_unlock_bh(&priv->beacon_lock);
1716 cancel_work_sync(&priv->ps_work);
1717 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1718 mutex_unlock(&priv->mutex);
1719}
1720
1721static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1722{
1723 struct ath9k_htc_priv *priv = hw->priv;
1724
1725 ath9k_htc_ps_wakeup(priv);
1726 mutex_lock(&priv->mutex);
1727 spin_lock_bh(&priv->beacon_lock);
1728 priv->op_flags &= ~OP_SCANNING;
1729 spin_unlock_bh(&priv->beacon_lock);
1730 priv->op_flags |= OP_FULL_RESET;
1731 if (priv->op_flags & OP_ASSOCIATED)
1732 ath9k_htc_beacon_config(priv, priv->vif);
1733 ath_start_ani(priv);
1734 mutex_unlock(&priv->mutex);
1735 ath9k_htc_ps_restore(priv);
1736}
1737
1738static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1739{
1740 return 0;
1741}
1742
1743static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1744 u8 coverage_class)
1745{
1746 struct ath9k_htc_priv *priv = hw->priv;
1747
1748 mutex_lock(&priv->mutex);
1749 priv->ah->coverage_class = coverage_class;
1750 ath9k_hw_init_global_settings(priv->ah);
1751 mutex_unlock(&priv->mutex);
1752}
1753
1754struct ieee80211_ops ath9k_htc_ops = {
1755 .tx = ath9k_htc_tx,
1756 .start = ath9k_htc_start,
1757 .stop = ath9k_htc_stop,
1758 .add_interface = ath9k_htc_add_interface,
1759 .remove_interface = ath9k_htc_remove_interface,
1760 .config = ath9k_htc_config,
1761 .configure_filter = ath9k_htc_configure_filter,
1762 .sta_notify = ath9k_htc_sta_notify,
1763 .conf_tx = ath9k_htc_conf_tx,
1764 .bss_info_changed = ath9k_htc_bss_info_changed,
1765 .set_key = ath9k_htc_set_key,
1766 .get_tsf = ath9k_htc_get_tsf,
1767 .set_tsf = ath9k_htc_set_tsf,
1768 .reset_tsf = ath9k_htc_reset_tsf,
1769 .ampdu_action = ath9k_htc_ampdu_action,
1770 .sw_scan_start = ath9k_htc_sw_scan_start,
1771 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1772 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1773 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1774 .set_coverage_class = ath9k_htc_set_coverage_class,
1775};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
new file mode 100644
index 000000000000..2571b443ac82
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -0,0 +1,707 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19/******/
20/* TX */
21/******/
22
23int get_hw_qnum(u16 queue, int *hwq_map)
24{
25 switch (queue) {
26 case 0:
27 return hwq_map[ATH9K_WME_AC_VO];
28 case 1:
29 return hwq_map[ATH9K_WME_AC_VI];
30 case 2:
31 return hwq_map[ATH9K_WME_AC_BE];
32 case 3:
33 return hwq_map[ATH9K_WME_AC_BK];
34 default:
35 return hwq_map[ATH9K_WME_AC_BE];
36 }
37}
38
39int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
40 struct ath9k_tx_queue_info *qinfo)
41{
42 struct ath_hw *ah = priv->ah;
43 int error = 0;
44 struct ath9k_tx_queue_info qi;
45
46 ath9k_hw_get_txq_props(ah, qnum, &qi);
47
48 qi.tqi_aifs = qinfo->tqi_aifs;
49 qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
50 qi.tqi_cwmax = qinfo->tqi_cwmax;
51 qi.tqi_burstTime = qinfo->tqi_burstTime;
52 qi.tqi_readyTime = qinfo->tqi_readyTime;
53
54 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
55 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
56 "Unable to update hardware queue %u!\n", qnum);
57 error = -EIO;
58 } else {
59 ath9k_hw_resettxqueue(ah, qnum);
60 }
61
62 return error;
63}
64
65int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
66{
67 struct ieee80211_hdr *hdr;
68 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
69 struct ieee80211_sta *sta = tx_info->control.sta;
70 struct ath9k_htc_sta *ista;
71 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum;
75 __le16 fc;
76 u8 *tx_fhdr;
77 u8 sta_idx;
78
79 hdr = (struct ieee80211_hdr *) skb->data;
80 fc = hdr->frame_control;
81
82 avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
83 if (sta) {
84 ista = (struct ath9k_htc_sta *) sta->drv_priv;
85 sta_idx = ista->index;
86 } else {
87 sta_idx = 0;
88 }
89
90 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
91
92 if (ieee80211_is_data(fc)) {
93 struct tx_frame_hdr tx_hdr;
94 u8 *qc;
95
96 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
97
98 tx_hdr.node_idx = sta_idx;
99 tx_hdr.vif_idx = avp->index;
100
101 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
102 tx_ctl.type = ATH9K_HTC_AMPDU;
103 tx_hdr.data_type = ATH9K_HTC_AMPDU;
104 } else {
105 tx_ctl.type = ATH9K_HTC_NORMAL;
106 tx_hdr.data_type = ATH9K_HTC_NORMAL;
107 }
108
109 if (ieee80211_is_data(fc)) {
110 qc = ieee80211_get_qos_ctl(hdr);
111 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
112 }
113
114 /* Check for RTS protection */
115 if (priv->hw->wiphy->rts_threshold != (u32) -1)
116 if (skb->len > priv->hw->wiphy->rts_threshold)
117 tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
118
119 /* CTS-to-self */
120 if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
121 (priv->op_flags & OP_PROTECT_ENABLE))
122 tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
123
124 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
125 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
126 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
127 else
128 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
129
130 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132
133 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135
136 switch (hw_qnum) {
137 case 0:
138 epid = priv->data_be_ep;
139 break;
140 case 2:
141 epid = priv->data_vi_ep;
142 break;
143 case 3:
144 epid = priv->data_vo_ep;
145 break;
146 case 1:
147 default:
148 epid = priv->data_bk_ep;
149 break;
150 }
151 } else {
152 struct tx_mgmt_hdr mgmt_hdr;
153
154 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
155
156 tx_ctl.type = ATH9K_HTC_NORMAL;
157
158 mgmt_hdr.node_idx = sta_idx;
159 mgmt_hdr.vif_idx = avp->index;
160 mgmt_hdr.tidno = 0;
161 mgmt_hdr.flags = 0;
162
163 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
164 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
165 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
166 else
167 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168
169 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
170 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
171 epid = priv->mgmt_ep;
172 }
173
174 return htc_send(priv->htc, skb, epid, &tx_ctl);
175}
176
177void ath9k_tx_tasklet(unsigned long data)
178{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
180 struct ieee80211_sta *sta;
181 struct ieee80211_hdr *hdr;
182 struct ieee80211_tx_info *tx_info;
183 struct sk_buff *skb = NULL;
184 __le16 fc;
185
186 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
187
188 hdr = (struct ieee80211_hdr *) skb->data;
189 fc = hdr->frame_control;
190 tx_info = IEEE80211_SKB_CB(skb);
191
192 memset(&tx_info->status, 0, sizeof(tx_info->status));
193
194 rcu_read_lock();
195
196 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
197 if (!sta) {
198 rcu_read_unlock();
199 ieee80211_tx_status(priv->hw, skb);
200 continue;
201 }
202
203 /* Check if we need to start aggregation */
204
205 if (sta && conf_is_ht(&priv->hw->conf) &&
206 (priv->op_flags & OP_TXAGGR)
207 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
208 if (ieee80211_is_data_qos(fc)) {
209 u8 *qc, tid;
210 struct ath9k_htc_sta *ista;
211
212 qc = ieee80211_get_qos_ctl(hdr);
213 tid = qc[0] & 0xf;
214 ista = (struct ath9k_htc_sta *)sta->drv_priv;
215
216 if ((tid < ATH9K_HTC_MAX_TID) &&
217 ista->tid_state[tid] == AGGR_STOP) {
218 ieee80211_start_tx_ba_session(sta, tid);
219 ista->tid_state[tid] = AGGR_PROGRESS;
220 }
221 }
222 }
223
224 rcu_read_unlock();
225
226 /* Send status to mac80211 */
227 ieee80211_tx_status(priv->hw, skb);
228 }
229
230 /* Wake TX queues if needed */
231 spin_lock_bh(&priv->tx_lock);
232 if (priv->tx_queues_stop) {
233 priv->tx_queues_stop = false;
234 spin_unlock_bh(&priv->tx_lock);
235 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
236 "Waking up TX queues\n");
237 ieee80211_wake_queues(priv->hw);
238 return;
239 }
240 spin_unlock_bh(&priv->tx_lock);
241}
242
243void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
244 enum htc_endpoint_id ep_id, bool txok)
245{
246 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
247 struct ath_common *common = ath9k_hw_common(priv->ah);
248 struct ieee80211_tx_info *tx_info;
249
250 if (!skb)
251 return;
252
253 if (ep_id == priv->mgmt_ep) {
254 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
255 } else if ((ep_id == priv->data_bk_ep) ||
256 (ep_id == priv->data_be_ep) ||
257 (ep_id == priv->data_vi_ep) ||
258 (ep_id == priv->data_vo_ep)) {
259 skb_pull(skb, sizeof(struct tx_frame_hdr));
260 } else {
261 ath_print(common, ATH_DBG_FATAL,
262 "Unsupported TX EPID: %d\n", ep_id);
263 dev_kfree_skb_any(skb);
264 return;
265 }
266
267 tx_info = IEEE80211_SKB_CB(skb);
268
269 if (txok)
270 tx_info->flags |= IEEE80211_TX_STAT_ACK;
271
272 skb_queue_tail(&priv->tx_queue, skb);
273 tasklet_schedule(&priv->tx_tasklet);
274}
275
276int ath9k_tx_init(struct ath9k_htc_priv *priv)
277{
278 skb_queue_head_init(&priv->tx_queue);
279 return 0;
280}
281
282void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
283{
284
285}
286
287bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
288 enum ath9k_tx_queue_subtype subtype)
289{
290 struct ath_hw *ah = priv->ah;
291 struct ath_common *common = ath9k_hw_common(ah);
292 struct ath9k_tx_queue_info qi;
293 int qnum;
294
295 memset(&qi, 0, sizeof(qi));
296
297 qi.tqi_subtype = subtype;
298 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
299 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
300 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
301 qi.tqi_physCompBuf = 0;
302 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
303
304 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
305 if (qnum == -1)
306 return false;
307
308 if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
309 ath_print(common, ATH_DBG_FATAL,
310 "qnum %u out of range, max %u!\n",
311 qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
312 ath9k_hw_releasetxqueue(ah, qnum);
313 return false;
314 }
315
316 priv->hwq_map[subtype] = qnum;
317 return true;
318}
319
320/******/
321/* RX */
322/******/
323
324/*
325 * Calculate the RX filter to be set in the HW.
326 */
327u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
328{
329#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
330
331 struct ath_hw *ah = priv->ah;
332 u32 rfilt;
333
334 rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
335 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
336 | ATH9K_RX_FILTER_MCAST;
337
338 /* If not a STA, enable processing of Probe Requests */
339 if (ah->opmode != NL80211_IFTYPE_STATION)
340 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
341
342 /*
343 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
344 * mode interface or when in monitor mode. AP mode does not need this
345 * since it receives all in-BSS frames anyway.
346 */
347 if (((ah->opmode != NL80211_IFTYPE_AP) &&
348 (priv->rxfilter & FIF_PROMISC_IN_BSS)) ||
349 (ah->opmode == NL80211_IFTYPE_MONITOR))
350 rfilt |= ATH9K_RX_FILTER_PROM;
351
352 if (priv->rxfilter & FIF_CONTROL)
353 rfilt |= ATH9K_RX_FILTER_CONTROL;
354
355 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
356 !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC))
357 rfilt |= ATH9K_RX_FILTER_MYBEACON;
358 else
359 rfilt |= ATH9K_RX_FILTER_BEACON;
360
361 if (conf_is_ht(&priv->hw->conf))
362 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
363
364 return rfilt;
365
366#undef RX_FILTER_PRESERVE
367}
368
369/*
370 * Recv initialization for opmode change.
371 */
372static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
373{
374 struct ath_hw *ah = priv->ah;
375 struct ath_common *common = ath9k_hw_common(ah);
376
377 u32 rfilt, mfilt[2];
378
379 /* configure rx filter */
380 rfilt = ath9k_htc_calcrxfilter(priv);
381 ath9k_hw_setrxfilter(ah, rfilt);
382
383 /* configure bssid mask */
384 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
385 ath_hw_setbssidmask(common);
386
387 /* configure operational mode */
388 ath9k_hw_setopmode(ah);
389
390 /* Handle any link-level address change. */
391 ath9k_hw_setmac(ah, common->macaddr);
392
393 /* calculate and install multicast filter */
394 mfilt[0] = mfilt[1] = ~0;
395 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
396}
397
398void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
399{
400 ath9k_hw_rxena(priv->ah);
401 ath9k_htc_opmode_init(priv);
402 ath9k_hw_startpcureceive(priv->ah);
403 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
404}
405
406static void ath9k_process_rate(struct ieee80211_hw *hw,
407 struct ieee80211_rx_status *rxs,
408 u8 rx_rate, u8 rs_flags)
409{
410 struct ieee80211_supported_band *sband;
411 enum ieee80211_band band;
412 unsigned int i = 0;
413
414 if (rx_rate & 0x80) {
415 /* HT rate */
416 rxs->flag |= RX_FLAG_HT;
417 if (rs_flags & ATH9K_RX_2040)
418 rxs->flag |= RX_FLAG_40MHZ;
419 if (rs_flags & ATH9K_RX_GI)
420 rxs->flag |= RX_FLAG_SHORT_GI;
421 rxs->rate_idx = rx_rate & 0x7f;
422 return;
423 }
424
425 band = hw->conf.channel->band;
426 sband = hw->wiphy->bands[band];
427
428 for (i = 0; i < sband->n_bitrates; i++) {
429 if (sband->bitrates[i].hw_value == rx_rate) {
430 rxs->rate_idx = i;
431 return;
432 }
433 if (sband->bitrates[i].hw_value_short == rx_rate) {
434 rxs->rate_idx = i;
435 rxs->flag |= RX_FLAG_SHORTPRE;
436 return;
437 }
438 }
439
440}
441
442static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
443 struct ath9k_htc_rxbuf *rxbuf,
444 struct ieee80211_rx_status *rx_status)
445
446{
447 struct ieee80211_hdr *hdr;
448 struct ieee80211_hw *hw = priv->hw;
449 struct sk_buff *skb = rxbuf->skb;
450 struct ath_common *common = ath9k_hw_common(priv->ah);
451 struct ath_htc_rx_status *rxstatus;
452 int hdrlen, padpos, padsize;
453 int last_rssi = ATH_RSSI_DUMMY_MARKER;
454 __le16 fc;
455
456 if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
457 ath_print(common, ATH_DBG_FATAL,
458 "Corrupted RX frame, dropping\n");
459 goto rx_next;
460 }
461
462 rxstatus = (struct ath_htc_rx_status *)skb->data;
463
464 if (be16_to_cpu(rxstatus->rs_datalen) -
465 (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
466 ath_print(common, ATH_DBG_FATAL,
467 "Corrupted RX data len, dropping "
468 "(dlen: %d, skblen: %d)\n",
469 rxstatus->rs_datalen, skb->len);
470 goto rx_next;
471 }
472
473 /* Get the RX status information */
474 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
475 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
476
477 hdr = (struct ieee80211_hdr *)skb->data;
478 fc = hdr->frame_control;
479 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
480
481 padpos = ath9k_cmn_padpos(fc);
482
483 padsize = padpos & 3;
484 if (padsize && skb->len >= padpos+padsize+FCS_LEN) {
485 memmove(skb->data + padsize, skb->data, padpos);
486 skb_pull(skb, padsize);
487 }
488
489 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
490
491 if (rxbuf->rxstatus.rs_status != 0) {
492 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC)
493 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
494 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY)
495 goto rx_next;
496
497 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) {
498 /* FIXME */
499 } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) {
500 if (ieee80211_is_ctl(fc))
501 /*
502 * Sometimes, we get invalid
503 * MIC failures on valid control frames.
504 * Remove these mic errors.
505 */
506 rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC;
507 else
508 rx_status->flag |= RX_FLAG_MMIC_ERROR;
509 }
510
511 /*
512 * Reject error frames with the exception of
513 * decryption and MIC failures. For monitor mode,
514 * we also ignore the CRC error.
515 */
516 if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) {
517 if (rxbuf->rxstatus.rs_status &
518 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
519 ATH9K_RXERR_CRC))
520 goto rx_next;
521 } else {
522 if (rxbuf->rxstatus.rs_status &
523 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
524 goto rx_next;
525 }
526 }
527 }
528
529 if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) {
530 u8 keyix;
531 keyix = rxbuf->rxstatus.rs_keyix;
532 if (keyix != ATH9K_RXKEYIX_INVALID) {
533 rx_status->flag |= RX_FLAG_DECRYPTED;
534 } else if (ieee80211_has_protected(fc) &&
535 skb->len >= hdrlen + 4) {
536 keyix = skb->data[hdrlen + 3] >> 6;
537 if (test_bit(keyix, common->keymap))
538 rx_status->flag |= RX_FLAG_DECRYPTED;
539 }
540 }
541
542 ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
543 rxbuf->rxstatus.rs_flags);
544
545 if (priv->op_flags & OP_ASSOCIATED) {
546 if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
547 !rxbuf->rxstatus.rs_moreaggr)
548 ATH_RSSI_LPF(priv->rx.last_rssi,
549 rxbuf->rxstatus.rs_rssi);
550
551 last_rssi = priv->rx.last_rssi;
552
553 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
554 rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
555 ATH_RSSI_EP_MULTIPLIER);
556
557 if (rxbuf->rxstatus.rs_rssi < 0)
558 rxbuf->rxstatus.rs_rssi = 0;
559
560 if (ieee80211_is_beacon(fc))
561 priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
562 }
563
564 rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
565 rx_status->band = hw->conf.channel->band;
566 rx_status->freq = hw->conf.channel->center_freq;
567 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
568 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
569 rx_status->flag |= RX_FLAG_TSFT;
570
571 return true;
572
573rx_next:
574 return false;
575}
576
577/*
578 * FIXME: Handle FLUSH later on.
579 */
580void ath9k_rx_tasklet(unsigned long data)
581{
582 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
583 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
584 struct ieee80211_rx_status rx_status;
585 struct sk_buff *skb;
586 unsigned long flags;
587 struct ieee80211_hdr *hdr;
588
589 do {
590 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
591 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
592 if (tmp_buf->in_process) {
593 rxbuf = tmp_buf;
594 break;
595 }
596 }
597
598 if (rxbuf == NULL) {
599 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
600 break;
601 }
602
603 if (!rxbuf->skb)
604 goto requeue;
605
606 if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
607 dev_kfree_skb_any(rxbuf->skb);
608 goto requeue;
609 }
610
611 memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
612 sizeof(struct ieee80211_rx_status));
613 skb = rxbuf->skb;
614 hdr = (struct ieee80211_hdr *) skb->data;
615
616 if (ieee80211_is_beacon(hdr->frame_control) && priv->ps_enabled)
617 ieee80211_queue_work(priv->hw, &priv->ps_work);
618
619 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
620
621 ieee80211_rx(priv->hw, skb);
622
623 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
624requeue:
625 rxbuf->in_process = false;
626 rxbuf->skb = NULL;
627 list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
628 rxbuf = NULL;
629 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
630 } while (1);
631
632}
633
634void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
635 enum htc_endpoint_id ep_id)
636{
637 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv;
638 struct ath_hw *ah = priv->ah;
639 struct ath_common *common = ath9k_hw_common(ah);
640 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
641
642 spin_lock(&priv->rx.rxbuflock);
643 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
644 if (!tmp_buf->in_process) {
645 rxbuf = tmp_buf;
646 break;
647 }
648 }
649 spin_unlock(&priv->rx.rxbuflock);
650
651 if (rxbuf == NULL) {
652 ath_print(common, ATH_DBG_ANY,
653 "No free RX buffer\n");
654 goto err;
655 }
656
657 spin_lock(&priv->rx.rxbuflock);
658 rxbuf->skb = skb;
659 rxbuf->in_process = true;
660 spin_unlock(&priv->rx.rxbuflock);
661
662 tasklet_schedule(&priv->rx_tasklet);
663 return;
664err:
665 dev_kfree_skb_any(skb);
666}
667
668/* FIXME: Locking for cleanup/init */
669
670void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
671{
672 struct ath9k_htc_rxbuf *rxbuf, *tbuf;
673
674 list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
675 list_del(&rxbuf->list);
676 if (rxbuf->skb)
677 dev_kfree_skb_any(rxbuf->skb);
678 kfree(rxbuf);
679 }
680}
681
682int ath9k_rx_init(struct ath9k_htc_priv *priv)
683{
684 struct ath_hw *ah = priv->ah;
685 struct ath_common *common = ath9k_hw_common(ah);
686 struct ath9k_htc_rxbuf *rxbuf;
687 int i = 0;
688
689 INIT_LIST_HEAD(&priv->rx.rxbuf);
690 spin_lock_init(&priv->rx.rxbuflock);
691
692 for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
693 rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
694 if (rxbuf == NULL) {
695 ath_print(common, ATH_DBG_FATAL,
696 "Unable to allocate RX buffers\n");
697 goto err;
698 }
699 list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
700 }
701
702 return 0;
703
704err:
705 ath9k_rx_cleanup(priv);
706 return -ENOMEM;
707}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
new file mode 100644
index 000000000000..064397fd738e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -0,0 +1,480 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid,
21 struct ath9k_htc_tx_ctl *tx_ctl)
22{
23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid];
25 int status;
26
27 hdr = (struct htc_frame_hdr *)
28 skb_push(skb, sizeof(struct htc_frame_hdr));
29 hdr->endpoint_id = epid;
30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len);
32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
34 tx_ctl);
35 return status;
36}
37
38static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
39{
40 enum htc_endpoint_id avail_epid;
41
42 for (avail_epid = (ENDPOINT_MAX - 1); avail_epid > ENDPOINT0; avail_epid--)
43 if (endpoint[avail_epid].service_id == 0)
44 return &endpoint[avail_epid];
45 return NULL;
46}
47
48static u8 service_to_ulpipe(u16 service_id)
49{
50 switch (service_id) {
51 case WMI_CONTROL_SVC:
52 return 4;
53 case WMI_BEACON_SVC:
54 case WMI_CAB_SVC:
55 case WMI_UAPSD_SVC:
56 case WMI_MGMT_SVC:
57 case WMI_DATA_VO_SVC:
58 case WMI_DATA_VI_SVC:
59 case WMI_DATA_BE_SVC:
60 case WMI_DATA_BK_SVC:
61 return 1;
62 default:
63 return 0;
64 }
65}
66
67static u8 service_to_dlpipe(u16 service_id)
68{
69 switch (service_id) {
70 case WMI_CONTROL_SVC:
71 return 3;
72 case WMI_BEACON_SVC:
73 case WMI_CAB_SVC:
74 case WMI_UAPSD_SVC:
75 case WMI_MGMT_SVC:
76 case WMI_DATA_VO_SVC:
77 case WMI_DATA_VI_SVC:
78 case WMI_DATA_BE_SVC:
79 case WMI_DATA_BK_SVC:
80 return 2;
81 default:
82 return 0;
83 }
84}
85
86static void htc_process_target_rdy(struct htc_target *target,
87 void *buf)
88{
89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94
95 endpoint = &target->endpoint[ENDPOINT0];
96 endpoint->service_id = HTC_CTRL_RSVD_SVC;
97 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
98 atomic_inc(&target->tgt_ready);
99 complete(&target->target_wait);
100}
101
102static void htc_process_conn_rsp(struct htc_target *target,
103 struct htc_frame_hdr *htc_hdr)
104{
105 struct htc_conn_svc_rspmsg *svc_rspmsg;
106 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
107 u16 service_id;
108 u16 max_msglen;
109 enum htc_endpoint_id epid, tepid;
110
111 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
112 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
113
114 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
115 epid = svc_rspmsg->endpoint_id;
116 service_id = be16_to_cpu(svc_rspmsg->service_id);
117 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
118 endpoint = &target->endpoint[epid];
119
120 for (tepid = (ENDPOINT_MAX - 1); tepid > ENDPOINT0; tepid--) {
121 tmp_endpoint = &target->endpoint[tepid];
122 if (tmp_endpoint->service_id == service_id) {
123 tmp_endpoint->service_id = 0;
124 break;
125 }
126 }
127
128 if (tepid == ENDPOINT0)
129 return;
130
131 endpoint->service_id = service_id;
132 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
133 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
134 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
135 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
136 endpoint->max_msglen = max_msglen;
137 target->conn_rsp_epid = epid;
138 complete(&target->cmd_wait);
139 } else {
140 target->conn_rsp_epid = ENDPOINT_UNUSED;
141 }
142}
143
144static int htc_config_pipe_credits(struct htc_target *target)
145{
146 struct sk_buff *skb;
147 struct htc_config_pipe_msg *cp_msg;
148 int ret, time_left;
149
150 skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC);
151 if (!skb) {
152 dev_err(target->dev, "failed to allocate send buffer\n");
153 return -ENOMEM;
154 }
155 skb_reserve(skb, sizeof(struct htc_frame_hdr));
156
157 cp_msg = (struct htc_config_pipe_msg *)
158 skb_put(skb, sizeof(struct htc_config_pipe_msg));
159
160 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
161 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
162 cp_msg->credits = 28;
163
164 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
165
166 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
167 if (ret)
168 goto err;
169
170 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
171 if (!time_left) {
172 dev_err(target->dev, "HTC credit config timeout\n");
173 return -ETIMEDOUT;
174 }
175
176 return 0;
177err:
178 kfree_skb(skb);
179 return -EINVAL;
180}
181
182static int htc_setup_complete(struct htc_target *target)
183{
184 struct sk_buff *skb;
185 struct htc_comp_msg *comp_msg;
186 int ret = 0, time_left;
187
188 skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC);
189 if (!skb) {
190 dev_err(target->dev, "failed to allocate send buffer\n");
191 return -ENOMEM;
192 }
193 skb_reserve(skb, sizeof(struct htc_frame_hdr));
194
195 comp_msg = (struct htc_comp_msg *)
196 skb_put(skb, sizeof(struct htc_comp_msg));
197 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
198
199 target->htc_flags |= HTC_OP_START_WAIT;
200
201 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
202 if (ret)
203 goto err;
204
205 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
206 if (!time_left) {
207 dev_err(target->dev, "HTC start timeout\n");
208 return -ETIMEDOUT;
209 }
210
211 return 0;
212
213err:
214 kfree_skb(skb);
215 return -EINVAL;
216}
217
218/* HTC APIs */
219
220int htc_init(struct htc_target *target)
221{
222 int ret;
223
224 ret = htc_config_pipe_credits(target);
225 if (ret)
226 return ret;
227
228 return htc_setup_complete(target);
229}
230
231int htc_connect_service(struct htc_target *target,
232 struct htc_service_connreq *service_connreq,
233 enum htc_endpoint_id *conn_rsp_epid)
234{
235 struct sk_buff *skb;
236 struct htc_endpoint *endpoint;
237 struct htc_conn_svc_msg *conn_msg;
238 int ret, time_left;
239
240 /* Find an available endpoint */
241 endpoint = get_next_avail_ep(target->endpoint);
242 if (!endpoint) {
243 dev_err(target->dev, "Endpoint is not available for"
244 "service %d\n", service_connreq->service_id);
245 return -EINVAL;
246 }
247
248 endpoint->service_id = service_connreq->service_id;
249 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
250 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
251 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
252 endpoint->ep_callbacks = service_connreq->ep_callbacks;
253
254 skb = alloc_skb(sizeof(struct htc_conn_svc_msg) +
255 sizeof(struct htc_frame_hdr), GFP_ATOMIC);
256 if (!skb) {
257 dev_err(target->dev, "Failed to allocate buf to send"
258 "service connect req\n");
259 return -ENOMEM;
260 }
261
262 skb_reserve(skb, sizeof(struct htc_frame_hdr));
263
264 conn_msg = (struct htc_conn_svc_msg *)
265 skb_put(skb, sizeof(struct htc_conn_svc_msg));
266 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
267 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
268 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
269 conn_msg->dl_pipeid = endpoint->dl_pipeid;
270 conn_msg->ul_pipeid = endpoint->ul_pipeid;
271
272 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
273 if (ret)
274 goto err;
275
276 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
277 if (!time_left) {
278 dev_err(target->dev, "Service connection timeout for: %d\n",
279 service_connreq->service_id);
280 return -ETIMEDOUT;
281 }
282
283 *conn_rsp_epid = target->conn_rsp_epid;
284 return 0;
285err:
286 kfree_skb(skb);
287 return ret;
288}
289
290int htc_send(struct htc_target *target, struct sk_buff *skb,
291 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
292{
293 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
294}
295
296void htc_stop(struct htc_target *target)
297{
298 enum htc_endpoint_id epid;
299 struct htc_endpoint *endpoint;
300
301 for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
302 endpoint = &target->endpoint[epid];
303 if (endpoint->service_id != 0)
304 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
305 }
306}
307
308void htc_start(struct htc_target *target)
309{
310 enum htc_endpoint_id epid;
311 struct htc_endpoint *endpoint;
312
313 for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
314 endpoint = &target->endpoint[epid];
315 if (endpoint->service_id != 0)
316 target->hif->start(target->hif_dev,
317 endpoint->ul_pipeid);
318 }
319}
320
321void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
322 struct sk_buff *skb, bool txok)
323{
324 struct htc_endpoint *endpoint;
325 struct htc_frame_hdr *htc_hdr = NULL;
326
327 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
328 complete(&htc_handle->cmd_wait);
329 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
330 goto ret;
331 }
332
333 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
334 complete(&htc_handle->cmd_wait);
335 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
336 goto ret;
337 }
338
339 if (skb) {
340 htc_hdr = (struct htc_frame_hdr *) skb->data;
341 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
342 skb_pull(skb, sizeof(struct htc_frame_hdr));
343
344 if (endpoint->ep_callbacks.tx) {
345 endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
346 skb, htc_hdr->endpoint_id,
347 txok);
348 }
349 }
350
351 return;
352ret:
353 /* HTC-generated packets are freed here. */
354 if (htc_hdr && htc_hdr->endpoint_id != ENDPOINT0)
355 dev_kfree_skb_any(skb);
356 else
357 kfree_skb(skb);
358}
359
360/*
361 * HTC Messages are handled directly here and the obtained SKB
362 * is freed.
363 *
364 * Sevice messages (Data, WMI) passed to the corresponding
365 * endpoint RX handlers, which have to free the SKB.
366 */
367void ath9k_htc_rx_msg(struct htc_target *htc_handle,
368 struct sk_buff *skb, u32 len, u8 pipe_id)
369{
370 struct htc_frame_hdr *htc_hdr;
371 enum htc_endpoint_id epid;
372 struct htc_endpoint *endpoint;
373 __be16 *msg_id;
374
375 if (!htc_handle || !skb)
376 return;
377
378 htc_hdr = (struct htc_frame_hdr *) skb->data;
379 epid = htc_hdr->endpoint_id;
380
381 if (epid >= ENDPOINT_MAX) {
382 if (pipe_id != USB_REG_IN_PIPE)
383 dev_kfree_skb_any(skb);
384 else
385 kfree_skb(skb);
386 return;
387 }
388
389 if (epid == ENDPOINT0) {
390
391 /* Handle trailer */
392 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
393 if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
394 /* Move past the Watchdog pattern */
395 htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
396 }
397
398 /* Get the message ID */
399 msg_id = (__be16 *) ((void *) htc_hdr +
400 sizeof(struct htc_frame_hdr));
401
402 /* Now process HTC messages */
403 switch (be16_to_cpu(*msg_id)) {
404 case HTC_MSG_READY_ID:
405 htc_process_target_rdy(htc_handle, htc_hdr);
406 break;
407 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
408 htc_process_conn_rsp(htc_handle, htc_hdr);
409 break;
410 default:
411 break;
412 }
413
414 kfree_skb(skb);
415
416 } else {
417 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
418 skb_trim(skb, len - htc_hdr->control[0]);
419
420 skb_pull(skb, sizeof(struct htc_frame_hdr));
421
422 endpoint = &htc_handle->endpoint[epid];
423 if (endpoint->ep_callbacks.rx)
424 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
425 skb, epid);
426 }
427}
428
429struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
430 struct ath9k_htc_hif *hif,
431 struct device *dev)
432{
433 struct htc_endpoint *endpoint;
434 struct htc_target *target;
435
436 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
437 if (!target) {
438 printk(KERN_ERR "Unable to allocate memory for"
439 "target device\n");
440 return NULL;
441 }
442
443 init_completion(&target->target_wait);
444 init_completion(&target->cmd_wait);
445
446 target->hif = hif;
447 target->hif_dev = hif_handle;
448 target->dev = dev;
449
450 /* Assign control endpoint pipe IDs */
451 endpoint = &target->endpoint[ENDPOINT0];
452 endpoint->ul_pipeid = hif->control_ul_pipe;
453 endpoint->dl_pipeid = hif->control_dl_pipe;
454
455 atomic_set(&target->tgt_ready, 0);
456
457 return target;
458}
459
460void ath9k_htc_hw_free(struct htc_target *htc)
461{
462 kfree(htc);
463}
464
465int ath9k_htc_hw_init(struct htc_target *target,
466 struct device *dev, u16 devid)
467{
468 if (ath9k_htc_probe_device(target, dev, devid)) {
469 printk(KERN_ERR "Failed to initialize the device\n");
470 return -ENODEV;
471 }
472
473 return 0;
474}
475
476void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
477{
478 if (target)
479 ath9k_htc_disconnect_device(target, hot_unplug);
480}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
new file mode 100644
index 000000000000..faba6790328b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -0,0 +1,245 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_HST_H
18#define HTC_HST_H
19
20struct ath9k_htc_priv;
21struct htc_target;
22struct ath9k_htc_tx_ctl;
23
24enum ath9k_hif_transports {
25 ATH9K_HIF_USB,
26};
27
28struct ath9k_htc_hif {
29 struct list_head list;
30 const enum ath9k_hif_transports transport;
31 const char *name;
32
33 u8 control_dl_pipe;
34 u8 control_ul_pipe;
35
36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
39 struct ath9k_htc_tx_ctl *tx_ctl);
40};
41
42enum htc_endpoint_id {
43 ENDPOINT_UNUSED = -1,
44 ENDPOINT0 = 0,
45 ENDPOINT1 = 1,
46 ENDPOINT2 = 2,
47 ENDPOINT3 = 3,
48 ENDPOINT4 = 4,
49 ENDPOINT5 = 5,
50 ENDPOINT6 = 6,
51 ENDPOINT7 = 7,
52 ENDPOINT8 = 8,
53 ENDPOINT_MAX = 22
54};
55
56/* Htc frame hdr flags */
57#define HTC_FLAGS_RECV_TRAILER (1 << 1)
58
59struct htc_frame_hdr {
60 u8 endpoint_id;
61 u8 flags;
62 __be16 payload_len;
63 u8 control[4];
64} __packed;
65
66struct htc_ready_msg {
67 __be16 message_id;
68 __be16 credits;
69 __be16 credit_size;
70 u8 max_endpoints;
71 u8 pad;
72} __packed;
73
74struct htc_config_pipe_msg {
75 __be16 message_id;
76 u8 pipe_id;
77 u8 credits;
78} __packed;
79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks {
95 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
97 void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
98};
99
100#define HTC_TX_QUEUE_SIZE 256
101
102struct htc_txq {
103 struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
104 u32 txqdepth;
105 u16 txbuf_cnt;
106 u16 txq_head;
107 u16 txq_tail;
108};
109
110struct htc_endpoint {
111 u16 service_id;
112
113 struct htc_ep_callbacks ep_callbacks;
114 struct htc_txq htc_txq;
115 u32 max_txqdepth;
116 int max_msglen;
117
118 u8 ul_pipeid;
119 u8 dl_pipeid;
120};
121
122#define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
123#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125
126struct htc_control_buf {
127 struct htc_packet htc_pkt;
128 u8 buf[HTC_CONTROL_BUFFER_SIZE];
129};
130
131#define HTC_OP_START_WAIT BIT(0)
132#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
133
134struct htc_target {
135 void *hif_dev;
136 struct ath9k_htc_priv *drv_priv;
137 struct device *dev;
138 struct ath9k_htc_hif *hif;
139 struct htc_endpoint endpoint[ENDPOINT_MAX];
140 struct completion target_wait;
141 struct completion cmd_wait;
142 struct list_head list;
143 enum htc_endpoint_id conn_rsp_epid;
144 u16 credits;
145 u16 credit_size;
146 u8 htc_flags;
147 atomic_t tgt_ready;
148};
149
150enum htc_msg_id {
151 HTC_MSG_READY_ID = 1,
152 HTC_MSG_CONNECT_SERVICE_ID,
153 HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
154 HTC_MSG_SETUP_COMPLETE_ID,
155 HTC_MSG_CONFIG_PIPE_ID,
156 HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
157};
158
159struct htc_service_connreq {
160 u16 service_id;
161 u16 con_flags;
162 u32 max_send_qdepth;
163 struct htc_ep_callbacks ep_callbacks;
164};
165
166/* Current service IDs */
167
168enum htc_service_group_ids{
169 RSVD_SERVICE_GROUP = 0,
170 WMI_SERVICE_GROUP = 1,
171
172 HTC_SERVICE_GROUP_LAST = 255
173};
174
175#define MAKE_SERVICE_ID(group, index) \
176 (int)(((int)group << 8) | (int)(index))
177
178/* NOTE: service ID of 0x0000 is reserved and should never be used */
179#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
180#define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
181
182#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
183#define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
184#define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
185#define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
186#define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
187#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
188#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
189#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
190#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
191
192struct htc_conn_svc_msg {
193 __be16 msg_id;
194 __be16 service_id;
195 __be16 con_flags;
196 u8 dl_pipeid;
197 u8 ul_pipeid;
198 u8 svc_meta_len;
199 u8 pad;
200} __packed;
201
202/* connect response status codes */
203#define HTC_SERVICE_SUCCESS 0
204#define HTC_SERVICE_NOT_FOUND 1
205#define HTC_SERVICE_FAILED 2
206#define HTC_SERVICE_NO_RESOURCES 3
207#define HTC_SERVICE_NO_MORE_EP 4
208
209struct htc_conn_svc_rspmsg {
210 __be16 msg_id;
211 __be16 service_id;
212 u8 status;
213 u8 endpoint_id;
214 __be16 max_msg_len;
215 u8 svc_meta_len;
216 u8 pad;
217} __packed;
218
219struct htc_comp_msg {
220 __be16 msg_id;
221} __packed;
222
223int htc_init(struct htc_target *target);
224int htc_connect_service(struct htc_target *target,
225 struct htc_service_connreq *service_connreq,
226 enum htc_endpoint_id *conn_rsp_eid);
227int htc_send(struct htc_target *target, struct sk_buff *skb,
228 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
229void htc_stop(struct htc_target *target);
230void htc_start(struct htc_target *target);
231
232void ath9k_htc_rx_msg(struct htc_target *htc_handle,
233 struct sk_buff *skb, u32 len, u8 pipe_id);
234void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
235 struct sk_buff *skb, bool txok);
236
237struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
238 struct ath9k_htc_hif *hif,
239 struct device *dev);
240void ath9k_htc_hw_free(struct htc_target *htc);
241int ath9k_htc_hw_init(struct htc_target *target,
242 struct device *dev, u16 devid);
243void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
244
245#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
new file mode 100644
index 000000000000..624422a8169e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -0,0 +1,280 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef ATH9K_HW_OPS_H
18#define ATH9K_HW_OPS_H
19
20#include "hw.h"
21
22/* Hardware core and driver accessible callbacks */
23
24static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
25 int restore,
26 int power_off)
27{
28 ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
29}
30
31static inline void ath9k_hw_rxena(struct ath_hw *ah)
32{
33 ath9k_hw_ops(ah)->rx_enable(ah);
34}
35
36static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
37 u32 link)
38{
39 ath9k_hw_ops(ah)->set_desc_link(ds, link);
40}
41
42static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
43 u32 **link)
44{
45 ath9k_hw_ops(ah)->get_desc_link(ds, link);
46}
47static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
48 struct ath9k_channel *chan,
49 u8 rxchainmask,
50 bool longcal)
51{
52 return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
53}
54
55static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
56{
57 return ath9k_hw_ops(ah)->get_isr(ah, masked);
58}
59
60static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
61 bool is_firstseg, bool is_lastseg,
62 const void *ds0, dma_addr_t buf_addr,
63 unsigned int qcu)
64{
65 ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
66 ds0, buf_addr, qcu);
67}
68
69static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
70 struct ath_tx_status *ts)
71{
72 return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
73}
74
75static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
76 u32 pktLen, enum ath9k_pkt_type type,
77 u32 txPower, u32 keyIx,
78 enum ath9k_key_type keyType,
79 u32 flags)
80{
81 ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
82 keyType, flags);
83}
84
85static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
86 void *lastds,
87 u32 durUpdateEn, u32 rtsctsRate,
88 u32 rtsctsDuration,
89 struct ath9k_11n_rate_series series[],
90 u32 nseries, u32 flags)
91{
92 ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
93 rtsctsRate, rtsctsDuration, series,
94 nseries, flags);
95}
96
97static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
98 u32 aggrLen)
99{
100 ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
101}
102
103static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
104 u32 numDelims)
105{
106 ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
107}
108
109static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
110{
111 ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
112}
113
114static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
115{
116 ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
117}
118
119static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
120 u32 burstDuration)
121{
122 ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
123}
124
125static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
126 u32 vmf)
127{
128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
129}
130
131/* Private hardware call ops */
132
133/* PHY ops */
134
135static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
136 struct ath9k_channel *chan)
137{
138 return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan);
139}
140
141static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah,
142 struct ath9k_channel *chan)
143{
144 ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
145}
146
147static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
148{
149 if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
150 return 0;
151
152 return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
153}
154
155static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
156{
157 if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
158 return;
159
160 ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
161}
162
163static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
164 struct ath9k_channel *chan,
165 u16 modesIndex)
166{
167 if (!ath9k_hw_private_ops(ah)->set_rf_regs)
168 return true;
169
170 return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex);
171}
172
173static inline void ath9k_hw_init_bb(struct ath_hw *ah,
174 struct ath9k_channel *chan)
175{
176 return ath9k_hw_private_ops(ah)->init_bb(ah, chan);
177}
178
179static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah,
180 struct ath9k_channel *chan)
181{
182 return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan);
183}
184
185static inline int ath9k_hw_process_ini(struct ath_hw *ah,
186 struct ath9k_channel *chan)
187{
188 return ath9k_hw_private_ops(ah)->process_ini(ah, chan);
189}
190
191static inline void ath9k_olc_init(struct ath_hw *ah)
192{
193 if (!ath9k_hw_private_ops(ah)->olc_init)
194 return;
195
196 return ath9k_hw_private_ops(ah)->olc_init(ah);
197}
198
199static inline void ath9k_hw_set_rfmode(struct ath_hw *ah,
200 struct ath9k_channel *chan)
201{
202 return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan);
203}
204
205static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
206{
207 return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah);
208}
209
210static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah,
211 struct ath9k_channel *chan)
212{
213 return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan);
214}
215
216static inline bool ath9k_hw_rfbus_req(struct ath_hw *ah)
217{
218 return ath9k_hw_private_ops(ah)->rfbus_req(ah);
219}
220
221static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
222{
223 return ath9k_hw_private_ops(ah)->rfbus_done(ah);
224}
225
226static inline void ath9k_enable_rfkill(struct ath_hw *ah)
227{
228 return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
229}
230
231static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
232{
233 if (!ath9k_hw_private_ops(ah)->restore_chainmask)
234 return;
235
236 return ath9k_hw_private_ops(ah)->restore_chainmask(ah);
237}
238
239static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value)
240{
241 return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
242}
243
244static inline bool ath9k_hw_ani_control(struct ath_hw *ah,
245 enum ath9k_ani_cmd cmd, int param)
246{
247 return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
248}
249
250static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
251 int16_t nfarray[NUM_NF_READINGS])
252{
253 ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
254}
255
256static inline void ath9k_hw_loadnf(struct ath_hw *ah,
257 struct ath9k_channel *chan)
258{
259 ath9k_hw_private_ops(ah)->loadnf(ah, chan);
260}
261
262static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
263 struct ath9k_channel *chan)
264{
265 return ath9k_hw_private_ops(ah)->init_cal(ah, chan);
266}
267
268static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
269 struct ath9k_cal_list *currCal)
270{
271 ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
272}
273
274static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
275 enum ath9k_cal_types calType)
276{
277 return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
278}
279
280#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 78b571129c92..c33f17dbe6f1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2010 Atheros Communications 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
@@ -19,18 +19,16 @@
19#include <asm/unaligned.h> 19#include <asm/unaligned.h>
20 20
21#include "hw.h" 21#include "hw.h"
22#include "hw-ops.h"
22#include "rc.h" 23#include "rc.h"
23#include "initvals.h" 24#include "ar9003_mac.h"
24 25
25#define ATH9K_CLOCK_RATE_CCK 22 26#define ATH9K_CLOCK_RATE_CCK 22
26#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 27#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
27#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 28#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
29#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44
28 30
29static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 31static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
30static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
31static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
32 struct ar5416_eeprom_def *pEepData,
33 u32 reg, u32 value);
34 32
35MODULE_AUTHOR("Atheros Communications"); 33MODULE_AUTHOR("Atheros Communications");
36MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); 34MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
@@ -49,6 +47,39 @@ static void __exit ath9k_exit(void)
49} 47}
50module_exit(ath9k_exit); 48module_exit(ath9k_exit);
51 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 void ath9k_hw_init_mode_regs(struct ath_hw *ah)
58{
59 ath9k_hw_private_ops(ah)->init_mode_regs(ah);
60}
61
62static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
63{
64 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
65
66 return priv_ops->macversion_supported(ah->hw_version.macVersion);
67}
68
69static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
70 struct ath9k_channel *chan)
71{
72 return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
73}
74
75static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
76{
77 if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs)
78 return;
79
80 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
81}
82
52/********************/ 83/********************/
53/* Helper Functions */ 84/* Helper Functions */
54/********************/ 85/********************/
@@ -61,7 +92,11 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
61 return usecs *ATH9K_CLOCK_RATE_CCK; 92 return usecs *ATH9K_CLOCK_RATE_CCK;
62 if (conf->channel->band == IEEE80211_BAND_2GHZ) 93 if (conf->channel->band == IEEE80211_BAND_2GHZ)
63 return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; 94 return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
64 return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; 95
96 if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
97 return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
98 else
99 return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM;
65} 100}
66 101
67static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) 102static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
@@ -236,21 +271,6 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
236 } 271 }
237} 272}
238 273
239static int ath9k_hw_get_radiorev(struct ath_hw *ah)
240{
241 u32 val;
242 int i;
243
244 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
245
246 for (i = 0; i < 8; i++)
247 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
248 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
249 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
250
251 return ath9k_hw_reverse_bits(val, 8);
252}
253
254/************************************/ 274/************************************/
255/* HW Attach, Detach, Init Routines */ 275/* HW Attach, Detach, Init Routines */
256/************************************/ 276/************************************/
@@ -260,6 +280,8 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
260 if (AR_SREV_9100(ah)) 280 if (AR_SREV_9100(ah))
261 return; 281 return;
262 282
283 ENABLE_REGWRITE_BUFFER(ah);
284
263 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 285 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
264 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 286 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
265 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); 287 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
@@ -271,20 +293,30 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
271 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); 293 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
272 294
273 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 295 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
296
297 REGWRITE_BUFFER_FLUSH(ah);
298 DISABLE_REGWRITE_BUFFER(ah);
274} 299}
275 300
301/* This should work for all families including legacy */
276static bool ath9k_hw_chip_test(struct ath_hw *ah) 302static bool ath9k_hw_chip_test(struct ath_hw *ah)
277{ 303{
278 struct ath_common *common = ath9k_hw_common(ah); 304 struct ath_common *common = ath9k_hw_common(ah);
279 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; 305 u32 regAddr[2] = { AR_STA_ID0 };
280 u32 regHold[2]; 306 u32 regHold[2];
281 u32 patternData[4] = { 0x55555555, 307 u32 patternData[4] = { 0x55555555,
282 0xaaaaaaaa, 308 0xaaaaaaaa,
283 0x66666666, 309 0x66666666,
284 0x99999999 }; 310 0x99999999 };
285 int i, j; 311 int i, j, loop_max;
312
313 if (!AR_SREV_9300_20_OR_LATER(ah)) {
314 loop_max = 2;
315 regAddr[1] = AR_PHY_BASE + (8 << 2);
316 } else
317 loop_max = 1;
286 318
287 for (i = 0; i < 2; i++) { 319 for (i = 0; i < loop_max; i++) {
288 u32 addr = regAddr[i]; 320 u32 addr = regAddr[i];
289 u32 wrData, rdData; 321 u32 wrData, rdData;
290 322
@@ -339,7 +371,13 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
339 ah->config.ofdm_trig_high = 500; 371 ah->config.ofdm_trig_high = 500;
340 ah->config.cck_trig_high = 200; 372 ah->config.cck_trig_high = 200;
341 ah->config.cck_trig_low = 100; 373 ah->config.cck_trig_low = 100;
342 ah->config.enable_ani = 1; 374
375 /*
376 * For now ANI is disabled for AR9003, it is still
377 * being tested.
378 */
379 if (!AR_SREV_9300_20_OR_LATER(ah))
380 ah->config.enable_ani = 1;
343 381
344 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 382 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
345 ah->config.spurchans[i][0] = AR_NO_SPUR; 383 ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -354,6 +392,12 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
354 ah->config.rx_intr_mitigation = true; 392 ah->config.rx_intr_mitigation = true;
355 393
356 /* 394 /*
395 * Tx IQ Calibration (ah->config.tx_iq_calibration) is only
396 * used by AR9003, but it is showing reliability issues.
397 * It will take a while to fix so this is currently disabled.
398 */
399
400 /*
357 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 401 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
358 * _and_ if on non-uniprocessor systems (Multiprocessor/HT). 402 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
359 * This means we use it for all AR5416 devices, and the few 403 * This means we use it for all AR5416 devices, and the few
@@ -372,7 +416,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
372 if (num_possible_cpus() > 1) 416 if (num_possible_cpus() > 1)
373 ah->config.serialize_regmode = SER_REG_MODE_AUTO; 417 ah->config.serialize_regmode = SER_REG_MODE_AUTO;
374} 418}
375EXPORT_SYMBOL(ath9k_hw_init);
376 419
377static void ath9k_hw_init_defaults(struct ath_hw *ah) 420static void ath9k_hw_init_defaults(struct ath_hw *ah)
378{ 421{
@@ -386,8 +429,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
386 ah->hw_version.subvendorid = 0; 429 ah->hw_version.subvendorid = 0;
387 430
388 ah->ah_flags = 0; 431 ah->ah_flags = 0;
389 if (ah->hw_version.devid == AR5416_AR9100_DEVID)
390 ah->hw_version.macVersion = AR_SREV_VERSION_9100;
391 if (!AR_SREV_9100(ah)) 432 if (!AR_SREV_9100(ah))
392 ah->ah_flags = AH_USE_EEPROM; 433 ah->ah_flags = AH_USE_EEPROM;
393 434
@@ -400,44 +441,17 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
400 ah->power_mode = ATH9K_PM_UNDEFINED; 441 ah->power_mode = ATH9K_PM_UNDEFINED;
401} 442}
402 443
403static int ath9k_hw_rf_claim(struct ath_hw *ah)
404{
405 u32 val;
406
407 REG_WRITE(ah, AR_PHY(0), 0x00000007);
408
409 val = ath9k_hw_get_radiorev(ah);
410 switch (val & AR_RADIO_SREV_MAJOR) {
411 case 0:
412 val = AR_RAD5133_SREV_MAJOR;
413 break;
414 case AR_RAD5133_SREV_MAJOR:
415 case AR_RAD5122_SREV_MAJOR:
416 case AR_RAD2133_SREV_MAJOR:
417 case AR_RAD2122_SREV_MAJOR:
418 break;
419 default:
420 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
421 "Radio Chip Rev 0x%02X not supported\n",
422 val & AR_RADIO_SREV_MAJOR);
423 return -EOPNOTSUPP;
424 }
425
426 ah->hw_version.analog5GhzRev = val;
427
428 return 0;
429}
430
431static int ath9k_hw_init_macaddr(struct ath_hw *ah) 444static int ath9k_hw_init_macaddr(struct ath_hw *ah)
432{ 445{
433 struct ath_common *common = ath9k_hw_common(ah); 446 struct ath_common *common = ath9k_hw_common(ah);
434 u32 sum; 447 u32 sum;
435 int i; 448 int i;
436 u16 eeval; 449 u16 eeval;
450 u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW };
437 451
438 sum = 0; 452 sum = 0;
439 for (i = 0; i < 3; i++) { 453 for (i = 0; i < 3; i++) {
440 eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i)); 454 eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]);
441 sum += eeval; 455 sum += eeval;
442 common->macaddr[2 * i] = eeval >> 8; 456 common->macaddr[2 * i] = eeval >> 8;
443 common->macaddr[2 * i + 1] = eeval & 0xff; 457 common->macaddr[2 * i + 1] = eeval & 0xff;
@@ -448,64 +462,20 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
448 return 0; 462 return 0;
449} 463}
450 464
451static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
452{
453 u32 rxgain_type;
454
455 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
456 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
457
458 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
459 INIT_INI_ARRAY(&ah->iniModesRxGain,
460 ar9280Modes_backoff_13db_rxgain_9280_2,
461 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
462 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
463 INIT_INI_ARRAY(&ah->iniModesRxGain,
464 ar9280Modes_backoff_23db_rxgain_9280_2,
465 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
466 else
467 INIT_INI_ARRAY(&ah->iniModesRxGain,
468 ar9280Modes_original_rxgain_9280_2,
469 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
470 } else {
471 INIT_INI_ARRAY(&ah->iniModesRxGain,
472 ar9280Modes_original_rxgain_9280_2,
473 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
474 }
475}
476
477static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
478{
479 u32 txgain_type;
480
481 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
482 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
483
484 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
485 INIT_INI_ARRAY(&ah->iniModesTxGain,
486 ar9280Modes_high_power_tx_gain_9280_2,
487 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
488 else
489 INIT_INI_ARRAY(&ah->iniModesTxGain,
490 ar9280Modes_original_tx_gain_9280_2,
491 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
492 } else {
493 INIT_INI_ARRAY(&ah->iniModesTxGain,
494 ar9280Modes_original_tx_gain_9280_2,
495 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
496 }
497}
498
499static int ath9k_hw_post_init(struct ath_hw *ah) 465static int ath9k_hw_post_init(struct ath_hw *ah)
500{ 466{
501 int ecode; 467 int ecode;
502 468
503 if (!ath9k_hw_chip_test(ah)) 469 if (!AR_SREV_9271(ah)) {
504 return -ENODEV; 470 if (!ath9k_hw_chip_test(ah))
471 return -ENODEV;
472 }
505 473
506 ecode = ath9k_hw_rf_claim(ah); 474 if (!AR_SREV_9300_20_OR_LATER(ah)) {
507 if (ecode != 0) 475 ecode = ar9002_hw_rf_claim(ah);
508 return ecode; 476 if (ecode != 0)
477 return ecode;
478 }
509 479
510 ecode = ath9k_hw_eeprom_init(ah); 480 ecode = ath9k_hw_eeprom_init(ah);
511 if (ecode != 0) 481 if (ecode != 0)
@@ -516,14 +486,12 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
516 ah->eep_ops->get_eeprom_ver(ah), 486 ah->eep_ops->get_eeprom_ver(ah),
517 ah->eep_ops->get_eeprom_rev(ah)); 487 ah->eep_ops->get_eeprom_rev(ah));
518 488
519 if (!AR_SREV_9280_10_OR_LATER(ah)) { 489 ecode = ath9k_hw_rf_alloc_ext_banks(ah);
520 ecode = ath9k_hw_rf_alloc_ext_banks(ah); 490 if (ecode) {
521 if (ecode) { 491 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
522 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 492 "Failed allocating banks for "
523 "Failed allocating banks for " 493 "external radio\n");
524 "external radio\n"); 494 return ecode;
525 return ecode;
526 }
527 } 495 }
528 496
529 if (!AR_SREV_9100(ah)) { 497 if (!AR_SREV_9100(ah)) {
@@ -534,321 +502,22 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
534 return 0; 502 return 0;
535} 503}
536 504
537static bool ath9k_hw_devid_supported(u16 devid) 505static void ath9k_hw_attach_ops(struct ath_hw *ah)
538{ 506{
539 switch (devid) { 507 if (AR_SREV_9300_20_OR_LATER(ah))
540 case AR5416_DEVID_PCI: 508 ar9003_hw_attach_ops(ah);
541 case AR5416_DEVID_PCIE: 509 else
542 case AR5416_AR9100_DEVID: 510 ar9002_hw_attach_ops(ah);
543 case AR9160_DEVID_PCI:
544 case AR9280_DEVID_PCI:
545 case AR9280_DEVID_PCIE:
546 case AR9285_DEVID_PCIE:
547 case AR5416_DEVID_AR9287_PCI:
548 case AR5416_DEVID_AR9287_PCIE:
549 case AR9271_USB:
550 case AR2427_DEVID_PCIE:
551 return true;
552 default:
553 break;
554 }
555 return false;
556}
557
558static bool ath9k_hw_macversion_supported(u32 macversion)
559{
560 switch (macversion) {
561 case AR_SREV_VERSION_5416_PCI:
562 case AR_SREV_VERSION_5416_PCIE:
563 case AR_SREV_VERSION_9160:
564 case AR_SREV_VERSION_9100:
565 case AR_SREV_VERSION_9280:
566 case AR_SREV_VERSION_9285:
567 case AR_SREV_VERSION_9287:
568 case AR_SREV_VERSION_9271:
569 return true;
570 default:
571 break;
572 }
573 return false;
574}
575
576static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
577{
578 if (AR_SREV_9160_10_OR_LATER(ah)) {
579 if (AR_SREV_9280_10_OR_LATER(ah)) {
580 ah->iq_caldata.calData = &iq_cal_single_sample;
581 ah->adcgain_caldata.calData =
582 &adc_gain_cal_single_sample;
583 ah->adcdc_caldata.calData =
584 &adc_dc_cal_single_sample;
585 ah->adcdc_calinitdata.calData =
586 &adc_init_dc_cal;
587 } else {
588 ah->iq_caldata.calData = &iq_cal_multi_sample;
589 ah->adcgain_caldata.calData =
590 &adc_gain_cal_multi_sample;
591 ah->adcdc_caldata.calData =
592 &adc_dc_cal_multi_sample;
593 ah->adcdc_calinitdata.calData =
594 &adc_init_dc_cal;
595 }
596 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
597 }
598}
599
600static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
601{
602 if (AR_SREV_9271(ah)) {
603 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
604 ARRAY_SIZE(ar9271Modes_9271), 6);
605 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
606 ARRAY_SIZE(ar9271Common_9271), 2);
607 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
608 ar9271Modes_9271_1_0_only,
609 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
610 return;
611 }
612
613 if (AR_SREV_9287_11_OR_LATER(ah)) {
614 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
615 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
616 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
617 ARRAY_SIZE(ar9287Common_9287_1_1), 2);
618 if (ah->config.pcie_clock_req)
619 INIT_INI_ARRAY(&ah->iniPcieSerdes,
620 ar9287PciePhy_clkreq_off_L1_9287_1_1,
621 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
622 else
623 INIT_INI_ARRAY(&ah->iniPcieSerdes,
624 ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
625 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
626 2);
627 } else if (AR_SREV_9287_10_OR_LATER(ah)) {
628 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
629 ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
630 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
631 ARRAY_SIZE(ar9287Common_9287_1_0), 2);
632
633 if (ah->config.pcie_clock_req)
634 INIT_INI_ARRAY(&ah->iniPcieSerdes,
635 ar9287PciePhy_clkreq_off_L1_9287_1_0,
636 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
637 else
638 INIT_INI_ARRAY(&ah->iniPcieSerdes,
639 ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
640 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
641 2);
642 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
643
644
645 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
646 ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
647 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
648 ARRAY_SIZE(ar9285Common_9285_1_2), 2);
649
650 if (ah->config.pcie_clock_req) {
651 INIT_INI_ARRAY(&ah->iniPcieSerdes,
652 ar9285PciePhy_clkreq_off_L1_9285_1_2,
653 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
654 } else {
655 INIT_INI_ARRAY(&ah->iniPcieSerdes,
656 ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
657 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
658 2);
659 }
660 } else if (AR_SREV_9285_10_OR_LATER(ah)) {
661 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
662 ARRAY_SIZE(ar9285Modes_9285), 6);
663 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
664 ARRAY_SIZE(ar9285Common_9285), 2);
665
666 if (ah->config.pcie_clock_req) {
667 INIT_INI_ARRAY(&ah->iniPcieSerdes,
668 ar9285PciePhy_clkreq_off_L1_9285,
669 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
670 } else {
671 INIT_INI_ARRAY(&ah->iniPcieSerdes,
672 ar9285PciePhy_clkreq_always_on_L1_9285,
673 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
674 }
675 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
676 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
677 ARRAY_SIZE(ar9280Modes_9280_2), 6);
678 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
679 ARRAY_SIZE(ar9280Common_9280_2), 2);
680
681 if (ah->config.pcie_clock_req) {
682 INIT_INI_ARRAY(&ah->iniPcieSerdes,
683 ar9280PciePhy_clkreq_off_L1_9280,
684 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
685 } else {
686 INIT_INI_ARRAY(&ah->iniPcieSerdes,
687 ar9280PciePhy_clkreq_always_on_L1_9280,
688 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
689 }
690 INIT_INI_ARRAY(&ah->iniModesAdditional,
691 ar9280Modes_fast_clock_9280_2,
692 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
693 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
694 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
695 ARRAY_SIZE(ar9280Modes_9280), 6);
696 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
697 ARRAY_SIZE(ar9280Common_9280), 2);
698 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
699 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
700 ARRAY_SIZE(ar5416Modes_9160), 6);
701 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
702 ARRAY_SIZE(ar5416Common_9160), 2);
703 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
704 ARRAY_SIZE(ar5416Bank0_9160), 2);
705 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
706 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
707 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
708 ARRAY_SIZE(ar5416Bank1_9160), 2);
709 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
710 ARRAY_SIZE(ar5416Bank2_9160), 2);
711 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
712 ARRAY_SIZE(ar5416Bank3_9160), 3);
713 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
714 ARRAY_SIZE(ar5416Bank6_9160), 3);
715 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
716 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
717 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
718 ARRAY_SIZE(ar5416Bank7_9160), 2);
719 if (AR_SREV_9160_11(ah)) {
720 INIT_INI_ARRAY(&ah->iniAddac,
721 ar5416Addac_91601_1,
722 ARRAY_SIZE(ar5416Addac_91601_1), 2);
723 } else {
724 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
725 ARRAY_SIZE(ar5416Addac_9160), 2);
726 }
727 } else if (AR_SREV_9100_OR_LATER(ah)) {
728 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
729 ARRAY_SIZE(ar5416Modes_9100), 6);
730 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
731 ARRAY_SIZE(ar5416Common_9100), 2);
732 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
733 ARRAY_SIZE(ar5416Bank0_9100), 2);
734 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
735 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
736 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
737 ARRAY_SIZE(ar5416Bank1_9100), 2);
738 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
739 ARRAY_SIZE(ar5416Bank2_9100), 2);
740 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
741 ARRAY_SIZE(ar5416Bank3_9100), 3);
742 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
743 ARRAY_SIZE(ar5416Bank6_9100), 3);
744 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
745 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
746 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
747 ARRAY_SIZE(ar5416Bank7_9100), 2);
748 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
749 ARRAY_SIZE(ar5416Addac_9100), 2);
750 } else {
751 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
752 ARRAY_SIZE(ar5416Modes), 6);
753 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
754 ARRAY_SIZE(ar5416Common), 2);
755 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
756 ARRAY_SIZE(ar5416Bank0), 2);
757 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
758 ARRAY_SIZE(ar5416BB_RfGain), 3);
759 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
760 ARRAY_SIZE(ar5416Bank1), 2);
761 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
762 ARRAY_SIZE(ar5416Bank2), 2);
763 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
764 ARRAY_SIZE(ar5416Bank3), 3);
765 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
766 ARRAY_SIZE(ar5416Bank6), 3);
767 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
768 ARRAY_SIZE(ar5416Bank6TPC), 3);
769 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
770 ARRAY_SIZE(ar5416Bank7), 2);
771 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
772 ARRAY_SIZE(ar5416Addac), 2);
773 }
774}
775
776static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
777{
778 if (AR_SREV_9287_11_OR_LATER(ah))
779 INIT_INI_ARRAY(&ah->iniModesRxGain,
780 ar9287Modes_rx_gain_9287_1_1,
781 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
782 else if (AR_SREV_9287_10(ah))
783 INIT_INI_ARRAY(&ah->iniModesRxGain,
784 ar9287Modes_rx_gain_9287_1_0,
785 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
786 else if (AR_SREV_9280_20(ah))
787 ath9k_hw_init_rxgain_ini(ah);
788
789 if (AR_SREV_9287_11_OR_LATER(ah)) {
790 INIT_INI_ARRAY(&ah->iniModesTxGain,
791 ar9287Modes_tx_gain_9287_1_1,
792 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
793 } else if (AR_SREV_9287_10(ah)) {
794 INIT_INI_ARRAY(&ah->iniModesTxGain,
795 ar9287Modes_tx_gain_9287_1_0,
796 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
797 } else if (AR_SREV_9280_20(ah)) {
798 ath9k_hw_init_txgain_ini(ah);
799 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
800 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
801
802 /* txgain table */
803 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
804 INIT_INI_ARRAY(&ah->iniModesTxGain,
805 ar9285Modes_high_power_tx_gain_9285_1_2,
806 ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
807 } else {
808 INIT_INI_ARRAY(&ah->iniModesTxGain,
809 ar9285Modes_original_tx_gain_9285_1_2,
810 ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
811 }
812
813 }
814}
815
816static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
817{
818 u32 i, j;
819
820 if (ah->hw_version.devid == AR9280_DEVID_PCI) {
821
822 /* EEPROM Fixup */
823 for (i = 0; i < ah->iniModes.ia_rows; i++) {
824 u32 reg = INI_RA(&ah->iniModes, i, 0);
825
826 for (j = 1; j < ah->iniModes.ia_columns; j++) {
827 u32 val = INI_RA(&ah->iniModes, i, j);
828
829 INI_RA(&ah->iniModes, i, j) =
830 ath9k_hw_ini_fixup(ah,
831 &ah->eeprom.def,
832 reg, val);
833 }
834 }
835 }
836} 511}
837 512
838int ath9k_hw_init(struct ath_hw *ah) 513/* Called for all hardware families */
514static int __ath9k_hw_init(struct ath_hw *ah)
839{ 515{
840 struct ath_common *common = ath9k_hw_common(ah); 516 struct ath_common *common = ath9k_hw_common(ah);
841 int r = 0; 517 int r = 0;
842 518
843 if (!ath9k_hw_devid_supported(ah->hw_version.devid)) { 519 if (ah->hw_version.devid == AR5416_AR9100_DEVID)
844 ath_print(common, ATH_DBG_FATAL, 520 ah->hw_version.macVersion = AR_SREV_VERSION_9100;
845 "Unsupported device ID: 0x%0x\n",
846 ah->hw_version.devid);
847 return -EOPNOTSUPP;
848 }
849
850 ath9k_hw_init_defaults(ah);
851 ath9k_hw_init_config(ah);
852 521
853 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { 522 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
854 ath_print(common, ATH_DBG_FATAL, 523 ath_print(common, ATH_DBG_FATAL,
@@ -856,6 +525,11 @@ int ath9k_hw_init(struct ath_hw *ah)
856 return -EIO; 525 return -EIO;
857 } 526 }
858 527
528 ath9k_hw_init_defaults(ah);
529 ath9k_hw_init_config(ah);
530
531 ath9k_hw_attach_ops(ah);
532
859 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { 533 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
860 ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); 534 ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
861 return -EIO; 535 return -EIO;
@@ -880,7 +554,7 @@ int ath9k_hw_init(struct ath_hw *ah)
880 else 554 else
881 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; 555 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
882 556
883 if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { 557 if (!ath9k_hw_macversion_supported(ah)) {
884 ath_print(common, ATH_DBG_FATAL, 558 ath_print(common, ATH_DBG_FATAL,
885 "Mac Chip Rev 0x%02x.%x is not supported by " 559 "Mac Chip Rev 0x%02x.%x is not supported by "
886 "this driver\n", ah->hw_version.macVersion, 560 "this driver\n", ah->hw_version.macVersion,
@@ -888,45 +562,45 @@ int ath9k_hw_init(struct ath_hw *ah)
888 return -EOPNOTSUPP; 562 return -EOPNOTSUPP;
889 } 563 }
890 564
891 if (AR_SREV_9100(ah)) { 565 if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
892 ah->iq_caldata.calData = &iq_cal_multi_sample;
893 ah->supp_cals = IQ_MISMATCH_CAL;
894 ah->is_pciexpress = false;
895 }
896
897 if (AR_SREV_9271(ah))
898 ah->is_pciexpress = false; 566 ah->is_pciexpress = false;
899 567
900 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 568 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
901
902 ath9k_hw_init_cal_settings(ah); 569 ath9k_hw_init_cal_settings(ah);
903 570
904 ah->ani_function = ATH9K_ANI_ALL; 571 ah->ani_function = ATH9K_ANI_ALL;
905 if (AR_SREV_9280_10_OR_LATER(ah)) { 572 if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
906 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 573 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
907 ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
908 ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate;
909 } else {
910 ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
911 ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate;
912 }
913 574
914 ath9k_hw_init_mode_regs(ah); 575 ath9k_hw_init_mode_regs(ah);
915 576
577 /*
578 * Configire PCIE after Ini init. SERDES values now come from ini file
579 * This enables PCIe low power mode.
580 */
581 if (AR_SREV_9300_20_OR_LATER(ah)) {
582 u32 regval;
583 unsigned int i;
584
585 /* Set Bits 16 and 17 in the AR_WA register. */
586 regval = REG_READ(ah, AR_WA);
587 regval |= 0x00030000;
588 REG_WRITE(ah, AR_WA, regval);
589
590 for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) {
591 REG_WRITE(ah,
592 INI_RA(&ah->iniPcieSerdesLowPower, i, 0),
593 INI_RA(&ah->iniPcieSerdesLowPower, i, 1));
594 }
595 }
596
916 if (ah->is_pciexpress) 597 if (ah->is_pciexpress)
917 ath9k_hw_configpcipowersave(ah, 0, 0); 598 ath9k_hw_configpcipowersave(ah, 0, 0);
918 else 599 else
919 ath9k_hw_disablepcie(ah); 600 ath9k_hw_disablepcie(ah);
920 601
921 /* Support for Japan ch.14 (2484) spread */ 602 if (!AR_SREV_9300_20_OR_LATER(ah))
922 if (AR_SREV_9287_11_OR_LATER(ah)) { 603 ar9002_hw_cck_chan14_spread(ah);
923 INIT_INI_ARRAY(&ah->iniCckfirNormal,
924 ar9287Common_normal_cck_fir_coeff_92871_1,
925 ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2);
926 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
927 ar9287Common_japan_2484_cck_fir_coeff_92871_1,
928 ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2);
929 }
930 604
931 r = ath9k_hw_post_init(ah); 605 r = ath9k_hw_post_init(ah);
932 if (r) 606 if (r)
@@ -937,8 +611,6 @@ int ath9k_hw_init(struct ath_hw *ah)
937 if (r) 611 if (r)
938 return r; 612 return r;
939 613
940 ath9k_hw_init_eeprom_fix(ah);
941
942 r = ath9k_hw_init_macaddr(ah); 614 r = ath9k_hw_init_macaddr(ah);
943 if (r) { 615 if (r) {
944 ath_print(common, ATH_DBG_FATAL, 616 ath_print(common, ATH_DBG_FATAL,
@@ -951,6 +623,9 @@ int ath9k_hw_init(struct ath_hw *ah)
951 else 623 else
952 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); 624 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
953 625
626 if (AR_SREV_9300_20_OR_LATER(ah))
627 ar9003_hw_set_nf_limits(ah);
628
954 ath9k_init_nfcal_hist_buffer(ah); 629 ath9k_init_nfcal_hist_buffer(ah);
955 630
956 common->state = ATH_HW_INITIALIZED; 631 common->state = ATH_HW_INITIALIZED;
@@ -958,24 +633,50 @@ int ath9k_hw_init(struct ath_hw *ah)
958 return 0; 633 return 0;
959} 634}
960 635
961static void ath9k_hw_init_bb(struct ath_hw *ah, 636int ath9k_hw_init(struct ath_hw *ah)
962 struct ath9k_channel *chan)
963{ 637{
964 u32 synthDelay; 638 int ret;
639 struct ath_common *common = ath9k_hw_common(ah);
965 640
966 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 641 /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */
967 if (IS_CHAN_B(chan)) 642 switch (ah->hw_version.devid) {
968 synthDelay = (4 * synthDelay) / 22; 643 case AR5416_DEVID_PCI:
969 else 644 case AR5416_DEVID_PCIE:
970 synthDelay /= 10; 645 case AR5416_AR9100_DEVID:
646 case AR9160_DEVID_PCI:
647 case AR9280_DEVID_PCI:
648 case AR9280_DEVID_PCIE:
649 case AR9285_DEVID_PCIE:
650 case AR9287_DEVID_PCI:
651 case AR9287_DEVID_PCIE:
652 case AR2427_DEVID_PCIE:
653 case AR9300_DEVID_PCIE:
654 break;
655 default:
656 if (common->bus_ops->ath_bus_type == ATH_USB)
657 break;
658 ath_print(common, ATH_DBG_FATAL,
659 "Hardware device ID 0x%04x not supported\n",
660 ah->hw_version.devid);
661 return -EOPNOTSUPP;
662 }
971 663
972 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 664 ret = __ath9k_hw_init(ah);
665 if (ret) {
666 ath_print(common, ATH_DBG_FATAL,
667 "Unable to initialize hardware; "
668 "initialization status: %d\n", ret);
669 return ret;
670 }
973 671
974 udelay(synthDelay + BASE_ACTIVATE_DELAY); 672 return 0;
975} 673}
674EXPORT_SYMBOL(ath9k_hw_init);
976 675
977static void ath9k_hw_init_qos(struct ath_hw *ah) 676static void ath9k_hw_init_qos(struct ath_hw *ah)
978{ 677{
678 ENABLE_REGWRITE_BUFFER(ah);
679
979 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); 680 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
980 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); 681 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
981 682
@@ -989,105 +690,22 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
989 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 690 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
990 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 691 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
991 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 692 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
992}
993
994static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
995{
996 u32 lcr;
997 u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
998
999 lcr = REG_READ(ah , 0x5100c);
1000 lcr |= 0x80;
1001 693
1002 REG_WRITE(ah, 0x5100c, lcr); 694 REGWRITE_BUFFER_FLUSH(ah);
1003 REG_WRITE(ah, 0x51004, (baud_divider >> 8)); 695 DISABLE_REGWRITE_BUFFER(ah);
1004 REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
1005
1006 lcr &= ~0x80;
1007 REG_WRITE(ah, 0x5100c, lcr);
1008} 696}
1009 697
1010static void ath9k_hw_init_pll(struct ath_hw *ah, 698static void ath9k_hw_init_pll(struct ath_hw *ah,
1011 struct ath9k_channel *chan) 699 struct ath9k_channel *chan)
1012{ 700{
1013 u32 pll; 701 u32 pll = ath9k_hw_compute_pll_control(ah, chan);
1014
1015 if (AR_SREV_9100(ah)) {
1016 if (chan && IS_CHAN_5GHZ(chan))
1017 pll = 0x1450;
1018 else
1019 pll = 0x1458;
1020 } else {
1021 if (AR_SREV_9280_10_OR_LATER(ah)) {
1022 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1023
1024 if (chan && IS_CHAN_HALF_RATE(chan))
1025 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1026 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1027 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1028
1029 if (chan && IS_CHAN_5GHZ(chan)) {
1030 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1031
1032
1033 if (AR_SREV_9280_20(ah)) {
1034 if (((chan->channel % 20) == 0)
1035 || ((chan->channel % 10) == 0))
1036 pll = 0x2850;
1037 else
1038 pll = 0x142c;
1039 }
1040 } else {
1041 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1042 }
1043
1044 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1045
1046 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1047
1048 if (chan && IS_CHAN_HALF_RATE(chan))
1049 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1050 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1051 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1052
1053 if (chan && IS_CHAN_5GHZ(chan))
1054 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1055 else
1056 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1057 } else {
1058 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1059
1060 if (chan && IS_CHAN_HALF_RATE(chan))
1061 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1062 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1063 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1064 702
1065 if (chan && IS_CHAN_5GHZ(chan))
1066 pll |= SM(0xa, AR_RTC_PLL_DIV);
1067 else
1068 pll |= SM(0xb, AR_RTC_PLL_DIV);
1069 }
1070 }
1071 REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 703 REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1072 704
1073 /* Switch the core clock for ar9271 to 117Mhz */ 705 /* Switch the core clock for ar9271 to 117Mhz */
1074 if (AR_SREV_9271(ah)) { 706 if (AR_SREV_9271(ah)) {
1075 if ((pll == 0x142c) || (pll == 0x2850) ) { 707 udelay(500);
1076 udelay(500); 708 REG_WRITE(ah, 0x50040, 0x304);
1077 /* set CLKOBS to output AHB clock */
1078 REG_WRITE(ah, 0x7020, 0xe);
1079 /*
1080 * 0x304: 117Mhz, ahb_ratio: 1x1
1081 * 0x306: 40Mhz, ahb_ratio: 1x1
1082 */
1083 REG_WRITE(ah, 0x50040, 0x304);
1084 /*
1085 * makes adjustments for the baud dividor to keep the
1086 * targetted baud rate based on the used core clock.
1087 */
1088 ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
1089 AR9271_TARGET_BAUD_RATE);
1090 }
1091 } 709 }
1092 710
1093 udelay(RTC_PLL_SETTLE_DELAY); 711 udelay(RTC_PLL_SETTLE_DELAY);
@@ -1095,70 +713,58 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
1095 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); 713 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1096} 714}
1097 715
1098static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
1099{
1100 int rx_chainmask, tx_chainmask;
1101
1102 rx_chainmask = ah->rxchainmask;
1103 tx_chainmask = ah->txchainmask;
1104
1105 switch (rx_chainmask) {
1106 case 0x5:
1107 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
1108 AR_PHY_SWAP_ALT_CHAIN);
1109 case 0x3:
1110 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
1111 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
1112 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
1113 break;
1114 }
1115 case 0x1:
1116 case 0x2:
1117 case 0x7:
1118 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
1119 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
1120 break;
1121 default:
1122 break;
1123 }
1124
1125 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
1126 if (tx_chainmask == 0x5) {
1127 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
1128 AR_PHY_SWAP_ALT_CHAIN);
1129 }
1130 if (AR_SREV_9100(ah))
1131 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
1132 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
1133}
1134
1135static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, 716static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1136 enum nl80211_iftype opmode) 717 enum nl80211_iftype opmode)
1137{ 718{
1138 ah->mask_reg = AR_IMR_TXERR | 719 u32 imr_reg = AR_IMR_TXERR |
1139 AR_IMR_TXURN | 720 AR_IMR_TXURN |
1140 AR_IMR_RXERR | 721 AR_IMR_RXERR |
1141 AR_IMR_RXORN | 722 AR_IMR_RXORN |
1142 AR_IMR_BCNMISC; 723 AR_IMR_BCNMISC;
1143 724
1144 if (ah->config.rx_intr_mitigation) 725 if (AR_SREV_9300_20_OR_LATER(ah)) {
1145 ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 726 imr_reg |= AR_IMR_RXOK_HP;
1146 else 727 if (ah->config.rx_intr_mitigation)
1147 ah->mask_reg |= AR_IMR_RXOK; 728 imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
729 else
730 imr_reg |= AR_IMR_RXOK_LP;
1148 731
1149 ah->mask_reg |= AR_IMR_TXOK; 732 } else {
733 if (ah->config.rx_intr_mitigation)
734 imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
735 else
736 imr_reg |= AR_IMR_RXOK;
737 }
738
739 if (ah->config.tx_intr_mitigation)
740 imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
741 else
742 imr_reg |= AR_IMR_TXOK;
1150 743
1151 if (opmode == NL80211_IFTYPE_AP) 744 if (opmode == NL80211_IFTYPE_AP)
1152 ah->mask_reg |= AR_IMR_MIB; 745 imr_reg |= AR_IMR_MIB;
746
747 ENABLE_REGWRITE_BUFFER(ah);
1153 748
1154 REG_WRITE(ah, AR_IMR, ah->mask_reg); 749 REG_WRITE(ah, AR_IMR, imr_reg);
1155 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); 750 ah->imrs2_reg |= AR_IMR_S2_GTT;
751 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
1156 752
1157 if (!AR_SREV_9100(ah)) { 753 if (!AR_SREV_9100(ah)) {
1158 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); 754 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
1159 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); 755 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
1160 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); 756 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
1161 } 757 }
758
759 REGWRITE_BUFFER_FLUSH(ah);
760 DISABLE_REGWRITE_BUFFER(ah);
761
762 if (AR_SREV_9300_20_OR_LATER(ah)) {
763 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
764 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, 0);
765 REG_WRITE(ah, AR_INTR_PRIO_SYNC_ENABLE, 0);
766 REG_WRITE(ah, AR_INTR_PRIO_SYNC_MASK, 0);
767 }
1162} 768}
1163 769
1164static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) 770static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
@@ -1241,19 +847,13 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1241{ 847{
1242 struct ath_common *common = ath9k_hw_common(ah); 848 struct ath_common *common = ath9k_hw_common(ah);
1243 849
1244 if (common->state <= ATH_HW_INITIALIZED) 850 if (common->state < ATH_HW_INITIALIZED)
1245 goto free_hw; 851 goto free_hw;
1246 852
1247 if (!AR_SREV_9100(ah))
1248 ath9k_hw_ani_disable(ah);
1249
1250 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); 853 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1251 854
1252free_hw: 855free_hw:
1253 if (!AR_SREV_9280_10_OR_LATER(ah)) 856 ath9k_hw_rf_free_ext_banks(ah);
1254 ath9k_hw_rf_free_ext_banks(ah);
1255 kfree(ah);
1256 ah = NULL;
1257} 857}
1258EXPORT_SYMBOL(ath9k_hw_deinit); 858EXPORT_SYMBOL(ath9k_hw_deinit);
1259 859
@@ -1261,136 +861,7 @@ EXPORT_SYMBOL(ath9k_hw_deinit);
1261/* INI */ 861/* INI */
1262/*******/ 862/*******/
1263 863
1264static void ath9k_hw_override_ini(struct ath_hw *ah, 864u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
1265 struct ath9k_channel *chan)
1266{
1267 u32 val;
1268
1269 if (AR_SREV_9271(ah)) {
1270 /*
1271 * Enable spectral scan to solution for issues with stuck
1272 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
1273 * AR9271 1.1
1274 */
1275 if (AR_SREV_9271_10(ah)) {
1276 val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
1277 AR_PHY_SPECTRAL_SCAN_ENABLE;
1278 REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
1279 }
1280 else if (AR_SREV_9271_11(ah))
1281 /*
1282 * change AR_PHY_RF_CTL3 setting to fix MAC issue
1283 * present on AR9271 1.1
1284 */
1285 REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
1286 return;
1287 }
1288
1289 /*
1290 * Set the RX_ABORT and RX_DIS and clear if off only after
1291 * RXE is set for MAC. This prevents frames with corrupted
1292 * descriptor status.
1293 */
1294 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1295
1296 if (AR_SREV_9280_10_OR_LATER(ah)) {
1297 val = REG_READ(ah, AR_PCU_MISC_MODE2) &
1298 (~AR_PCU_MISC_MODE2_HWWAR1);
1299
1300 if (AR_SREV_9287_10_OR_LATER(ah))
1301 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
1302
1303 REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
1304 }
1305
1306 if (!AR_SREV_5416_20_OR_LATER(ah) ||
1307 AR_SREV_9280_10_OR_LATER(ah))
1308 return;
1309 /*
1310 * Disable BB clock gating
1311 * Necessary to avoid issues on AR5416 2.0
1312 */
1313 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
1314
1315 /*
1316 * Disable RIFS search on some chips to avoid baseband
1317 * hang issues.
1318 */
1319 if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
1320 val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
1321 val &= ~AR_PHY_RIFS_INIT_DELAY;
1322 REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
1323 }
1324}
1325
1326static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
1327 struct ar5416_eeprom_def *pEepData,
1328 u32 reg, u32 value)
1329{
1330 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
1331 struct ath_common *common = ath9k_hw_common(ah);
1332
1333 switch (ah->hw_version.devid) {
1334 case AR9280_DEVID_PCI:
1335 if (reg == 0x7894) {
1336 ath_print(common, ATH_DBG_EEPROM,
1337 "ini VAL: %x EEPROM: %x\n", value,
1338 (pBase->version & 0xff));
1339
1340 if ((pBase->version & 0xff) > 0x0a) {
1341 ath_print(common, ATH_DBG_EEPROM,
1342 "PWDCLKIND: %d\n",
1343 pBase->pwdclkind);
1344 value &= ~AR_AN_TOP2_PWDCLKIND;
1345 value |= AR_AN_TOP2_PWDCLKIND &
1346 (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
1347 } else {
1348 ath_print(common, ATH_DBG_EEPROM,
1349 "PWDCLKIND Earlier Rev\n");
1350 }
1351
1352 ath_print(common, ATH_DBG_EEPROM,
1353 "final ini VAL: %x\n", value);
1354 }
1355 break;
1356 }
1357
1358 return value;
1359}
1360
1361static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
1362 struct ar5416_eeprom_def *pEepData,
1363 u32 reg, u32 value)
1364{
1365 if (ah->eep_map == EEP_MAP_4KBITS)
1366 return value;
1367 else
1368 return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
1369}
1370
1371static void ath9k_olc_init(struct ath_hw *ah)
1372{
1373 u32 i;
1374
1375 if (OLC_FOR_AR9287_10_LATER) {
1376 REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
1377 AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
1378 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
1379 AR9287_AN_TXPC0_TXPCMODE,
1380 AR9287_AN_TXPC0_TXPCMODE_S,
1381 AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
1382 udelay(100);
1383 } else {
1384 for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
1385 ah->originalGain[i] =
1386 MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
1387 AR_PHY_TX_GAIN);
1388 ah->PDADCdelta = 0;
1389 }
1390}
1391
1392static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
1393 struct ath9k_channel *chan)
1394{ 865{
1395 u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); 866 u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
1396 867
@@ -1404,173 +875,24 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
1404 return ctl; 875 return ctl;
1405} 876}
1406 877
1407static int ath9k_hw_process_ini(struct ath_hw *ah,
1408 struct ath9k_channel *chan)
1409{
1410 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1411 int i, regWrites = 0;
1412 struct ieee80211_channel *channel = chan->chan;
1413 u32 modesIndex, freqIndex;
1414
1415 switch (chan->chanmode) {
1416 case CHANNEL_A:
1417 case CHANNEL_A_HT20:
1418 modesIndex = 1;
1419 freqIndex = 1;
1420 break;
1421 case CHANNEL_A_HT40PLUS:
1422 case CHANNEL_A_HT40MINUS:
1423 modesIndex = 2;
1424 freqIndex = 1;
1425 break;
1426 case CHANNEL_G:
1427 case CHANNEL_G_HT20:
1428 case CHANNEL_B:
1429 modesIndex = 4;
1430 freqIndex = 2;
1431 break;
1432 case CHANNEL_G_HT40PLUS:
1433 case CHANNEL_G_HT40MINUS:
1434 modesIndex = 3;
1435 freqIndex = 2;
1436 break;
1437
1438 default:
1439 return -EINVAL;
1440 }
1441
1442 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1443 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
1444 ah->eep_ops->set_addac(ah, chan);
1445
1446 if (AR_SREV_5416_22_OR_LATER(ah)) {
1447 REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
1448 } else {
1449 struct ar5416IniArray temp;
1450 u32 addacSize =
1451 sizeof(u32) * ah->iniAddac.ia_rows *
1452 ah->iniAddac.ia_columns;
1453
1454 memcpy(ah->addac5416_21,
1455 ah->iniAddac.ia_array, addacSize);
1456
1457 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
1458
1459 temp.ia_array = ah->addac5416_21;
1460 temp.ia_columns = ah->iniAddac.ia_columns;
1461 temp.ia_rows = ah->iniAddac.ia_rows;
1462 REG_WRITE_ARRAY(&temp, 1, regWrites);
1463 }
1464
1465 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
1466
1467 for (i = 0; i < ah->iniModes.ia_rows; i++) {
1468 u32 reg = INI_RA(&ah->iniModes, i, 0);
1469 u32 val = INI_RA(&ah->iniModes, i, modesIndex);
1470
1471 REG_WRITE(ah, reg, val);
1472
1473 if (reg >= 0x7800 && reg < 0x78a0
1474 && ah->config.analog_shiftreg) {
1475 udelay(100);
1476 }
1477
1478 DO_DELAY(regWrites);
1479 }
1480
1481 if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
1482 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
1483
1484 if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
1485 AR_SREV_9287_10_OR_LATER(ah))
1486 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1487
1488 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
1489 u32 reg = INI_RA(&ah->iniCommon, i, 0);
1490 u32 val = INI_RA(&ah->iniCommon, i, 1);
1491
1492 REG_WRITE(ah, reg, val);
1493
1494 if (reg >= 0x7800 && reg < 0x78a0
1495 && ah->config.analog_shiftreg) {
1496 udelay(100);
1497 }
1498
1499 DO_DELAY(regWrites);
1500 }
1501
1502 ath9k_hw_write_regs(ah, freqIndex, regWrites);
1503
1504 if (AR_SREV_9271_10(ah))
1505 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1506 modesIndex, regWrites);
1507
1508 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
1509 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
1510 regWrites);
1511 }
1512
1513 ath9k_hw_override_ini(ah, chan);
1514 ath9k_hw_set_regs(ah, chan);
1515 ath9k_hw_init_chain_masks(ah);
1516
1517 if (OLC_FOR_AR9280_20_LATER)
1518 ath9k_olc_init(ah);
1519
1520 ah->eep_ops->set_txpower(ah, chan,
1521 ath9k_regd_get_ctl(regulatory, chan),
1522 channel->max_antenna_gain * 2,
1523 channel->max_power * 2,
1524 min((u32) MAX_RATE_POWER,
1525 (u32) regulatory->power_limit));
1526
1527 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1528 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
1529 "ar5416SetRfRegs failed\n");
1530 return -EIO;
1531 }
1532
1533 return 0;
1534}
1535
1536/****************************************/ 878/****************************************/
1537/* Reset and Channel Switching Routines */ 879/* Reset and Channel Switching Routines */
1538/****************************************/ 880/****************************************/
1539 881
1540static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
1541{
1542 u32 rfMode = 0;
1543
1544 if (chan == NULL)
1545 return;
1546
1547 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1548 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1549
1550 if (!AR_SREV_9280_10_OR_LATER(ah))
1551 rfMode |= (IS_CHAN_5GHZ(chan)) ?
1552 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
1553
1554 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1555 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1556
1557 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1558}
1559
1560static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
1561{
1562 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1563}
1564
1565static inline void ath9k_hw_set_dma(struct ath_hw *ah) 882static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1566{ 883{
884 struct ath_common *common = ath9k_hw_common(ah);
1567 u32 regval; 885 u32 regval;
1568 886
887 ENABLE_REGWRITE_BUFFER(ah);
888
1569 /* 889 /*
1570 * set AHB_MODE not to do cacheline prefetches 890 * set AHB_MODE not to do cacheline prefetches
1571 */ 891 */
1572 regval = REG_READ(ah, AR_AHB_MODE); 892 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1573 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); 893 regval = REG_READ(ah, AR_AHB_MODE);
894 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
895 }
1574 896
1575 /* 897 /*
1576 * let mac dma reads be in 128 byte chunks 898 * let mac dma reads be in 128 byte chunks
@@ -1578,12 +900,18 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1578 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; 900 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
1579 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); 901 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
1580 902
903 REGWRITE_BUFFER_FLUSH(ah);
904 DISABLE_REGWRITE_BUFFER(ah);
905
1581 /* 906 /*
1582 * Restore TX Trigger Level to its pre-reset value. 907 * Restore TX Trigger Level to its pre-reset value.
1583 * The initial value depends on whether aggregation is enabled, and is 908 * The initial value depends on whether aggregation is enabled, and is
1584 * adjusted whenever underruns are detected. 909 * adjusted whenever underruns are detected.
1585 */ 910 */
1586 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); 911 if (!AR_SREV_9300_20_OR_LATER(ah))
912 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
913
914 ENABLE_REGWRITE_BUFFER(ah);
1587 915
1588 /* 916 /*
1589 * let mac dma writes be in 128 byte chunks 917 * let mac dma writes be in 128 byte chunks
@@ -1596,6 +924,14 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1596 */ 924 */
1597 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 925 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
1598 926
927 if (AR_SREV_9300_20_OR_LATER(ah)) {
928 REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
929 REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
930
931 ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
932 ah->caps.rx_status_len);
933 }
934
1599 /* 935 /*
1600 * reduce the number of usable entries in PCU TXBUF to avoid 936 * reduce the number of usable entries in PCU TXBUF to avoid
1601 * wrap around issues. 937 * wrap around issues.
@@ -1611,6 +947,12 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1611 REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 947 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
1612 AR_PCU_TXBUF_CTRL_USABLE_SIZE); 948 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
1613 } 949 }
950
951 REGWRITE_BUFFER_FLUSH(ah);
952 DISABLE_REGWRITE_BUFFER(ah);
953
954 if (AR_SREV_9300_20_OR_LATER(ah))
955 ath9k_hw_reset_txstatus_ring(ah);
1614} 956}
1615 957
1616static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) 958static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
@@ -1638,10 +980,8 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1638 } 980 }
1639} 981}
1640 982
1641static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, 983void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
1642 u32 coef_scaled, 984 u32 *coef_mantissa, u32 *coef_exponent)
1643 u32 *coef_mantissa,
1644 u32 *coef_exponent)
1645{ 985{
1646 u32 coef_exp, coef_man; 986 u32 coef_exp, coef_man;
1647 987
@@ -1657,40 +997,6 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
1657 *coef_exponent = coef_exp - 16; 997 *coef_exponent = coef_exp - 16;
1658} 998}
1659 999
1660static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
1661 struct ath9k_channel *chan)
1662{
1663 u32 coef_scaled, ds_coef_exp, ds_coef_man;
1664 u32 clockMhzScaled = 0x64000000;
1665 struct chan_centers centers;
1666
1667 if (IS_CHAN_HALF_RATE(chan))
1668 clockMhzScaled = clockMhzScaled >> 1;
1669 else if (IS_CHAN_QUARTER_RATE(chan))
1670 clockMhzScaled = clockMhzScaled >> 2;
1671
1672 ath9k_hw_get_channel_centers(ah, chan, &centers);
1673 coef_scaled = clockMhzScaled / centers.synth_center;
1674
1675 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
1676 &ds_coef_exp);
1677
1678 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1679 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
1680 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1681 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
1682
1683 coef_scaled = (9 * coef_scaled) / 10;
1684
1685 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
1686 &ds_coef_exp);
1687
1688 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
1689 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
1690 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
1691 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
1692}
1693
1694static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) 1000static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1695{ 1001{
1696 u32 rst_flags; 1002 u32 rst_flags;
@@ -1704,6 +1010,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1704 (void)REG_READ(ah, AR_RTC_DERIVED_CLK); 1010 (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
1705 } 1011 }
1706 1012
1013 ENABLE_REGWRITE_BUFFER(ah);
1014
1707 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1015 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1708 AR_RTC_FORCE_WAKE_ON_INT); 1016 AR_RTC_FORCE_WAKE_ON_INT);
1709 1017
@@ -1715,11 +1023,16 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1715 if (tmpReg & 1023 if (tmpReg &
1716 (AR_INTR_SYNC_LOCAL_TIMEOUT | 1024 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1717 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1025 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1026 u32 val;
1718 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1027 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1719 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 1028
1720 } else { 1029 val = AR_RC_HOSTIF;
1030 if (!AR_SREV_9300_20_OR_LATER(ah))
1031 val |= AR_RC_AHB;
1032 REG_WRITE(ah, AR_RC, val);
1033
1034 } else if (!AR_SREV_9300_20_OR_LATER(ah))
1721 REG_WRITE(ah, AR_RC, AR_RC_AHB); 1035 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1722 }
1723 1036
1724 rst_flags = AR_RTC_RC_MAC_WARM; 1037 rst_flags = AR_RTC_RC_MAC_WARM;
1725 if (type == ATH9K_RESET_COLD) 1038 if (type == ATH9K_RESET_COLD)
@@ -1727,6 +1040,10 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1727 } 1040 }
1728 1041
1729 REG_WRITE(ah, AR_RTC_RC, rst_flags); 1042 REG_WRITE(ah, AR_RTC_RC, rst_flags);
1043
1044 REGWRITE_BUFFER_FLUSH(ah);
1045 DISABLE_REGWRITE_BUFFER(ah);
1046
1730 udelay(50); 1047 udelay(50);
1731 1048
1732 REG_WRITE(ah, AR_RTC_RC, 0); 1049 REG_WRITE(ah, AR_RTC_RC, 0);
@@ -1747,16 +1064,23 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1747 1064
1748static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) 1065static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1749{ 1066{
1067 ENABLE_REGWRITE_BUFFER(ah);
1068
1750 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1069 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1751 AR_RTC_FORCE_WAKE_ON_INT); 1070 AR_RTC_FORCE_WAKE_ON_INT);
1752 1071
1753 if (!AR_SREV_9100(ah)) 1072 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1754 REG_WRITE(ah, AR_RC, AR_RC_AHB); 1073 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1755 1074
1756 REG_WRITE(ah, AR_RTC_RESET, 0); 1075 REG_WRITE(ah, AR_RTC_RESET, 0);
1757 udelay(2);
1758 1076
1759 if (!AR_SREV_9100(ah)) 1077 REGWRITE_BUFFER_FLUSH(ah);
1078 DISABLE_REGWRITE_BUFFER(ah);
1079
1080 if (!AR_SREV_9300_20_OR_LATER(ah))
1081 udelay(2);
1082
1083 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
1760 REG_WRITE(ah, AR_RC, 0); 1084 REG_WRITE(ah, AR_RC, 0);
1761 1085
1762 REG_WRITE(ah, AR_RTC_RESET, 1); 1086 REG_WRITE(ah, AR_RTC_RESET, 1);
@@ -1792,34 +1116,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1792 } 1116 }
1793} 1117}
1794 1118
1795static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
1796{
1797 u32 phymode;
1798 u32 enableDacFifo = 0;
1799
1800 if (AR_SREV_9285_10_OR_LATER(ah))
1801 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
1802 AR_PHY_FC_ENABLE_DAC_FIFO);
1803
1804 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1805 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
1806
1807 if (IS_CHAN_HT40(chan)) {
1808 phymode |= AR_PHY_FC_DYN2040_EN;
1809
1810 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1811 (chan->chanmode == CHANNEL_G_HT40PLUS))
1812 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1813
1814 }
1815 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1816
1817 ath9k_hw_set11nmac2040(ah);
1818
1819 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1820 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1821}
1822
1823static bool ath9k_hw_chip_reset(struct ath_hw *ah, 1119static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1824 struct ath9k_channel *chan) 1120 struct ath9k_channel *chan)
1825{ 1121{
@@ -1845,7 +1141,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1845 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 1141 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1846 struct ath_common *common = ath9k_hw_common(ah); 1142 struct ath_common *common = ath9k_hw_common(ah);
1847 struct ieee80211_channel *channel = chan->chan; 1143 struct ieee80211_channel *channel = chan->chan;
1848 u32 synthDelay, qnum; 1144 u32 qnum;
1849 int r; 1145 int r;
1850 1146
1851 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 1147 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1857,17 +1153,15 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1857 } 1153 }
1858 } 1154 }
1859 1155
1860 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); 1156 if (!ath9k_hw_rfbus_req(ah)) {
1861 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
1862 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
1863 ath_print(common, ATH_DBG_FATAL, 1157 ath_print(common, ATH_DBG_FATAL,
1864 "Could not kill baseband RX\n"); 1158 "Could not kill baseband RX\n");
1865 return false; 1159 return false;
1866 } 1160 }
1867 1161
1868 ath9k_hw_set_regs(ah, chan); 1162 ath9k_hw_set_channel_regs(ah, chan);
1869 1163
1870 r = ah->ath9k_hw_rf_set_freq(ah, chan); 1164 r = ath9k_hw_rf_set_freq(ah, chan);
1871 if (r) { 1165 if (r) {
1872 ath_print(common, ATH_DBG_FATAL, 1166 ath_print(common, ATH_DBG_FATAL,
1873 "Failed to set channel\n"); 1167 "Failed to set channel\n");
@@ -1881,20 +1175,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1881 min((u32) MAX_RATE_POWER, 1175 min((u32) MAX_RATE_POWER,
1882 (u32) regulatory->power_limit)); 1176 (u32) regulatory->power_limit));
1883 1177
1884 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 1178 ath9k_hw_rfbus_done(ah);
1885 if (IS_CHAN_B(chan))
1886 synthDelay = (4 * synthDelay) / 22;
1887 else
1888 synthDelay /= 10;
1889
1890 udelay(synthDelay + BASE_ACTIVATE_DELAY);
1891
1892 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
1893 1179
1894 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1180 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
1895 ath9k_hw_set_delta_slope(ah, chan); 1181 ath9k_hw_set_delta_slope(ah, chan);
1896 1182
1897 ah->ath9k_hw_spur_mitigate_freq(ah, chan); 1183 ath9k_hw_spur_mitigate_freq(ah, chan);
1898 1184
1899 if (!chan->oneTimeCalsDone) 1185 if (!chan->oneTimeCalsDone)
1900 chan->oneTimeCalsDone = true; 1186 chan->oneTimeCalsDone = true;
@@ -1902,17 +1188,33 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1902 return true; 1188 return true;
1903} 1189}
1904 1190
1905static void ath9k_enable_rfkill(struct ath_hw *ah) 1191bool ath9k_hw_check_alive(struct ath_hw *ah)
1906{ 1192{
1907 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, 1193 int count = 50;
1908 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); 1194 u32 reg;
1195
1196 if (AR_SREV_9285_10_OR_LATER(ah))
1197 return true;
1198
1199 do {
1200 reg = REG_READ(ah, AR_OBS_BUS_1);
1909 1201
1910 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, 1202 if ((reg & 0x7E7FFFEF) == 0x00702400)
1911 AR_GPIO_INPUT_MUX2_RFSILENT); 1203 continue;
1912 1204
1913 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); 1205 switch (reg & 0x7E000B00) {
1914 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); 1206 case 0x1E000000:
1207 case 0x52000B00:
1208 case 0x18000B00:
1209 continue;
1210 default:
1211 return true;
1212 }
1213 } while (count-- > 0);
1214
1215 return false;
1915} 1216}
1217EXPORT_SYMBOL(ath9k_hw_check_alive);
1916 1218
1917int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 1219int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1918 bool bChannelChange) 1220 bool bChannelChange)
@@ -1923,11 +1225,18 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1923 u32 saveDefAntenna; 1225 u32 saveDefAntenna;
1924 u32 macStaId1; 1226 u32 macStaId1;
1925 u64 tsf = 0; 1227 u64 tsf = 0;
1926 int i, rx_chainmask, r; 1228 int i, r;
1927 1229
1928 ah->txchainmask = common->tx_chainmask; 1230 ah->txchainmask = common->tx_chainmask;
1929 ah->rxchainmask = common->rx_chainmask; 1231 ah->rxchainmask = common->rx_chainmask;
1930 1232
1233 if (!ah->chip_fullsleep) {
1234 ath9k_hw_abortpcurecv(ah);
1235 if (!ath9k_hw_stopdmarecv(ah))
1236 ath_print(common, ATH_DBG_XMIT,
1237 "Failed to stop receive dma\n");
1238 }
1239
1931 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 1240 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
1932 return -EIO; 1241 return -EIO;
1933 1242
@@ -1940,8 +1249,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1940 (chan->channel != ah->curchan->channel) && 1249 (chan->channel != ah->curchan->channel) &&
1941 ((chan->channelFlags & CHANNEL_ALL) == 1250 ((chan->channelFlags & CHANNEL_ALL) ==
1942 (ah->curchan->channelFlags & CHANNEL_ALL)) && 1251 (ah->curchan->channelFlags & CHANNEL_ALL)) &&
1943 !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || 1252 !AR_SREV_9280(ah)) {
1944 IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
1945 1253
1946 if (ath9k_hw_channel_change(ah, chan)) { 1254 if (ath9k_hw_channel_change(ah, chan)) {
1947 ath9k_hw_loadnf(ah, ah->curchan); 1255 ath9k_hw_loadnf(ah, ah->curchan);
@@ -1966,6 +1274,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1966 1274
1967 ath9k_hw_mark_phy_inactive(ah); 1275 ath9k_hw_mark_phy_inactive(ah);
1968 1276
1277 /* Only required on the first reset */
1969 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1278 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1970 REG_WRITE(ah, 1279 REG_WRITE(ah,
1971 AR9271_RESET_POWER_DOWN_CONTROL, 1280 AR9271_RESET_POWER_DOWN_CONTROL,
@@ -1978,6 +1287,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1978 return -EINVAL; 1287 return -EINVAL;
1979 } 1288 }
1980 1289
1290 /* Only required on the first reset */
1981 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1291 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1982 ah->htc_reset_init = false; 1292 ah->htc_reset_init = false;
1983 REG_WRITE(ah, 1293 REG_WRITE(ah,
@@ -1993,16 +1303,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1993 if (AR_SREV_9280_10_OR_LATER(ah)) 1303 if (AR_SREV_9280_10_OR_LATER(ah))
1994 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1304 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
1995 1305
1996 if (AR_SREV_9287_12_OR_LATER(ah)) {
1997 /* Enable ASYNC FIFO */
1998 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
1999 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
2000 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
2001 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2002 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
2003 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2004 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
2005 }
2006 r = ath9k_hw_process_ini(ah, chan); 1306 r = ath9k_hw_process_ini(ah, chan);
2007 if (r) 1307 if (r)
2008 return r; 1308 return r;
@@ -2027,9 +1327,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2027 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1327 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
2028 ath9k_hw_set_delta_slope(ah, chan); 1328 ath9k_hw_set_delta_slope(ah, chan);
2029 1329
2030 ah->ath9k_hw_spur_mitigate_freq(ah, chan); 1330 ath9k_hw_spur_mitigate_freq(ah, chan);
2031 ah->eep_ops->set_board_values(ah, chan); 1331 ah->eep_ops->set_board_values(ah, chan);
2032 1332
1333 ath9k_hw_set_operating_mode(ah, ah->opmode);
1334
1335 ENABLE_REGWRITE_BUFFER(ah);
1336
2033 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); 1337 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
2034 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) 1338 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
2035 | macStaId1 1339 | macStaId1
@@ -2037,25 +1341,27 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2037 | (ah->config. 1341 | (ah->config.
2038 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) 1342 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
2039 | ah->sta_id1_defaults); 1343 | ah->sta_id1_defaults);
2040 ath9k_hw_set_operating_mode(ah, ah->opmode);
2041
2042 ath_hw_setbssidmask(common); 1344 ath_hw_setbssidmask(common);
2043
2044 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 1345 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
2045
2046 ath9k_hw_write_associd(ah); 1346 ath9k_hw_write_associd(ah);
2047
2048 REG_WRITE(ah, AR_ISR, ~0); 1347 REG_WRITE(ah, AR_ISR, ~0);
2049
2050 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 1348 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
2051 1349
2052 r = ah->ath9k_hw_rf_set_freq(ah, chan); 1350 REGWRITE_BUFFER_FLUSH(ah);
1351 DISABLE_REGWRITE_BUFFER(ah);
1352
1353 r = ath9k_hw_rf_set_freq(ah, chan);
2053 if (r) 1354 if (r)
2054 return r; 1355 return r;
2055 1356
1357 ENABLE_REGWRITE_BUFFER(ah);
1358
2056 for (i = 0; i < AR_NUM_DCU; i++) 1359 for (i = 0; i < AR_NUM_DCU; i++)
2057 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 1360 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
2058 1361
1362 REGWRITE_BUFFER_FLUSH(ah);
1363 DISABLE_REGWRITE_BUFFER(ah);
1364
2059 ah->intr_txqs = 0; 1365 ah->intr_txqs = 0;
2060 for (i = 0; i < ah->caps.total_queues; i++) 1366 for (i = 0; i < ah->caps.total_queues; i++)
2061 ath9k_hw_resettxqueue(ah, i); 1367 ath9k_hw_resettxqueue(ah, i);
@@ -2068,25 +1374,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2068 1374
2069 ath9k_hw_init_global_settings(ah); 1375 ath9k_hw_init_global_settings(ah);
2070 1376
2071 if (AR_SREV_9287_12_OR_LATER(ah)) { 1377 if (!AR_SREV_9300_20_OR_LATER(ah)) {
2072 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 1378 ar9002_hw_enable_async_fifo(ah);
2073 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); 1379 ar9002_hw_enable_wep_aggregation(ah);
2074 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
2075 AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
2076 REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
2077 AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
2078
2079 REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
2080 REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
2081
2082 REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
2083 AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
2084 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
2085 AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
2086 }
2087 if (AR_SREV_9287_12_OR_LATER(ah)) {
2088 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
2089 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
2090 } 1380 }
2091 1381
2092 REG_WRITE(ah, AR_STA_ID1, 1382 REG_WRITE(ah, AR_STA_ID1,
@@ -2101,19 +1391,24 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2101 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 1391 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
2102 } 1392 }
2103 1393
1394 if (ah->config.tx_intr_mitigation) {
1395 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
1396 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
1397 }
1398
2104 ath9k_hw_init_bb(ah, chan); 1399 ath9k_hw_init_bb(ah, chan);
2105 1400
2106 if (!ath9k_hw_init_cal(ah, chan)) 1401 if (!ath9k_hw_init_cal(ah, chan))
2107 return -EIO; 1402 return -EIO;
2108 1403
2109 rx_chainmask = ah->rxchainmask; 1404 ENABLE_REGWRITE_BUFFER(ah);
2110 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
2111 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2112 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2113 }
2114 1405
1406 ath9k_hw_restore_chainmask(ah);
2115 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); 1407 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
2116 1408
1409 REGWRITE_BUFFER_FLUSH(ah);
1410 DISABLE_REGWRITE_BUFFER(ah);
1411
2117 /* 1412 /*
2118 * For big endian systems turn on swapping for descriptors 1413 * For big endian systems turn on swapping for descriptors
2119 */ 1414 */
@@ -2143,6 +1438,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2143 if (ah->btcoex_hw.enabled) 1438 if (ah->btcoex_hw.enabled)
2144 ath9k_hw_btcoex_enable(ah); 1439 ath9k_hw_btcoex_enable(ah);
2145 1440
1441 if (AR_SREV_9300_20_OR_LATER(ah)) {
1442 ath9k_hw_loadnf(ah, curchan);
1443 ath9k_hw_start_nfcal(ah);
1444 }
1445
2146 return 0; 1446 return 0;
2147} 1447}
2148EXPORT_SYMBOL(ath9k_hw_reset); 1448EXPORT_SYMBOL(ath9k_hw_reset);
@@ -2429,21 +1729,35 @@ EXPORT_SYMBOL(ath9k_hw_keyisvalid);
2429/* Power Management (Chipset) */ 1729/* Power Management (Chipset) */
2430/******************************/ 1730/******************************/
2431 1731
1732/*
1733 * Notify Power Mgt is disabled in self-generated frames.
1734 * If requested, force chip to sleep.
1735 */
2432static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) 1736static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2433{ 1737{
2434 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 1738 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
2435 if (setChip) { 1739 if (setChip) {
1740 /*
1741 * Clear the RTC force wake bit to allow the
1742 * mac to go to sleep.
1743 */
2436 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, 1744 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
2437 AR_RTC_FORCE_WAKE_EN); 1745 AR_RTC_FORCE_WAKE_EN);
2438 if (!AR_SREV_9100(ah)) 1746 if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
2439 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 1747 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
2440 1748
2441 if(!AR_SREV_5416(ah)) 1749 /* Shutdown chip. Active low */
1750 if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
2442 REG_CLR_BIT(ah, (AR_RTC_RESET), 1751 REG_CLR_BIT(ah, (AR_RTC_RESET),
2443 AR_RTC_RESET_EN); 1752 AR_RTC_RESET_EN);
2444 } 1753 }
2445} 1754}
2446 1755
1756/*
1757 * Notify Power Management is enabled in self-generating
1758 * frames. If request, set power mode of chip to
1759 * auto/normal. Duration in units of 128us (1/8 TU).
1760 */
2447static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) 1761static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
2448{ 1762{
2449 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 1763 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
@@ -2451,9 +1765,14 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
2451 struct ath9k_hw_capabilities *pCap = &ah->caps; 1765 struct ath9k_hw_capabilities *pCap = &ah->caps;
2452 1766
2453 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 1767 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1768 /* Set WakeOnInterrupt bit; clear ForceWake bit */
2454 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1769 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
2455 AR_RTC_FORCE_WAKE_ON_INT); 1770 AR_RTC_FORCE_WAKE_ON_INT);
2456 } else { 1771 } else {
1772 /*
1773 * Clear the RTC force wake bit to allow the
1774 * mac to go to sleep.
1775 */
2457 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, 1776 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
2458 AR_RTC_FORCE_WAKE_EN); 1777 AR_RTC_FORCE_WAKE_EN);
2459 } 1778 }
@@ -2472,7 +1791,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
2472 ATH9K_RESET_POWER_ON) != true) { 1791 ATH9K_RESET_POWER_ON) != true) {
2473 return false; 1792 return false;
2474 } 1793 }
2475 ath9k_hw_init_pll(ah, NULL); 1794 if (!AR_SREV_9300_20_OR_LATER(ah))
1795 ath9k_hw_init_pll(ah, NULL);
2476 } 1796 }
2477 if (AR_SREV_9100(ah)) 1797 if (AR_SREV_9100(ah))
2478 REG_SET_BIT(ah, AR_RTC_RESET, 1798 REG_SET_BIT(ah, AR_RTC_RESET,
@@ -2542,424 +1862,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2542} 1862}
2543EXPORT_SYMBOL(ath9k_hw_setpower); 1863EXPORT_SYMBOL(ath9k_hw_setpower);
2544 1864
2545/*
2546 * Helper for ASPM support.
2547 *
2548 * Disable PLL when in L0s as well as receiver clock when in L1.
2549 * This power saving option must be enabled through the SerDes.
2550 *
2551 * Programming the SerDes must go through the same 288 bit serial shift
2552 * register as the other analog registers. Hence the 9 writes.
2553 */
2554void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
2555{
2556 u8 i;
2557 u32 val;
2558
2559 if (ah->is_pciexpress != true)
2560 return;
2561
2562 /* Do not touch SerDes registers */
2563 if (ah->config.pcie_powersave_enable == 2)
2564 return;
2565
2566 /* Nothing to do on restore for 11N */
2567 if (!restore) {
2568 if (AR_SREV_9280_20_OR_LATER(ah)) {
2569 /*
2570 * AR9280 2.0 or later chips use SerDes values from the
2571 * initvals.h initialized depending on chipset during
2572 * ath9k_hw_init()
2573 */
2574 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
2575 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
2576 INI_RA(&ah->iniPcieSerdes, i, 1));
2577 }
2578 } else if (AR_SREV_9280(ah) &&
2579 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
2580 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
2581 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2582
2583 /* RX shut off when elecidle is asserted */
2584 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
2585 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
2586 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
2587
2588 /* Shut off CLKREQ active in L1 */
2589 if (ah->config.pcie_clock_req)
2590 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
2591 else
2592 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
2593
2594 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
2595 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2596 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
2597
2598 /* Load the new settings */
2599 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2600
2601 } else {
2602 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
2603 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2604
2605 /* RX shut off when elecidle is asserted */
2606 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
2607 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
2608 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
2609
2610 /*
2611 * Ignore ah->ah_config.pcie_clock_req setting for
2612 * pre-AR9280 11n
2613 */
2614 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
2615
2616 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
2617 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2618 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
2619
2620 /* Load the new settings */
2621 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2622 }
2623
2624 udelay(1000);
2625
2626 /* set bit 19 to allow forcing of pcie core into L1 state */
2627 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
2628
2629 /* Several PCIe massages to ensure proper behaviour */
2630 if (ah->config.pcie_waen) {
2631 val = ah->config.pcie_waen;
2632 if (!power_off)
2633 val &= (~AR_WA_D3_L1_DISABLE);
2634 } else {
2635 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
2636 AR_SREV_9287(ah)) {
2637 val = AR9285_WA_DEFAULT;
2638 if (!power_off)
2639 val &= (~AR_WA_D3_L1_DISABLE);
2640 } else if (AR_SREV_9280(ah)) {
2641 /*
2642 * On AR9280 chips bit 22 of 0x4004 needs to be
2643 * set otherwise card may disappear.
2644 */
2645 val = AR9280_WA_DEFAULT;
2646 if (!power_off)
2647 val &= (~AR_WA_D3_L1_DISABLE);
2648 } else
2649 val = AR_WA_DEFAULT;
2650 }
2651
2652 REG_WRITE(ah, AR_WA, val);
2653 }
2654
2655 if (power_off) {
2656 /*
2657 * Set PCIe workaround bits
2658 * bit 14 in WA register (disable L1) should only
2659 * be set when device enters D3 and be cleared
2660 * when device comes back to D0.
2661 */
2662 if (ah->config.pcie_waen) {
2663 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
2664 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
2665 } else {
2666 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
2667 AR_SREV_9287(ah)) &&
2668 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
2669 (AR_SREV_9280(ah) &&
2670 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
2671 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
2672 }
2673 }
2674 }
2675}
2676EXPORT_SYMBOL(ath9k_hw_configpcipowersave);
2677
2678/**********************/
2679/* Interrupt Handling */
2680/**********************/
2681
2682bool ath9k_hw_intrpend(struct ath_hw *ah)
2683{
2684 u32 host_isr;
2685
2686 if (AR_SREV_9100(ah))
2687 return true;
2688
2689 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
2690 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
2691 return true;
2692
2693 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
2694 if ((host_isr & AR_INTR_SYNC_DEFAULT)
2695 && (host_isr != AR_INTR_SPURIOUS))
2696 return true;
2697
2698 return false;
2699}
2700EXPORT_SYMBOL(ath9k_hw_intrpend);
2701
2702bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
2703{
2704 u32 isr = 0;
2705 u32 mask2 = 0;
2706 struct ath9k_hw_capabilities *pCap = &ah->caps;
2707 u32 sync_cause = 0;
2708 bool fatal_int = false;
2709 struct ath_common *common = ath9k_hw_common(ah);
2710
2711 if (!AR_SREV_9100(ah)) {
2712 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
2713 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
2714 == AR_RTC_STATUS_ON) {
2715 isr = REG_READ(ah, AR_ISR);
2716 }
2717 }
2718
2719 sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
2720 AR_INTR_SYNC_DEFAULT;
2721
2722 *masked = 0;
2723
2724 if (!isr && !sync_cause)
2725 return false;
2726 } else {
2727 *masked = 0;
2728 isr = REG_READ(ah, AR_ISR);
2729 }
2730
2731 if (isr) {
2732 if (isr & AR_ISR_BCNMISC) {
2733 u32 isr2;
2734 isr2 = REG_READ(ah, AR_ISR_S2);
2735 if (isr2 & AR_ISR_S2_TIM)
2736 mask2 |= ATH9K_INT_TIM;
2737 if (isr2 & AR_ISR_S2_DTIM)
2738 mask2 |= ATH9K_INT_DTIM;
2739 if (isr2 & AR_ISR_S2_DTIMSYNC)
2740 mask2 |= ATH9K_INT_DTIMSYNC;
2741 if (isr2 & (AR_ISR_S2_CABEND))
2742 mask2 |= ATH9K_INT_CABEND;
2743 if (isr2 & AR_ISR_S2_GTT)
2744 mask2 |= ATH9K_INT_GTT;
2745 if (isr2 & AR_ISR_S2_CST)
2746 mask2 |= ATH9K_INT_CST;
2747 if (isr2 & AR_ISR_S2_TSFOOR)
2748 mask2 |= ATH9K_INT_TSFOOR;
2749 }
2750
2751 isr = REG_READ(ah, AR_ISR_RAC);
2752 if (isr == 0xffffffff) {
2753 *masked = 0;
2754 return false;
2755 }
2756
2757 *masked = isr & ATH9K_INT_COMMON;
2758
2759 if (ah->config.rx_intr_mitigation) {
2760 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2761 *masked |= ATH9K_INT_RX;
2762 }
2763
2764 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
2765 *masked |= ATH9K_INT_RX;
2766 if (isr &
2767 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
2768 AR_ISR_TXEOL)) {
2769 u32 s0_s, s1_s;
2770
2771 *masked |= ATH9K_INT_TX;
2772
2773 s0_s = REG_READ(ah, AR_ISR_S0_S);
2774 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
2775 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
2776
2777 s1_s = REG_READ(ah, AR_ISR_S1_S);
2778 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
2779 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
2780 }
2781
2782 if (isr & AR_ISR_RXORN) {
2783 ath_print(common, ATH_DBG_INTERRUPT,
2784 "receive FIFO overrun interrupt\n");
2785 }
2786
2787 if (!AR_SREV_9100(ah)) {
2788 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2789 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
2790 if (isr5 & AR_ISR_S5_TIM_TIMER)
2791 *masked |= ATH9K_INT_TIM_TIMER;
2792 }
2793 }
2794
2795 *masked |= mask2;
2796 }
2797
2798 if (AR_SREV_9100(ah))
2799 return true;
2800
2801 if (isr & AR_ISR_GENTMR) {
2802 u32 s5_s;
2803
2804 s5_s = REG_READ(ah, AR_ISR_S5_S);
2805 if (isr & AR_ISR_GENTMR) {
2806 ah->intr_gen_timer_trigger =
2807 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
2808
2809 ah->intr_gen_timer_thresh =
2810 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
2811
2812 if (ah->intr_gen_timer_trigger)
2813 *masked |= ATH9K_INT_GENTIMER;
2814
2815 }
2816 }
2817
2818 if (sync_cause) {
2819 fatal_int =
2820 (sync_cause &
2821 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
2822 ? true : false;
2823
2824 if (fatal_int) {
2825 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
2826 ath_print(common, ATH_DBG_ANY,
2827 "received PCI FATAL interrupt\n");
2828 }
2829 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
2830 ath_print(common, ATH_DBG_ANY,
2831 "received PCI PERR interrupt\n");
2832 }
2833 *masked |= ATH9K_INT_FATAL;
2834 }
2835 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
2836 ath_print(common, ATH_DBG_INTERRUPT,
2837 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
2838 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
2839 REG_WRITE(ah, AR_RC, 0);
2840 *masked |= ATH9K_INT_FATAL;
2841 }
2842 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
2843 ath_print(common, ATH_DBG_INTERRUPT,
2844 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
2845 }
2846
2847 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
2848 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
2849 }
2850
2851 return true;
2852}
2853EXPORT_SYMBOL(ath9k_hw_getisr);
2854
2855enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
2856{
2857 u32 omask = ah->mask_reg;
2858 u32 mask, mask2;
2859 struct ath9k_hw_capabilities *pCap = &ah->caps;
2860 struct ath_common *common = ath9k_hw_common(ah);
2861
2862 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
2863
2864 if (omask & ATH9K_INT_GLOBAL) {
2865 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
2866 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
2867 (void) REG_READ(ah, AR_IER);
2868 if (!AR_SREV_9100(ah)) {
2869 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
2870 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
2871
2872 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
2873 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
2874 }
2875 }
2876
2877 mask = ints & ATH9K_INT_COMMON;
2878 mask2 = 0;
2879
2880 if (ints & ATH9K_INT_TX) {
2881 if (ah->txok_interrupt_mask)
2882 mask |= AR_IMR_TXOK;
2883 if (ah->txdesc_interrupt_mask)
2884 mask |= AR_IMR_TXDESC;
2885 if (ah->txerr_interrupt_mask)
2886 mask |= AR_IMR_TXERR;
2887 if (ah->txeol_interrupt_mask)
2888 mask |= AR_IMR_TXEOL;
2889 }
2890 if (ints & ATH9K_INT_RX) {
2891 mask |= AR_IMR_RXERR;
2892 if (ah->config.rx_intr_mitigation)
2893 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
2894 else
2895 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
2896 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
2897 mask |= AR_IMR_GENTMR;
2898 }
2899
2900 if (ints & (ATH9K_INT_BMISC)) {
2901 mask |= AR_IMR_BCNMISC;
2902 if (ints & ATH9K_INT_TIM)
2903 mask2 |= AR_IMR_S2_TIM;
2904 if (ints & ATH9K_INT_DTIM)
2905 mask2 |= AR_IMR_S2_DTIM;
2906 if (ints & ATH9K_INT_DTIMSYNC)
2907 mask2 |= AR_IMR_S2_DTIMSYNC;
2908 if (ints & ATH9K_INT_CABEND)
2909 mask2 |= AR_IMR_S2_CABEND;
2910 if (ints & ATH9K_INT_TSFOOR)
2911 mask2 |= AR_IMR_S2_TSFOOR;
2912 }
2913
2914 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
2915 mask |= AR_IMR_BCNMISC;
2916 if (ints & ATH9K_INT_GTT)
2917 mask2 |= AR_IMR_S2_GTT;
2918 if (ints & ATH9K_INT_CST)
2919 mask2 |= AR_IMR_S2_CST;
2920 }
2921
2922 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
2923 REG_WRITE(ah, AR_IMR, mask);
2924 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
2925 AR_IMR_S2_DTIM |
2926 AR_IMR_S2_DTIMSYNC |
2927 AR_IMR_S2_CABEND |
2928 AR_IMR_S2_CABTO |
2929 AR_IMR_S2_TSFOOR |
2930 AR_IMR_S2_GTT | AR_IMR_S2_CST);
2931 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
2932 ah->mask_reg = ints;
2933
2934 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2935 if (ints & ATH9K_INT_TIM_TIMER)
2936 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
2937 else
2938 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
2939 }
2940
2941 if (ints & ATH9K_INT_GLOBAL) {
2942 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
2943 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
2944 if (!AR_SREV_9100(ah)) {
2945 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
2946 AR_INTR_MAC_IRQ);
2947 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
2948
2949
2950 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
2951 AR_INTR_SYNC_DEFAULT);
2952 REG_WRITE(ah, AR_INTR_SYNC_MASK,
2953 AR_INTR_SYNC_DEFAULT);
2954 }
2955 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
2956 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
2957 }
2958
2959 return omask;
2960}
2961EXPORT_SYMBOL(ath9k_hw_set_interrupts);
2962
2963/*******************/ 1865/*******************/
2964/* Beacon Handling */ 1866/* Beacon Handling */
2965/*******************/ 1867/*******************/
@@ -2970,6 +1872,8 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2970 1872
2971 ah->beacon_interval = beacon_period; 1873 ah->beacon_interval = beacon_period;
2972 1874
1875 ENABLE_REGWRITE_BUFFER(ah);
1876
2973 switch (ah->opmode) { 1877 switch (ah->opmode) {
2974 case NL80211_IFTYPE_STATION: 1878 case NL80211_IFTYPE_STATION:
2975 case NL80211_IFTYPE_MONITOR: 1879 case NL80211_IFTYPE_MONITOR:
@@ -3013,6 +1917,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
3013 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); 1917 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
3014 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); 1918 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
3015 1919
1920 REGWRITE_BUFFER_FLUSH(ah);
1921 DISABLE_REGWRITE_BUFFER(ah);
1922
3016 beacon_period &= ~ATH9K_BEACON_ENA; 1923 beacon_period &= ~ATH9K_BEACON_ENA;
3017 if (beacon_period & ATH9K_BEACON_RESET_TSF) { 1924 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
3018 ath9k_hw_reset_tsf(ah); 1925 ath9k_hw_reset_tsf(ah);
@@ -3029,6 +1936,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3029 struct ath9k_hw_capabilities *pCap = &ah->caps; 1936 struct ath9k_hw_capabilities *pCap = &ah->caps;
3030 struct ath_common *common = ath9k_hw_common(ah); 1937 struct ath_common *common = ath9k_hw_common(ah);
3031 1938
1939 ENABLE_REGWRITE_BUFFER(ah);
1940
3032 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); 1941 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
3033 1942
3034 REG_WRITE(ah, AR_BEACON_PERIOD, 1943 REG_WRITE(ah, AR_BEACON_PERIOD,
@@ -3036,6 +1945,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3036 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, 1945 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
3037 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); 1946 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
3038 1947
1948 REGWRITE_BUFFER_FLUSH(ah);
1949 DISABLE_REGWRITE_BUFFER(ah);
1950
3039 REG_RMW_FIELD(ah, AR_RSSI_THR, 1951 REG_RMW_FIELD(ah, AR_RSSI_THR,
3040 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); 1952 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
3041 1953
@@ -3058,6 +1970,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3058 ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); 1970 ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
3059 ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); 1971 ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
3060 1972
1973 ENABLE_REGWRITE_BUFFER(ah);
1974
3061 REG_WRITE(ah, AR_NEXT_DTIM, 1975 REG_WRITE(ah, AR_NEXT_DTIM,
3062 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); 1976 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
3063 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); 1977 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
@@ -3077,6 +1991,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3077 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); 1991 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
3078 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); 1992 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
3079 1993
1994 REGWRITE_BUFFER_FLUSH(ah);
1995 DISABLE_REGWRITE_BUFFER(ah);
1996
3080 REG_SET_BIT(ah, AR_TIMER_MODE, 1997 REG_SET_BIT(ah, AR_TIMER_MODE,
3081 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | 1998 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
3082 AR_DTIM_TIMER_EN); 1999 AR_DTIM_TIMER_EN);
@@ -3219,7 +2136,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3219 else 2136 else
3220 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; 2137 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3221 2138
3222 if (AR_SREV_9285_10_OR_LATER(ah)) 2139 if (AR_SREV_9271(ah))
2140 pCap->num_gpio_pins = AR9271_NUM_GPIO;
2141 else if (AR_SREV_9285_10_OR_LATER(ah))
3223 pCap->num_gpio_pins = AR9285_NUM_GPIO; 2142 pCap->num_gpio_pins = AR9285_NUM_GPIO;
3224 else if (AR_SREV_9280_10_OR_LATER(ah)) 2143 else if (AR_SREV_9280_10_OR_LATER(ah))
3225 pCap->num_gpio_pins = AR928X_NUM_GPIO; 2144 pCap->num_gpio_pins = AR928X_NUM_GPIO;
@@ -3246,8 +2165,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3246 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; 2165 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3247 } 2166 }
3248#endif 2167#endif
3249 2168 if (AR_SREV_9271(ah))
3250 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; 2169 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
2170 else
2171 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3251 2172
3252 if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) 2173 if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
3253 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; 2174 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
@@ -3291,6 +2212,26 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3291 btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; 2212 btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
3292 } 2213 }
3293 2214
2215 if (AR_SREV_9300_20_OR_LATER(ah)) {
2216 pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC |
2217 ATH9K_HW_CAP_FASTCLOCK;
2218 pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
2219 pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
2220 pCap->rx_status_len = sizeof(struct ar9003_rxs);
2221 pCap->tx_desc_len = sizeof(struct ar9003_txc);
2222 pCap->txs_len = sizeof(struct ar9003_txs);
2223 } else {
2224 pCap->tx_desc_len = sizeof(struct ath_desc);
2225 if (AR_SREV_9280_20(ah) &&
2226 ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <=
2227 AR5416_EEP_MINOR_VER_16) ||
2228 ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G)))
2229 pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK;
2230 }
2231
2232 if (AR_SREV_9300_20_OR_LATER(ah))
2233 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
2234
3294 return 0; 2235 return 0;
3295} 2236}
3296 2237
@@ -3323,10 +2264,6 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3323 case ATH9K_CAP_TKIP_SPLIT: 2264 case ATH9K_CAP_TKIP_SPLIT:
3324 return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ? 2265 return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
3325 false : true; 2266 false : true;
3326 case ATH9K_CAP_DIVERSITY:
3327 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
3328 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
3329 true : false;
3330 case ATH9K_CAP_MCAST_KEYSRCH: 2267 case ATH9K_CAP_MCAST_KEYSRCH:
3331 switch (capability) { 2268 switch (capability) {
3332 case 0: 2269 case 0:
@@ -3369,8 +2306,6 @@ EXPORT_SYMBOL(ath9k_hw_getcapability);
3369bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, 2306bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3370 u32 capability, u32 setting, int *status) 2307 u32 capability, u32 setting, int *status)
3371{ 2308{
3372 u32 v;
3373
3374 switch (type) { 2309 switch (type) {
3375 case ATH9K_CAP_TKIP_MIC: 2310 case ATH9K_CAP_TKIP_MIC:
3376 if (setting) 2311 if (setting)
@@ -3380,14 +2315,6 @@ bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3380 ah->sta_id1_defaults &= 2315 ah->sta_id1_defaults &=
3381 ~AR_STA_ID1_CRPT_MIC_ENABLE; 2316 ~AR_STA_ID1_CRPT_MIC_ENABLE;
3382 return true; 2317 return true;
3383 case ATH9K_CAP_DIVERSITY:
3384 v = REG_READ(ah, AR_PHY_CCK_DETECT);
3385 if (setting)
3386 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
3387 else
3388 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
3389 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
3390 return true;
3391 case ATH9K_CAP_MCAST_KEYSRCH: 2318 case ATH9K_CAP_MCAST_KEYSRCH:
3392 if (setting) 2319 if (setting)
3393 ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH; 2320 ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
@@ -3455,7 +2382,11 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3455 if (gpio >= ah->caps.num_gpio_pins) 2382 if (gpio >= ah->caps.num_gpio_pins)
3456 return 0xffffffff; 2383 return 0xffffffff;
3457 2384
3458 if (AR_SREV_9287_10_OR_LATER(ah)) 2385 if (AR_SREV_9300_20_OR_LATER(ah))
2386 return MS_REG_READ(AR9300, gpio) != 0;
2387 else if (AR_SREV_9271(ah))
2388 return MS_REG_READ(AR9271, gpio) != 0;
2389 else if (AR_SREV_9287_10_OR_LATER(ah))
3459 return MS_REG_READ(AR9287, gpio) != 0; 2390 return MS_REG_READ(AR9287, gpio) != 0;
3460 else if (AR_SREV_9285_10_OR_LATER(ah)) 2391 else if (AR_SREV_9285_10_OR_LATER(ah))
3461 return MS_REG_READ(AR9285, gpio) != 0; 2392 return MS_REG_READ(AR9285, gpio) != 0;
@@ -3484,6 +2415,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output);
3484 2415
3485void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 2416void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3486{ 2417{
2418 if (AR_SREV_9271(ah))
2419 val = ~val;
2420
3487 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 2421 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
3488 AR_GPIO_BIT(gpio)); 2422 AR_GPIO_BIT(gpio));
3489} 2423}
@@ -3523,6 +2457,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
3523{ 2457{
3524 u32 phybits; 2458 u32 phybits;
3525 2459
2460 ENABLE_REGWRITE_BUFFER(ah);
2461
3526 REG_WRITE(ah, AR_RX_FILTER, bits); 2462 REG_WRITE(ah, AR_RX_FILTER, bits);
3527 2463
3528 phybits = 0; 2464 phybits = 0;
@@ -3538,6 +2474,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
3538 else 2474 else
3539 REG_WRITE(ah, AR_RXCFG, 2475 REG_WRITE(ah, AR_RXCFG,
3540 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); 2476 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
2477
2478 REGWRITE_BUFFER_FLUSH(ah);
2479 DISABLE_REGWRITE_BUFFER(ah);
3541} 2480}
3542EXPORT_SYMBOL(ath9k_hw_setrxfilter); 2481EXPORT_SYMBOL(ath9k_hw_setrxfilter);
3543 2482
@@ -3610,14 +2549,25 @@ void ath9k_hw_write_associd(struct ath_hw *ah)
3610} 2549}
3611EXPORT_SYMBOL(ath9k_hw_write_associd); 2550EXPORT_SYMBOL(ath9k_hw_write_associd);
3612 2551
2552#define ATH9K_MAX_TSF_READ 10
2553
3613u64 ath9k_hw_gettsf64(struct ath_hw *ah) 2554u64 ath9k_hw_gettsf64(struct ath_hw *ah)
3614{ 2555{
3615 u64 tsf; 2556 u32 tsf_lower, tsf_upper1, tsf_upper2;
2557 int i;
2558
2559 tsf_upper1 = REG_READ(ah, AR_TSF_U32);
2560 for (i = 0; i < ATH9K_MAX_TSF_READ; i++) {
2561 tsf_lower = REG_READ(ah, AR_TSF_L32);
2562 tsf_upper2 = REG_READ(ah, AR_TSF_U32);
2563 if (tsf_upper2 == tsf_upper1)
2564 break;
2565 tsf_upper1 = tsf_upper2;
2566 }
3616 2567
3617 tsf = REG_READ(ah, AR_TSF_U32); 2568 WARN_ON( i == ATH9K_MAX_TSF_READ );
3618 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
3619 2569
3620 return tsf; 2570 return (((u64)tsf_upper1 << 32) | tsf_lower);
3621} 2571}
3622EXPORT_SYMBOL(ath9k_hw_gettsf64); 2572EXPORT_SYMBOL(ath9k_hw_gettsf64);
3623 2573
@@ -3868,6 +2818,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
3868} 2818}
3869EXPORT_SYMBOL(ath_gen_timer_isr); 2819EXPORT_SYMBOL(ath_gen_timer_isr);
3870 2820
2821/********/
2822/* HTC */
2823/********/
2824
2825void ath9k_hw_htc_resetinit(struct ath_hw *ah)
2826{
2827 ah->htc_reset_init = true;
2828}
2829EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
2830
3871static struct { 2831static struct {
3872 u32 version; 2832 u32 version;
3873 const char * name; 2833 const char * name;
@@ -3882,6 +2842,7 @@ static struct {
3882 { AR_SREV_VERSION_9285, "9285" }, 2842 { AR_SREV_VERSION_9285, "9285" },
3883 { AR_SREV_VERSION_9287, "9287" }, 2843 { AR_SREV_VERSION_9287, "9287" },
3884 { AR_SREV_VERSION_9271, "9271" }, 2844 { AR_SREV_VERSION_9271, "9271" },
2845 { AR_SREV_VERSION_9300, "9300" },
3885}; 2846};
3886 2847
3887/* For devices with external radios */ 2848/* For devices with external radios */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dbbf7ca5f97d..77245dff5993 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2010 Atheros Communications 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
@@ -41,18 +41,16 @@
41#define AR9280_DEVID_PCIE 0x002a 41#define AR9280_DEVID_PCIE 0x002a
42#define AR9285_DEVID_PCIE 0x002b 42#define AR9285_DEVID_PCIE 0x002b
43#define AR2427_DEVID_PCIE 0x002c 43#define AR2427_DEVID_PCIE 0x002c
44#define AR9287_DEVID_PCI 0x002d
45#define AR9287_DEVID_PCIE 0x002e
46#define AR9300_DEVID_PCIE 0x0030
44 47
45#define AR5416_AR9100_DEVID 0x000b 48#define AR5416_AR9100_DEVID 0x000b
46 49
47#define AR9271_USB 0x9271
48
49#define AR_SUBVENDOR_ID_NOG 0x0e11 50#define AR_SUBVENDOR_ID_NOG 0x0e11
50#define AR_SUBVENDOR_ID_NEW_A 0x7065 51#define AR_SUBVENDOR_ID_NEW_A 0x7065
51#define AR5416_MAGIC 0x19641014 52#define AR5416_MAGIC 0x19641014
52 53
53#define AR5416_DEVID_AR9287_PCI 0x002D
54#define AR5416_DEVID_AR9287_PCIE 0x002E
55
56#define AR9280_COEX2WIRE_SUBSYSID 0x309b 54#define AR9280_COEX2WIRE_SUBSYSID 0x309b
57#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa 55#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
58#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab 56#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
@@ -70,6 +68,24 @@
70#define REG_READ(_ah, _reg) \ 68#define REG_READ(_ah, _reg) \
71 ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) 69 ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
72 70
71#define ENABLE_REGWRITE_BUFFER(_ah) \
72 do { \
73 if (AR_SREV_9271(_ah)) \
74 ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
75 } while (0)
76
77#define DISABLE_REGWRITE_BUFFER(_ah) \
78 do { \
79 if (AR_SREV_9271(_ah)) \
80 ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
81 } while (0)
82
83#define REGWRITE_BUFFER_FLUSH(_ah) \
84 do { \
85 if (AR_SREV_9271(_ah)) \
86 ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
87 } while (0)
88
73#define SM(_v, _f) (((_v) << _f##_S) & _f) 89#define SM(_v, _f) (((_v) << _f##_S) & _f)
74#define MS(_v, _f) (((_v) & _f) >> _f##_S) 90#define MS(_v, _f) (((_v) & _f) >> _f##_S)
75#define REG_RMW(_a, _r, _set, _clr) \ 91#define REG_RMW(_a, _r, _set, _clr) \
@@ -77,6 +93,8 @@
77#define REG_RMW_FIELD(_a, _r, _f, _v) \ 93#define REG_RMW_FIELD(_a, _r, _f, _v) \
78 REG_WRITE(_a, _r, \ 94 REG_WRITE(_a, _r, \
79 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) 95 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
96#define REG_READ_FIELD(_a, _r, _f) \
97 (((REG_READ(_a, _r) & _f) >> _f##_S))
80#define REG_SET_BIT(_a, _r, _f) \ 98#define REG_SET_BIT(_a, _r, _f) \
81 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f) 99 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
82#define REG_CLR_BIT(_a, _r, _f) \ 100#define REG_CLR_BIT(_a, _r, _f) \
@@ -137,6 +155,16 @@
137 155
138#define TU_TO_USEC(_tu) ((_tu) << 10) 156#define TU_TO_USEC(_tu) ((_tu) << 10)
139 157
158#define ATH9K_HW_RX_HP_QDEPTH 16
159#define ATH9K_HW_RX_LP_QDEPTH 128
160
161enum ath_ini_subsys {
162 ATH_INI_PRE = 0,
163 ATH_INI_CORE,
164 ATH_INI_POST,
165 ATH_INI_NUM_SPLIT,
166};
167
140enum wireless_mode { 168enum wireless_mode {
141 ATH9K_MODE_11A = 0, 169 ATH9K_MODE_11A = 0,
142 ATH9K_MODE_11G, 170 ATH9K_MODE_11G,
@@ -167,13 +195,16 @@ enum ath9k_hw_caps {
167 ATH9K_HW_CAP_ENHANCEDPM = BIT(14), 195 ATH9K_HW_CAP_ENHANCEDPM = BIT(14),
168 ATH9K_HW_CAP_AUTOSLEEP = BIT(15), 196 ATH9K_HW_CAP_AUTOSLEEP = BIT(15),
169 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), 197 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
198 ATH9K_HW_CAP_EDMA = BIT(17),
199 ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
200 ATH9K_HW_CAP_LDPC = BIT(19),
201 ATH9K_HW_CAP_FASTCLOCK = BIT(20),
170}; 202};
171 203
172enum ath9k_capability_type { 204enum ath9k_capability_type {
173 ATH9K_CAP_CIPHER = 0, 205 ATH9K_CAP_CIPHER = 0,
174 ATH9K_CAP_TKIP_MIC, 206 ATH9K_CAP_TKIP_MIC,
175 ATH9K_CAP_TKIP_SPLIT, 207 ATH9K_CAP_TKIP_SPLIT,
176 ATH9K_CAP_DIVERSITY,
177 ATH9K_CAP_TXPOW, 208 ATH9K_CAP_TXPOW,
178 ATH9K_CAP_MCAST_KEYSRCH, 209 ATH9K_CAP_MCAST_KEYSRCH,
179 ATH9K_CAP_DS 210 ATH9K_CAP_DS
@@ -194,6 +225,11 @@ struct ath9k_hw_capabilities {
194 u8 num_gpio_pins; 225 u8 num_gpio_pins;
195 u8 num_antcfg_2ghz; 226 u8 num_antcfg_2ghz;
196 u8 num_antcfg_5ghz; 227 u8 num_antcfg_5ghz;
228 u8 rx_hp_qdepth;
229 u8 rx_lp_qdepth;
230 u8 rx_status_len;
231 u8 tx_desc_len;
232 u8 txs_len;
197}; 233};
198 234
199struct ath9k_ops_config { 235struct ath9k_ops_config {
@@ -214,6 +250,7 @@ struct ath9k_ops_config {
214 u32 enable_ani; 250 u32 enable_ani;
215 int serialize_regmode; 251 int serialize_regmode;
216 bool rx_intr_mitigation; 252 bool rx_intr_mitigation;
253 bool tx_intr_mitigation;
217#define SPUR_DISABLE 0 254#define SPUR_DISABLE 0
218#define SPUR_ENABLE_IOCTL 1 255#define SPUR_ENABLE_IOCTL 1
219#define SPUR_ENABLE_EEPROM 2 256#define SPUR_ENABLE_EEPROM 2
@@ -225,6 +262,7 @@ struct ath9k_ops_config {
225#define AR_BASE_FREQ_5GHZ 4900 262#define AR_BASE_FREQ_5GHZ 4900
226#define AR_SPUR_FEEQ_BOUND_HT40 19 263#define AR_SPUR_FEEQ_BOUND_HT40 19
227#define AR_SPUR_FEEQ_BOUND_HT20 10 264#define AR_SPUR_FEEQ_BOUND_HT20 10
265 bool tx_iq_calibration; /* Only available for >= AR9003 */
228 int spurmode; 266 int spurmode;
229 u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; 267 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
230 u8 max_txtrig_level; 268 u8 max_txtrig_level;
@@ -233,6 +271,8 @@ struct ath9k_ops_config {
233enum ath9k_int { 271enum ath9k_int {
234 ATH9K_INT_RX = 0x00000001, 272 ATH9K_INT_RX = 0x00000001,
235 ATH9K_INT_RXDESC = 0x00000002, 273 ATH9K_INT_RXDESC = 0x00000002,
274 ATH9K_INT_RXHP = 0x00000001,
275 ATH9K_INT_RXLP = 0x00000002,
236 ATH9K_INT_RXNOFRM = 0x00000008, 276 ATH9K_INT_RXNOFRM = 0x00000008,
237 ATH9K_INT_RXEOL = 0x00000010, 277 ATH9K_INT_RXEOL = 0x00000010,
238 ATH9K_INT_RXORN = 0x00000020, 278 ATH9K_INT_RXORN = 0x00000020,
@@ -329,10 +369,9 @@ struct ath9k_channel {
329#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) 369#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
330#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) 370#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
331#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) 371#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
332#define IS_CHAN_A_5MHZ_SPACED(_c) \ 372#define IS_CHAN_A_FAST_CLOCK(_ah, _c) \
333 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ 373 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
334 (((_c)->channel % 20) != 0) && \ 374 ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
335 (((_c)->channel % 10) != 0))
336 375
337/* These macros check chanmode and not channelFlags */ 376/* These macros check chanmode and not channelFlags */
338#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) 377#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
@@ -365,6 +404,12 @@ enum ser_reg_mode {
365 SER_REG_MODE_AUTO = 2, 404 SER_REG_MODE_AUTO = 2,
366}; 405};
367 406
407enum ath9k_rx_qtype {
408 ATH9K_RX_QUEUE_HP,
409 ATH9K_RX_QUEUE_LP,
410 ATH9K_RX_QUEUE_MAX,
411};
412
368struct ath9k_beacon_state { 413struct ath9k_beacon_state {
369 u32 bs_nexttbtt; 414 u32 bs_nexttbtt;
370 u32 bs_nextdtim; 415 u32 bs_nextdtim;
@@ -442,6 +487,124 @@ struct ath_gen_timer_table {
442 } timer_mask; 487 } timer_mask;
443}; 488};
444 489
490/**
491 * struct ath_hw_private_ops - callbacks used internally by hardware code
492 *
493 * This structure contains private callbacks designed to only be used internally
494 * by the hardware core.
495 *
496 * @init_cal_settings: setup types of calibrations supported
497 * @init_cal: starts actual calibration
498 *
499 * @init_mode_regs: Initializes mode registers
500 * @init_mode_gain_regs: Initialize TX/RX gain registers
501 * @macversion_supported: If this specific mac revision is supported
502 *
503 * @rf_set_freq: change frequency
504 * @spur_mitigate_freq: spur mitigation
505 * @rf_alloc_ext_banks:
506 * @rf_free_ext_banks:
507 * @set_rf_regs:
508 * @compute_pll_control: compute the PLL control value to use for
509 * AR_RTC_PLL_CONTROL for a given channel
510 * @setup_calibration: set up calibration
511 * @iscal_supported: used to query if a type of calibration is supported
512 * @loadnf: load noise floor read from each chain on the CCA registers
513 */
514struct ath_hw_private_ops {
515 /* Calibration ops */
516 void (*init_cal_settings)(struct ath_hw *ah);
517 bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
518
519 void (*init_mode_regs)(struct ath_hw *ah);
520 void (*init_mode_gain_regs)(struct ath_hw *ah);
521 bool (*macversion_supported)(u32 macversion);
522 void (*setup_calibration)(struct ath_hw *ah,
523 struct ath9k_cal_list *currCal);
524 bool (*iscal_supported)(struct ath_hw *ah,
525 enum ath9k_cal_types calType);
526
527 /* PHY ops */
528 int (*rf_set_freq)(struct ath_hw *ah,
529 struct ath9k_channel *chan);
530 void (*spur_mitigate_freq)(struct ath_hw *ah,
531 struct ath9k_channel *chan);
532 int (*rf_alloc_ext_banks)(struct ath_hw *ah);
533 void (*rf_free_ext_banks)(struct ath_hw *ah);
534 bool (*set_rf_regs)(struct ath_hw *ah,
535 struct ath9k_channel *chan,
536 u16 modesIndex);
537 void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan);
538 void (*init_bb)(struct ath_hw *ah,
539 struct ath9k_channel *chan);
540 int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan);
541 void (*olc_init)(struct ath_hw *ah);
542 void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan);
543 void (*mark_phy_inactive)(struct ath_hw *ah);
544 void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
545 bool (*rfbus_req)(struct ath_hw *ah);
546 void (*rfbus_done)(struct ath_hw *ah);
547 void (*enable_rfkill)(struct ath_hw *ah);
548 void (*restore_chainmask)(struct ath_hw *ah);
549 void (*set_diversity)(struct ath_hw *ah, bool value);
550 u32 (*compute_pll_control)(struct ath_hw *ah,
551 struct ath9k_channel *chan);
552 bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
553 int param);
554 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
555 void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
556};
557
558/**
559 * struct ath_hw_ops - callbacks used by hardware code and driver code
560 *
561 * This structure contains callbacks designed to to be used internally by
562 * hardware code and also by the lower level driver.
563 *
564 * @config_pci_powersave:
565 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
566 */
567struct ath_hw_ops {
568 void (*config_pci_powersave)(struct ath_hw *ah,
569 int restore,
570 int power_off);
571 void (*rx_enable)(struct ath_hw *ah);
572 void (*set_desc_link)(void *ds, u32 link);
573 void (*get_desc_link)(void *ds, u32 **link);
574 bool (*calibrate)(struct ath_hw *ah,
575 struct ath9k_channel *chan,
576 u8 rxchainmask,
577 bool longcal);
578 bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
579 void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
580 bool is_firstseg, bool is_is_lastseg,
581 const void *ds0, dma_addr_t buf_addr,
582 unsigned int qcu);
583 int (*proc_txdesc)(struct ath_hw *ah, void *ds,
584 struct ath_tx_status *ts);
585 void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
586 u32 pktLen, enum ath9k_pkt_type type,
587 u32 txPower, u32 keyIx,
588 enum ath9k_key_type keyType,
589 u32 flags);
590 void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
591 void *lastds,
592 u32 durUpdateEn, u32 rtsctsRate,
593 u32 rtsctsDuration,
594 struct ath9k_11n_rate_series series[],
595 u32 nseries, u32 flags);
596 void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
597 u32 aggrLen);
598 void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
599 u32 numDelims);
600 void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
601 void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
602 void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
603 u32 burstDuration);
604 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
605 u32 vmf);
606};
607
445struct ath_hw { 608struct ath_hw {
446 struct ieee80211_hw *hw; 609 struct ieee80211_hw *hw;
447 struct ath_common common; 610 struct ath_common common;
@@ -455,13 +618,18 @@ struct ath_hw {
455 struct ar5416_eeprom_def def; 618 struct ar5416_eeprom_def def;
456 struct ar5416_eeprom_4k map4k; 619 struct ar5416_eeprom_4k map4k;
457 struct ar9287_eeprom map9287; 620 struct ar9287_eeprom map9287;
621 struct ar9300_eeprom ar9300_eep;
458 } eeprom; 622 } eeprom;
459 const struct eeprom_ops *eep_ops; 623 const struct eeprom_ops *eep_ops;
460 enum ath9k_eep_map eep_map;
461 624
462 bool sw_mgmt_crypto; 625 bool sw_mgmt_crypto;
463 bool is_pciexpress; 626 bool is_pciexpress;
627 bool need_an_top2_fixup;
464 u16 tx_trig_level; 628 u16 tx_trig_level;
629 s16 nf_2g_max;
630 s16 nf_2g_min;
631 s16 nf_5g_max;
632 s16 nf_5g_min;
465 u16 rfsilent; 633 u16 rfsilent;
466 u32 rfkill_gpio; 634 u32 rfkill_gpio;
467 u32 rfkill_polarity; 635 u32 rfkill_polarity;
@@ -478,7 +646,8 @@ struct ath_hw {
478 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; 646 struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
479 647
480 int16_t curchan_rad_index; 648 int16_t curchan_rad_index;
481 u32 mask_reg; 649 enum ath9k_int imask;
650 u32 imrs2_reg;
482 u32 txok_interrupt_mask; 651 u32 txok_interrupt_mask;
483 u32 txerr_interrupt_mask; 652 u32 txerr_interrupt_mask;
484 u32 txdesc_interrupt_mask; 653 u32 txdesc_interrupt_mask;
@@ -493,6 +662,7 @@ struct ath_hw {
493 struct ath9k_cal_list adcgain_caldata; 662 struct ath9k_cal_list adcgain_caldata;
494 struct ath9k_cal_list adcdc_calinitdata; 663 struct ath9k_cal_list adcdc_calinitdata;
495 struct ath9k_cal_list adcdc_caldata; 664 struct ath9k_cal_list adcdc_caldata;
665 struct ath9k_cal_list tempCompCalData;
496 struct ath9k_cal_list *cal_list; 666 struct ath9k_cal_list *cal_list;
497 struct ath9k_cal_list *cal_list_last; 667 struct ath9k_cal_list *cal_list_last;
498 struct ath9k_cal_list *cal_list_curr; 668 struct ath9k_cal_list *cal_list_curr;
@@ -533,12 +703,10 @@ struct ath_hw {
533 DONT_USE_32KHZ, 703 DONT_USE_32KHZ,
534 } enable_32kHz_clock; 704 } enable_32kHz_clock;
535 705
536 /* Callback for radio frequency change */ 706 /* Private to hardware code */
537 int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan); 707 struct ath_hw_private_ops private_ops;
538 708 /* Accessed by the lower level driver */
539 /* Callback for baseband spur frequency */ 709 struct ath_hw_ops ops;
540 void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
541 struct ath9k_channel *chan);
542 710
543 /* Used to program the radio on non single-chip devices */ 711 /* Used to program the radio on non single-chip devices */
544 u32 *analogBank0Data; 712 u32 *analogBank0Data;
@@ -551,6 +719,7 @@ struct ath_hw {
551 u32 *addac5416_21; 719 u32 *addac5416_21;
552 u32 *bank6Temp; 720 u32 *bank6Temp;
553 721
722 u8 txpower_limit;
554 int16_t txpower_indexoffset; 723 int16_t txpower_indexoffset;
555 int coverage_class; 724 int coverage_class;
556 u32 beacon_interval; 725 u32 beacon_interval;
@@ -592,16 +761,34 @@ struct ath_hw {
592 struct ar5416IniArray iniBank7; 761 struct ar5416IniArray iniBank7;
593 struct ar5416IniArray iniAddac; 762 struct ar5416IniArray iniAddac;
594 struct ar5416IniArray iniPcieSerdes; 763 struct ar5416IniArray iniPcieSerdes;
764 struct ar5416IniArray iniPcieSerdesLowPower;
595 struct ar5416IniArray iniModesAdditional; 765 struct ar5416IniArray iniModesAdditional;
596 struct ar5416IniArray iniModesRxGain; 766 struct ar5416IniArray iniModesRxGain;
597 struct ar5416IniArray iniModesTxGain; 767 struct ar5416IniArray iniModesTxGain;
598 struct ar5416IniArray iniModes_9271_1_0_only; 768 struct ar5416IniArray iniModes_9271_1_0_only;
599 struct ar5416IniArray iniCckfirNormal; 769 struct ar5416IniArray iniCckfirNormal;
600 struct ar5416IniArray iniCckfirJapan2484; 770 struct ar5416IniArray iniCckfirJapan2484;
771 struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
772 struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
773 struct ar5416IniArray iniModes_9271_ANI_reg;
774 struct ar5416IniArray iniModes_high_power_tx_gain_9271;
775 struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
776
777 struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
778 struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
779 struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT];
780 struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT];
601 781
602 u32 intr_gen_timer_trigger; 782 u32 intr_gen_timer_trigger;
603 u32 intr_gen_timer_thresh; 783 u32 intr_gen_timer_thresh;
604 struct ath_gen_timer_table hw_gen_timers; 784 struct ath_gen_timer_table hw_gen_timers;
785
786 struct ar9003_txs *ts_ring;
787 void *ts_start;
788 u32 ts_paddr_start;
789 u32 ts_paddr_end;
790 u16 ts_tail;
791 u8 ts_size;
605}; 792};
606 793
607static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) 794static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -614,6 +801,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
614 return &(ath9k_hw_common(ah)->regulatory); 801 return &(ath9k_hw_common(ah)->regulatory);
615} 802}
616 803
804static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
805{
806 return &ah->private_ops;
807}
808
809static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
810{
811 return &ah->ops;
812}
813
617/* Initialization, Detach, Reset */ 814/* Initialization, Detach, Reset */
618const char *ath9k_hw_probe(u16 vendorid, u16 devid); 815const char *ath9k_hw_probe(u16 vendorid, u16 devid);
619void ath9k_hw_deinit(struct ath_hw *ah); 816void ath9k_hw_deinit(struct ath_hw *ah);
@@ -625,6 +822,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
625 u32 capability, u32 *result); 822 u32 capability, u32 *result);
626bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, 823bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
627 u32 capability, u32 setting, int *status); 824 u32 capability, u32 setting, int *status);
825u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
628 826
629/* Key Cache Management */ 827/* Key Cache Management */
630bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); 828bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
@@ -673,16 +871,10 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah);
673void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 871void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
674void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, 872void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
675 const struct ath9k_beacon_state *bs); 873 const struct ath9k_beacon_state *bs);
874bool ath9k_hw_check_alive(struct ath_hw *ah);
676 875
677bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 876bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
678 877
679void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
680
681/* Interrupt Handling */
682bool ath9k_hw_intrpend(struct ath_hw *ah);
683bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
684enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
685
686/* Generic hw timer primitives */ 878/* Generic hw timer primitives */
687struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 879struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
688 void (*trigger)(void *), 880 void (*trigger)(void *),
@@ -701,6 +893,39 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
701 893
702void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); 894void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
703 895
896/* HTC */
897void ath9k_hw_htc_resetinit(struct ath_hw *ah);
898
899/* PHY */
900void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
901 u32 *coef_mantissa, u32 *coef_exponent);
902
903/*
904 * Code Specific to AR5008, AR9001 or AR9002,
905 * we stuff these here to avoid callbacks for AR9003.
906 */
907void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
908int ar9002_hw_rf_claim(struct ath_hw *ah);
909void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
910void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
911
912/*
913 * Code specifric to AR9003, we stuff these here to avoid callbacks
914 * for older families
915 */
916void ar9003_hw_set_nf_limits(struct ath_hw *ah);
917
918/* Hardware family op attach helpers */
919void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
920void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
921void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
922
923void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
924void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
925
926void ar9002_hw_attach_ops(struct ath_hw *ah);
927void ar9003_hw_attach_ops(struct ath_hw *ah);
928
704#define ATH_PCIE_CAP_LINK_CTRL 0x70 929#define ATH_PCIE_CAP_LINK_CTRL 0x70
705#define ATH_PCIE_CAP_LINK_L0S 1 930#define ATH_PCIE_CAP_LINK_L0S 1
706#define ATH_PCIE_CAP_LINK_L1 2 931#define ATH_PCIE_CAP_LINK_L1 2
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 3d4d897add6d..d457cb3bd772 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -175,6 +175,18 @@ static const struct ath_ops ath9k_common_ops = {
175 .write = ath9k_iowrite32, 175 .write = ath9k_iowrite32,
176}; 176};
177 177
178static int count_streams(unsigned int chainmask, int max)
179{
180 int streams = 0;
181
182 do {
183 if (++streams == max)
184 break;
185 } while ((chainmask = chainmask & (chainmask - 1)));
186
187 return streams;
188}
189
178/**************************/ 190/**************************/
179/* Initialization */ 191/* Initialization */
180/**************************/ 192/**************************/
@@ -182,8 +194,10 @@ static const struct ath_ops ath9k_common_ops = {
182static void setup_ht_cap(struct ath_softc *sc, 194static void setup_ht_cap(struct ath_softc *sc,
183 struct ieee80211_sta_ht_cap *ht_info) 195 struct ieee80211_sta_ht_cap *ht_info)
184{ 196{
185 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 197 struct ath_hw *ah = sc->sc_ah;
198 struct ath_common *common = ath9k_hw_common(ah);
186 u8 tx_streams, rx_streams; 199 u8 tx_streams, rx_streams;
200 int i, max_streams;
187 201
188 ht_info->ht_supported = true; 202 ht_info->ht_supported = true;
189 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 203 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
@@ -191,28 +205,40 @@ static void setup_ht_cap(struct ath_softc *sc,
191 IEEE80211_HT_CAP_SGI_40 | 205 IEEE80211_HT_CAP_SGI_40 |
192 IEEE80211_HT_CAP_DSSSCCK40; 206 IEEE80211_HT_CAP_DSSSCCK40;
193 207
208 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
209 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
210
194 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 211 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
195 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; 212 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
196 213
214 if (AR_SREV_9300_20_OR_LATER(ah))
215 max_streams = 3;
216 else
217 max_streams = 2;
218
219 if (AR_SREV_9280_10_OR_LATER(ah)) {
220 if (max_streams >= 2)
221 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
222 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
223 }
224
197 /* set up supported mcs set */ 225 /* set up supported mcs set */
198 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 226 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
199 tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? 227 tx_streams = count_streams(common->tx_chainmask, max_streams);
200 1 : 2; 228 rx_streams = count_streams(common->rx_chainmask, max_streams);
201 rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? 229
202 1 : 2; 230 ath_print(common, ATH_DBG_CONFIG,
231 "TX streams %d, RX streams: %d\n",
232 tx_streams, rx_streams);
203 233
204 if (tx_streams != rx_streams) { 234 if (tx_streams != rx_streams) {
205 ath_print(common, ATH_DBG_CONFIG,
206 "TX streams %d, RX streams: %d\n",
207 tx_streams, rx_streams);
208 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; 235 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
209 ht_info->mcs.tx_params |= ((tx_streams - 1) << 236 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
210 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); 237 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
211 } 238 }
212 239
213 ht_info->mcs.rx_mask[0] = 0xff; 240 for (i = 0; i < rx_streams; i++)
214 if (rx_streams >= 2) 241 ht_info->mcs.rx_mask[i] = 0xff;
215 ht_info->mcs.rx_mask[1] = 0xff;
216 242
217 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; 243 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
218} 244}
@@ -235,31 +261,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
235*/ 261*/
236int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, 262int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
237 struct list_head *head, const char *name, 263 struct list_head *head, const char *name,
238 int nbuf, int ndesc) 264 int nbuf, int ndesc, bool is_tx)
239{ 265{
240#define DS2PHYS(_dd, _ds) \ 266#define DS2PHYS(_dd, _ds) \
241 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 267 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
242#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) 268#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
243#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) 269#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
244 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 270 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
245 struct ath_desc *ds; 271 u8 *ds;
246 struct ath_buf *bf; 272 struct ath_buf *bf;
247 int i, bsize, error; 273 int i, bsize, error, desc_len;
248 274
249 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", 275 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
250 name, nbuf, ndesc); 276 name, nbuf, ndesc);
251 277
252 INIT_LIST_HEAD(head); 278 INIT_LIST_HEAD(head);
279
280 if (is_tx)
281 desc_len = sc->sc_ah->caps.tx_desc_len;
282 else
283 desc_len = sizeof(struct ath_desc);
284
253 /* ath_desc must be a multiple of DWORDs */ 285 /* ath_desc must be a multiple of DWORDs */
254 if ((sizeof(struct ath_desc) % 4) != 0) { 286 if ((desc_len % 4) != 0) {
255 ath_print(common, ATH_DBG_FATAL, 287 ath_print(common, ATH_DBG_FATAL,
256 "ath_desc not DWORD aligned\n"); 288 "ath_desc not DWORD aligned\n");
257 BUG_ON((sizeof(struct ath_desc) % 4) != 0); 289 BUG_ON((desc_len % 4) != 0);
258 error = -ENOMEM; 290 error = -ENOMEM;
259 goto fail; 291 goto fail;
260 } 292 }
261 293
262 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; 294 dd->dd_desc_len = desc_len * nbuf * ndesc;
263 295
264 /* 296 /*
265 * Need additional DMA memory because we can't use 297 * Need additional DMA memory because we can't use
@@ -272,11 +304,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
272 u32 dma_len; 304 u32 dma_len;
273 305
274 while (ndesc_skipped) { 306 while (ndesc_skipped) {
275 dma_len = ndesc_skipped * sizeof(struct ath_desc); 307 dma_len = ndesc_skipped * desc_len;
276 dd->dd_desc_len += dma_len; 308 dd->dd_desc_len += dma_len;
277 309
278 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); 310 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
279 }; 311 }
280 } 312 }
281 313
282 /* allocate descriptors */ 314 /* allocate descriptors */
@@ -286,7 +318,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
286 error = -ENOMEM; 318 error = -ENOMEM;
287 goto fail; 319 goto fail;
288 } 320 }
289 ds = dd->dd_desc; 321 ds = (u8 *) dd->dd_desc;
290 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", 322 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
291 name, ds, (u32) dd->dd_desc_len, 323 name, ds, (u32) dd->dd_desc_len,
292 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); 324 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
@@ -300,7 +332,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
300 } 332 }
301 dd->dd_bufptr = bf; 333 dd->dd_bufptr = bf;
302 334
303 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { 335 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
304 bf->bf_desc = ds; 336 bf->bf_desc = ds;
305 bf->bf_daddr = DS2PHYS(dd, ds); 337 bf->bf_daddr = DS2PHYS(dd, ds);
306 338
@@ -316,7 +348,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
316 ((caddr_t) dd->dd_desc + 348 ((caddr_t) dd->dd_desc +
317 dd->dd_desc_len)); 349 dd->dd_desc_len));
318 350
319 ds += ndesc; 351 ds += (desc_len * ndesc);
320 bf->bf_desc = ds; 352 bf->bf_desc = ds;
321 bf->bf_daddr = DS2PHYS(dd, ds); 353 bf->bf_daddr = DS2PHYS(dd, ds);
322 } 354 }
@@ -514,7 +546,7 @@ static void ath9k_init_misc(struct ath_softc *sc)
514 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; 546 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
515 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; 547 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
516 548
517 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); 549 ath9k_hw_set_diversity(sc->sc_ah, true);
518 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); 550 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
519 551
520 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 552 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
@@ -568,13 +600,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
568 ath_read_cachesize(common, &csz); 600 ath_read_cachesize(common, &csz);
569 common->cachelsz = csz << 2; /* convert to bytes */ 601 common->cachelsz = csz << 2; /* convert to bytes */
570 602
603 /* Initializes the hardware for all supported chipsets */
571 ret = ath9k_hw_init(ah); 604 ret = ath9k_hw_init(ah);
572 if (ret) { 605 if (ret)
573 ath_print(common, ATH_DBG_FATAL,
574 "Unable to initialize hardware; "
575 "initialization status: %d\n", ret);
576 goto err_hw; 606 goto err_hw;
577 }
578 607
579 ret = ath9k_init_debug(ah); 608 ret = ath9k_init_debug(ah);
580 if (ret) { 609 if (ret) {
@@ -760,6 +789,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
760 789
761 tasklet_kill(&sc->intr_tq); 790 tasklet_kill(&sc->intr_tq);
762 tasklet_kill(&sc->bcon_tasklet); 791 tasklet_kill(&sc->bcon_tasklet);
792
793 kfree(sc->sc_ah);
794 sc->sc_ah = NULL;
763} 795}
764 796
765void ath9k_deinit_device(struct ath_softc *sc) 797void ath9k_deinit_device(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index efc420cd42bf..0e425cb4bbb1 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -25,14 +25,21 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, 25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
26 ah->txurn_interrupt_mask); 26 ah->txurn_interrupt_mask);
27 27
28 ENABLE_REGWRITE_BUFFER(ah);
29
28 REG_WRITE(ah, AR_IMR_S0, 30 REG_WRITE(ah, AR_IMR_S0,
29 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) 31 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
30 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); 32 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
31 REG_WRITE(ah, AR_IMR_S1, 33 REG_WRITE(ah, AR_IMR_S1,
32 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) 34 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
33 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); 35 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
34 REG_RMW_FIELD(ah, AR_IMR_S2, 36
35 AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); 37 ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
38 ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
39 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
40
41 REGWRITE_BUFFER_FLUSH(ah);
42 DISABLE_REGWRITE_BUFFER(ah);
36} 43}
37 44
38u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 45u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -55,6 +62,18 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
55} 62}
56EXPORT_SYMBOL(ath9k_hw_txstart); 63EXPORT_SYMBOL(ath9k_hw_txstart);
57 64
65void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds)
66{
67 struct ar5416_desc *ads = AR5416DESC(ds);
68
69 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
70 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
71 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
72 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
73 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
74}
75EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
76
58u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) 77u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
59{ 78{
60 u32 npend; 79 u32 npend;
@@ -103,7 +122,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
103 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 122 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
104 return false; 123 return false;
105 124
106 omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); 125 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
107 126
108 txcfg = REG_READ(ah, AR_TXCFG); 127 txcfg = REG_READ(ah, AR_TXCFG);
109 curLevel = MS(txcfg, AR_FTRIG); 128 curLevel = MS(txcfg, AR_FTRIG);
@@ -205,280 +224,6 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
205} 224}
206EXPORT_SYMBOL(ath9k_hw_stoptxdma); 225EXPORT_SYMBOL(ath9k_hw_stoptxdma);
207 226
208void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
209 u32 segLen, bool firstSeg,
210 bool lastSeg, const struct ath_desc *ds0)
211{
212 struct ar5416_desc *ads = AR5416DESC(ds);
213
214 if (firstSeg) {
215 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
216 } else if (lastSeg) {
217 ads->ds_ctl0 = 0;
218 ads->ds_ctl1 = segLen;
219 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
220 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
221 } else {
222 ads->ds_ctl0 = 0;
223 ads->ds_ctl1 = segLen | AR_TxMore;
224 ads->ds_ctl2 = 0;
225 ads->ds_ctl3 = 0;
226 }
227 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
228 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
229 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
230 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
231 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
232}
233EXPORT_SYMBOL(ath9k_hw_filltxdesc);
234
235void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
236{
237 struct ar5416_desc *ads = AR5416DESC(ds);
238
239 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
240 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
241 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
242 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
243 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
244}
245EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
246
247int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
248{
249 struct ar5416_desc *ads = AR5416DESC(ds);
250
251 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
252 return -EINPROGRESS;
253
254 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
255 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
256 ds->ds_txstat.ts_status = 0;
257 ds->ds_txstat.ts_flags = 0;
258
259 if (ads->ds_txstatus1 & AR_FrmXmitOK)
260 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
261 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
262 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
263 if (ads->ds_txstatus1 & AR_Filtered)
264 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
265 if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
266 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
267 ath9k_hw_updatetxtriglevel(ah, true);
268 }
269 if (ads->ds_txstatus9 & AR_TxOpExceeded)
270 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
271 if (ads->ds_txstatus1 & AR_TxTimerExpired)
272 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
273
274 if (ads->ds_txstatus1 & AR_DescCfgErr)
275 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
276 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
277 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
278 ath9k_hw_updatetxtriglevel(ah, true);
279 }
280 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
281 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
282 ath9k_hw_updatetxtriglevel(ah, true);
283 }
284 if (ads->ds_txstatus0 & AR_TxBaStatus) {
285 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
286 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
287 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
288 }
289
290 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
291 switch (ds->ds_txstat.ts_rateindex) {
292 case 0:
293 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
294 break;
295 case 1:
296 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
297 break;
298 case 2:
299 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
300 break;
301 case 3:
302 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
303 break;
304 }
305
306 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
307 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
308 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
309 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
310 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
311 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
312 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
313 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
314 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
315 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
316 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
317 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
318 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
319 ds->ds_txstat.ts_antenna = 0;
320
321 return 0;
322}
323EXPORT_SYMBOL(ath9k_hw_txprocdesc);
324
325void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
326 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
327 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
328{
329 struct ar5416_desc *ads = AR5416DESC(ds);
330
331 txPower += ah->txpower_indexoffset;
332 if (txPower > 63)
333 txPower = 63;
334
335 ads->ds_ctl0 = (pktLen & AR_FrameLen)
336 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
337 | SM(txPower, AR_XmitPower)
338 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
339 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
340 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
341 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
342
343 ads->ds_ctl1 =
344 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
345 | SM(type, AR_FrameType)
346 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
347 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
348 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
349
350 ads->ds_ctl6 = SM(keyType, AR_EncrType);
351
352 if (AR_SREV_9285(ah)) {
353 ads->ds_ctl8 = 0;
354 ads->ds_ctl9 = 0;
355 ads->ds_ctl10 = 0;
356 ads->ds_ctl11 = 0;
357 }
358}
359EXPORT_SYMBOL(ath9k_hw_set11n_txdesc);
360
361void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
362 struct ath_desc *lastds,
363 u32 durUpdateEn, u32 rtsctsRate,
364 u32 rtsctsDuration,
365 struct ath9k_11n_rate_series series[],
366 u32 nseries, u32 flags)
367{
368 struct ar5416_desc *ads = AR5416DESC(ds);
369 struct ar5416_desc *last_ads = AR5416DESC(lastds);
370 u32 ds_ctl0;
371
372 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
373 ds_ctl0 = ads->ds_ctl0;
374
375 if (flags & ATH9K_TXDESC_RTSENA) {
376 ds_ctl0 &= ~AR_CTSEnable;
377 ds_ctl0 |= AR_RTSEnable;
378 } else {
379 ds_ctl0 &= ~AR_RTSEnable;
380 ds_ctl0 |= AR_CTSEnable;
381 }
382
383 ads->ds_ctl0 = ds_ctl0;
384 } else {
385 ads->ds_ctl0 =
386 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
387 }
388
389 ads->ds_ctl2 = set11nTries(series, 0)
390 | set11nTries(series, 1)
391 | set11nTries(series, 2)
392 | set11nTries(series, 3)
393 | (durUpdateEn ? AR_DurUpdateEna : 0)
394 | SM(0, AR_BurstDur);
395
396 ads->ds_ctl3 = set11nRate(series, 0)
397 | set11nRate(series, 1)
398 | set11nRate(series, 2)
399 | set11nRate(series, 3);
400
401 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
402 | set11nPktDurRTSCTS(series, 1);
403
404 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
405 | set11nPktDurRTSCTS(series, 3);
406
407 ads->ds_ctl7 = set11nRateFlags(series, 0)
408 | set11nRateFlags(series, 1)
409 | set11nRateFlags(series, 2)
410 | set11nRateFlags(series, 3)
411 | SM(rtsctsRate, AR_RTSCTSRate);
412 last_ads->ds_ctl2 = ads->ds_ctl2;
413 last_ads->ds_ctl3 = ads->ds_ctl3;
414}
415EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario);
416
417void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
418 u32 aggrLen)
419{
420 struct ar5416_desc *ads = AR5416DESC(ds);
421
422 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
423 ads->ds_ctl6 &= ~AR_AggrLen;
424 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
425}
426EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first);
427
428void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
429 u32 numDelims)
430{
431 struct ar5416_desc *ads = AR5416DESC(ds);
432 unsigned int ctl6;
433
434 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
435
436 ctl6 = ads->ds_ctl6;
437 ctl6 &= ~AR_PadDelim;
438 ctl6 |= SM(numDelims, AR_PadDelim);
439 ads->ds_ctl6 = ctl6;
440}
441EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle);
442
443void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
444{
445 struct ar5416_desc *ads = AR5416DESC(ds);
446
447 ads->ds_ctl1 |= AR_IsAggr;
448 ads->ds_ctl1 &= ~AR_MoreAggr;
449 ads->ds_ctl6 &= ~AR_PadDelim;
450}
451EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last);
452
453void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
454{
455 struct ar5416_desc *ads = AR5416DESC(ds);
456
457 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
458}
459EXPORT_SYMBOL(ath9k_hw_clr11n_aggr);
460
461void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
462 u32 burstDuration)
463{
464 struct ar5416_desc *ads = AR5416DESC(ds);
465
466 ads->ds_ctl2 &= ~AR_BurstDur;
467 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
468}
469EXPORT_SYMBOL(ath9k_hw_set11n_burstduration);
470
471void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
472 u32 vmf)
473{
474 struct ar5416_desc *ads = AR5416DESC(ds);
475
476 if (vmf)
477 ads->ds_ctl0 |= AR_VirtMoreFrag;
478 else
479 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
480}
481
482void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) 227void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
483{ 228{
484 *txqs &= ah->intr_txqs; 229 *txqs &= ah->intr_txqs;
@@ -730,6 +475,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
730 } else 475 } else
731 cwMin = qi->tqi_cwmin; 476 cwMin = qi->tqi_cwmin;
732 477
478 ENABLE_REGWRITE_BUFFER(ah);
479
733 REG_WRITE(ah, AR_DLCL_IFS(q), 480 REG_WRITE(ah, AR_DLCL_IFS(q),
734 SM(cwMin, AR_D_LCL_IFS_CWMIN) | 481 SM(cwMin, AR_D_LCL_IFS_CWMIN) |
735 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | 482 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
@@ -744,6 +491,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
744 REG_WRITE(ah, AR_DMISC(q), 491 REG_WRITE(ah, AR_DMISC(q),
745 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); 492 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
746 493
494 REGWRITE_BUFFER_FLUSH(ah);
495
747 if (qi->tqi_cbrPeriod) { 496 if (qi->tqi_cbrPeriod) {
748 REG_WRITE(ah, AR_QCBRCFG(q), 497 REG_WRITE(ah, AR_QCBRCFG(q),
749 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 498 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
@@ -759,6 +508,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
759 AR_Q_RDYTIMECFG_EN); 508 AR_Q_RDYTIMECFG_EN);
760 } 509 }
761 510
511 REGWRITE_BUFFER_FLUSH(ah);
512
762 REG_WRITE(ah, AR_DCHNTIME(q), 513 REG_WRITE(ah, AR_DCHNTIME(q),
763 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | 514 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
764 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 515 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
@@ -776,6 +527,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
776 REG_READ(ah, AR_DMISC(q)) | 527 REG_READ(ah, AR_DMISC(q)) |
777 AR_D_MISC_POST_FR_BKOFF_DIS); 528 AR_D_MISC_POST_FR_BKOFF_DIS);
778 } 529 }
530
531 REGWRITE_BUFFER_FLUSH(ah);
532 DISABLE_REGWRITE_BUFFER(ah);
533
779 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 534 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
780 REG_WRITE(ah, AR_DMISC(q), 535 REG_WRITE(ah, AR_DMISC(q),
781 REG_READ(ah, AR_DMISC(q)) | 536 REG_READ(ah, AR_DMISC(q)) |
@@ -783,6 +538,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
783 } 538 }
784 switch (qi->tqi_type) { 539 switch (qi->tqi_type) {
785 case ATH9K_TX_QUEUE_BEACON: 540 case ATH9K_TX_QUEUE_BEACON:
541 ENABLE_REGWRITE_BUFFER(ah);
542
786 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 543 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
787 | AR_Q_MISC_FSP_DBA_GATED 544 | AR_Q_MISC_FSP_DBA_GATED
788 | AR_Q_MISC_BEACON_USE 545 | AR_Q_MISC_BEACON_USE
@@ -793,8 +550,20 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
793 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 550 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
794 | AR_D_MISC_BEACON_USE 551 | AR_D_MISC_BEACON_USE
795 | AR_D_MISC_POST_FR_BKOFF_DIS); 552 | AR_D_MISC_POST_FR_BKOFF_DIS);
553
554 REGWRITE_BUFFER_FLUSH(ah);
555 DISABLE_REGWRITE_BUFFER(ah);
556
557 /* cwmin and cwmax should be 0 for beacon queue */
558 if (AR_SREV_9300_20_OR_LATER(ah)) {
559 REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
560 | SM(0, AR_D_LCL_IFS_CWMAX)
561 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
562 }
796 break; 563 break;
797 case ATH9K_TX_QUEUE_CAB: 564 case ATH9K_TX_QUEUE_CAB:
565 ENABLE_REGWRITE_BUFFER(ah);
566
798 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 567 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
799 | AR_Q_MISC_FSP_DBA_GATED 568 | AR_Q_MISC_FSP_DBA_GATED
800 | AR_Q_MISC_CBR_INCR_DIS1 569 | AR_Q_MISC_CBR_INCR_DIS1
@@ -808,6 +577,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
808 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 577 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
809 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 578 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
810 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 579 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
580
581 REGWRITE_BUFFER_FLUSH(ah);
582 DISABLE_REGWRITE_BUFFER(ah);
583
811 break; 584 break;
812 case ATH9K_TX_QUEUE_PSPOLL: 585 case ATH9K_TX_QUEUE_PSPOLL:
813 REG_WRITE(ah, AR_QMISC(q), 586 REG_WRITE(ah, AR_QMISC(q),
@@ -829,6 +602,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
829 AR_D_MISC_POST_FR_BKOFF_DIS); 602 AR_D_MISC_POST_FR_BKOFF_DIS);
830 } 603 }
831 604
605 if (AR_SREV_9300_20_OR_LATER(ah))
606 REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
607
832 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) 608 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
833 ah->txok_interrupt_mask |= 1 << q; 609 ah->txok_interrupt_mask |= 1 << q;
834 else 610 else
@@ -856,7 +632,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
856EXPORT_SYMBOL(ath9k_hw_resettxqueue); 632EXPORT_SYMBOL(ath9k_hw_resettxqueue);
857 633
858int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 634int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
859 u32 pa, struct ath_desc *nds, u64 tsf) 635 struct ath_rx_status *rs, u64 tsf)
860{ 636{
861 struct ar5416_desc ads; 637 struct ar5416_desc ads;
862 struct ar5416_desc *adsp = AR5416DESC(ds); 638 struct ar5416_desc *adsp = AR5416DESC(ds);
@@ -867,92 +643,76 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
867 643
868 ads.u.rx = adsp->u.rx; 644 ads.u.rx = adsp->u.rx;
869 645
870 ds->ds_rxstat.rs_status = 0; 646 rs->rs_status = 0;
871 ds->ds_rxstat.rs_flags = 0; 647 rs->rs_flags = 0;
872 648
873 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 649 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
874 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; 650 rs->rs_tstamp = ads.AR_RcvTimestamp;
875 651
876 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { 652 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
877 ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD; 653 rs->rs_rssi = ATH9K_RSSI_BAD;
878 ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD; 654 rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
879 ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD; 655 rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
880 ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD; 656 rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
881 ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD; 657 rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
882 ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD; 658 rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
883 ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD; 659 rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
884 } else { 660 } else {
885 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 661 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
886 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, 662 rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
887 AR_RxRSSIAnt00); 663 AR_RxRSSIAnt00);
888 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, 664 rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
889 AR_RxRSSIAnt01); 665 AR_RxRSSIAnt01);
890 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, 666 rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
891 AR_RxRSSIAnt02); 667 AR_RxRSSIAnt02);
892 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, 668 rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
893 AR_RxRSSIAnt10); 669 AR_RxRSSIAnt10);
894 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, 670 rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
895 AR_RxRSSIAnt11); 671 AR_RxRSSIAnt11);
896 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, 672 rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
897 AR_RxRSSIAnt12); 673 AR_RxRSSIAnt12);
898 } 674 }
899 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 675 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
900 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); 676 rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
901 else 677 else
902 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID; 678 rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
903 679
904 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads)); 680 rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
905 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; 681 rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
906 682
907 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; 683 rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
908 ds->ds_rxstat.rs_moreaggr = 684 rs->rs_moreaggr =
909 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 685 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
910 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 686 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
911 ds->ds_rxstat.rs_flags = 687 rs->rs_flags =
912 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 688 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
913 ds->ds_rxstat.rs_flags |= 689 rs->rs_flags |=
914 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 690 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
915 691
916 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 692 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
917 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 693 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
918 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) 694 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
919 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST; 695 rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
920 if (ads.ds_rxstatus8 & AR_DecryptBusyErr) 696 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
921 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY; 697 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
922 698
923 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 699 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
924 if (ads.ds_rxstatus8 & AR_CRCErr) 700 if (ads.ds_rxstatus8 & AR_CRCErr)
925 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC; 701 rs->rs_status |= ATH9K_RXERR_CRC;
926 else if (ads.ds_rxstatus8 & AR_PHYErr) { 702 else if (ads.ds_rxstatus8 & AR_PHYErr) {
927 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY; 703 rs->rs_status |= ATH9K_RXERR_PHY;
928 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 704 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
929 ds->ds_rxstat.rs_phyerr = phyerr; 705 rs->rs_phyerr = phyerr;
930 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 706 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
931 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT; 707 rs->rs_status |= ATH9K_RXERR_DECRYPT;
932 else if (ads.ds_rxstatus8 & AR_MichaelErr) 708 else if (ads.ds_rxstatus8 & AR_MichaelErr)
933 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC; 709 rs->rs_status |= ATH9K_RXERR_MIC;
934 } 710 }
935 711
936 return 0; 712 return 0;
937} 713}
938EXPORT_SYMBOL(ath9k_hw_rxprocdesc); 714EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
939 715
940void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
941 u32 size, u32 flags)
942{
943 struct ar5416_desc *ads = AR5416DESC(ds);
944 struct ath9k_hw_capabilities *pCap = &ah->caps;
945
946 ads->ds_ctl1 = size & AR_BufLen;
947 if (flags & ATH9K_RXDESC_INTREQ)
948 ads->ds_ctl1 |= AR_RxIntrReq;
949
950 ads->ds_rxstatus8 &= ~AR_RxDone;
951 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
952 memset(&(ads->u), 0, sizeof(ads->u));
953}
954EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
955
956/* 716/*
957 * This can stop or re-enables RX. 717 * This can stop or re-enables RX.
958 * 718 *
@@ -996,12 +756,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
996} 756}
997EXPORT_SYMBOL(ath9k_hw_putrxbuf); 757EXPORT_SYMBOL(ath9k_hw_putrxbuf);
998 758
999void ath9k_hw_rxena(struct ath_hw *ah)
1000{
1001 REG_WRITE(ah, AR_CR, AR_CR_RXE);
1002}
1003EXPORT_SYMBOL(ath9k_hw_rxena);
1004
1005void ath9k_hw_startpcureceive(struct ath_hw *ah) 759void ath9k_hw_startpcureceive(struct ath_hw *ah)
1006{ 760{
1007 ath9k_enable_mib_counters(ah); 761 ath9k_enable_mib_counters(ah);
@@ -1020,6 +774,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
1020} 774}
1021EXPORT_SYMBOL(ath9k_hw_stoppcurecv); 775EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
1022 776
777void ath9k_hw_abortpcurecv(struct ath_hw *ah)
778{
779 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
780
781 ath9k_hw_disable_mib_counters(ah);
782}
783EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
784
1023bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 785bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
1024{ 786{
1025#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 787#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
@@ -1065,3 +827,142 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
1065 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); 827 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
1066} 828}
1067EXPORT_SYMBOL(ath9k_hw_beaconq_setup); 829EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
830
831bool ath9k_hw_intrpend(struct ath_hw *ah)
832{
833 u32 host_isr;
834
835 if (AR_SREV_9100(ah))
836 return true;
837
838 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
839 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
840 return true;
841
842 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
843 if ((host_isr & AR_INTR_SYNC_DEFAULT)
844 && (host_isr != AR_INTR_SPURIOUS))
845 return true;
846
847 return false;
848}
849EXPORT_SYMBOL(ath9k_hw_intrpend);
850
851enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
852 enum ath9k_int ints)
853{
854 enum ath9k_int omask = ah->imask;
855 u32 mask, mask2;
856 struct ath9k_hw_capabilities *pCap = &ah->caps;
857 struct ath_common *common = ath9k_hw_common(ah);
858
859 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
860
861 if (omask & ATH9K_INT_GLOBAL) {
862 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
863 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
864 (void) REG_READ(ah, AR_IER);
865 if (!AR_SREV_9100(ah)) {
866 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
867 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
868
869 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
870 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
871 }
872 }
873
874 /* TODO: global int Ref count */
875 mask = ints & ATH9K_INT_COMMON;
876 mask2 = 0;
877
878 if (ints & ATH9K_INT_TX) {
879 if (ah->config.tx_intr_mitigation)
880 mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
881 else {
882 if (ah->txok_interrupt_mask)
883 mask |= AR_IMR_TXOK;
884 if (ah->txdesc_interrupt_mask)
885 mask |= AR_IMR_TXDESC;
886 }
887 if (ah->txerr_interrupt_mask)
888 mask |= AR_IMR_TXERR;
889 if (ah->txeol_interrupt_mask)
890 mask |= AR_IMR_TXEOL;
891 }
892 if (ints & ATH9K_INT_RX) {
893 if (AR_SREV_9300_20_OR_LATER(ah)) {
894 mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
895 if (ah->config.rx_intr_mitigation) {
896 mask &= ~AR_IMR_RXOK_LP;
897 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
898 } else {
899 mask |= AR_IMR_RXOK_LP;
900 }
901 } else {
902 if (ah->config.rx_intr_mitigation)
903 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
904 else
905 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
906 }
907 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
908 mask |= AR_IMR_GENTMR;
909 }
910
911 if (ints & (ATH9K_INT_BMISC)) {
912 mask |= AR_IMR_BCNMISC;
913 if (ints & ATH9K_INT_TIM)
914 mask2 |= AR_IMR_S2_TIM;
915 if (ints & ATH9K_INT_DTIM)
916 mask2 |= AR_IMR_S2_DTIM;
917 if (ints & ATH9K_INT_DTIMSYNC)
918 mask2 |= AR_IMR_S2_DTIMSYNC;
919 if (ints & ATH9K_INT_CABEND)
920 mask2 |= AR_IMR_S2_CABEND;
921 if (ints & ATH9K_INT_TSFOOR)
922 mask2 |= AR_IMR_S2_TSFOOR;
923 }
924
925 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
926 mask |= AR_IMR_BCNMISC;
927 if (ints & ATH9K_INT_GTT)
928 mask2 |= AR_IMR_S2_GTT;
929 if (ints & ATH9K_INT_CST)
930 mask2 |= AR_IMR_S2_CST;
931 }
932
933 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
934 REG_WRITE(ah, AR_IMR, mask);
935 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
936 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
937 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
938 ah->imrs2_reg |= mask2;
939 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
940
941 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
942 if (ints & ATH9K_INT_TIM_TIMER)
943 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
944 else
945 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
946 }
947
948 if (ints & ATH9K_INT_GLOBAL) {
949 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
950 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
951 if (!AR_SREV_9100(ah)) {
952 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
953 AR_INTR_MAC_IRQ);
954 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
955
956
957 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
958 AR_INTR_SYNC_DEFAULT);
959 REG_WRITE(ah, AR_INTR_SYNC_MASK,
960 AR_INTR_SYNC_DEFAULT);
961 }
962 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
963 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
964 }
965
966 return omask;
967}
968EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 29851e6376a9..00f3e0c7528a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -37,6 +37,8 @@
37 AR_2040_##_index : 0) \ 37 AR_2040_##_index : 0) \
38 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ 38 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
39 AR_GI##_index : 0) \ 39 AR_GI##_index : 0) \
40 |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ? \
41 AR_STBC##_index : 0) \
40 |SM((_series)[_index].ChSel, AR_ChainSel##_index)) 42 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
41 43
42#define CCK_SIFS_TIME 10 44#define CCK_SIFS_TIME 10
@@ -86,7 +88,6 @@
86#define ATH9K_TX_DESC_CFG_ERR 0x04 88#define ATH9K_TX_DESC_CFG_ERR 0x04
87#define ATH9K_TX_DATA_UNDERRUN 0x08 89#define ATH9K_TX_DATA_UNDERRUN 0x08
88#define ATH9K_TX_DELIM_UNDERRUN 0x10 90#define ATH9K_TX_DELIM_UNDERRUN 0x10
89#define ATH9K_TX_SW_ABORTED 0x40
90#define ATH9K_TX_SW_FILTERED 0x80 91#define ATH9K_TX_SW_FILTERED 0x80
91 92
92/* 64 bytes */ 93/* 64 bytes */
@@ -117,7 +118,10 @@ struct ath_tx_status {
117 int8_t ts_rssi_ext0; 118 int8_t ts_rssi_ext0;
118 int8_t ts_rssi_ext1; 119 int8_t ts_rssi_ext1;
119 int8_t ts_rssi_ext2; 120 int8_t ts_rssi_ext2;
120 u8 pad[3]; 121 u8 qid;
122 u16 desc_id;
123 u8 tid;
124 u8 pad[2];
121 u32 ba_low; 125 u32 ba_low;
122 u32 ba_high; 126 u32 ba_high;
123 u32 evm0; 127 u32 evm0;
@@ -148,6 +152,34 @@ struct ath_rx_status {
148 u32 evm0; 152 u32 evm0;
149 u32 evm1; 153 u32 evm1;
150 u32 evm2; 154 u32 evm2;
155 u32 evm3;
156 u32 evm4;
157};
158
159struct ath_htc_rx_status {
160 __be64 rs_tstamp;
161 __be16 rs_datalen;
162 u8 rs_status;
163 u8 rs_phyerr;
164 int8_t rs_rssi;
165 int8_t rs_rssi_ctl0;
166 int8_t rs_rssi_ctl1;
167 int8_t rs_rssi_ctl2;
168 int8_t rs_rssi_ext0;
169 int8_t rs_rssi_ext1;
170 int8_t rs_rssi_ext2;
171 u8 rs_keyix;
172 u8 rs_rate;
173 u8 rs_antenna;
174 u8 rs_more;
175 u8 rs_isaggr;
176 u8 rs_moreaggr;
177 u8 rs_num_delims;
178 u8 rs_flags;
179 u8 rs_dummy;
180 __be32 evm0;
181 __be32 evm1;
182 __be32 evm2;
151}; 183};
152 184
153#define ATH9K_RXERR_CRC 0x01 185#define ATH9K_RXERR_CRC 0x01
@@ -207,18 +239,9 @@ struct ath_desc {
207 u32 ds_ctl0; 239 u32 ds_ctl0;
208 u32 ds_ctl1; 240 u32 ds_ctl1;
209 u32 ds_hw[20]; 241 u32 ds_hw[20];
210 union {
211 struct ath_tx_status tx;
212 struct ath_rx_status rx;
213 void *stats;
214 } ds_us;
215 void *ds_vdata; 242 void *ds_vdata;
216} __packed; 243} __packed;
217 244
218#define ds_txstat ds_us.tx
219#define ds_rxstat ds_us.rx
220#define ds_stat ds_us.stats
221
222#define ATH9K_TXDESC_CLRDMASK 0x0001 245#define ATH9K_TXDESC_CLRDMASK 0x0001
223#define ATH9K_TXDESC_NOACK 0x0002 246#define ATH9K_TXDESC_NOACK 0x0002
224#define ATH9K_TXDESC_RTSENA 0x0004 247#define ATH9K_TXDESC_RTSENA 0x0004
@@ -242,7 +265,8 @@ struct ath_desc {
242#define ATH9K_TXDESC_EXT_AND_CTL 0x0080 265#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
243#define ATH9K_TXDESC_VMF 0x0100 266#define ATH9K_TXDESC_VMF 0x0100
244#define ATH9K_TXDESC_FRAG_IS_ON 0x0200 267#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
245#define ATH9K_TXDESC_CAB 0x0400 268#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
269#define ATH9K_TXDESC_LDPC 0x00010000
246 270
247#define ATH9K_RXDESC_INTREQ 0x0020 271#define ATH9K_RXDESC_INTREQ 0x0020
248 272
@@ -336,7 +360,6 @@ struct ar5416_desc {
336#define AR_DestIdxValid 0x40000000 360#define AR_DestIdxValid 0x40000000
337#define AR_CTSEnable 0x80000000 361#define AR_CTSEnable 0x80000000
338 362
339#define AR_BufLen 0x00000fff
340#define AR_TxMore 0x00001000 363#define AR_TxMore 0x00001000
341#define AR_DestIdx 0x000fe000 364#define AR_DestIdx 0x000fe000
342#define AR_DestIdx_S 13 365#define AR_DestIdx_S 13
@@ -393,6 +416,7 @@ struct ar5416_desc {
393#define AR_EncrType 0x0c000000 416#define AR_EncrType 0x0c000000
394#define AR_EncrType_S 26 417#define AR_EncrType_S 26
395#define AR_TxCtlRsvd61 0xf0000000 418#define AR_TxCtlRsvd61 0xf0000000
419#define AR_LDPC 0x80000000
396 420
397#define AR_2040_0 0x00000001 421#define AR_2040_0 0x00000001
398#define AR_GI0 0x00000002 422#define AR_GI0 0x00000002
@@ -412,7 +436,10 @@ struct ar5416_desc {
412#define AR_ChainSel3_S 17 436#define AR_ChainSel3_S 17
413#define AR_RTSCTSRate 0x0ff00000 437#define AR_RTSCTSRate 0x0ff00000
414#define AR_RTSCTSRate_S 20 438#define AR_RTSCTSRate_S 20
415#define AR_TxCtlRsvd70 0xf0000000 439#define AR_STBC0 0x10000000
440#define AR_STBC1 0x20000000
441#define AR_STBC2 0x40000000
442#define AR_STBC3 0x80000000
416 443
417#define AR_TxRSSIAnt00 0x000000ff 444#define AR_TxRSSIAnt00 0x000000ff
418#define AR_TxRSSIAnt00_S 0 445#define AR_TxRSSIAnt00_S 0
@@ -476,7 +503,6 @@ struct ar5416_desc {
476 503
477#define AR_RxCTLRsvd00 0xffffffff 504#define AR_RxCTLRsvd00 0xffffffff
478 505
479#define AR_BufLen 0x00000fff
480#define AR_RxCtlRsvd00 0x00001000 506#define AR_RxCtlRsvd00 0x00001000
481#define AR_RxIntrReq 0x00002000 507#define AR_RxIntrReq 0x00002000
482#define AR_RxCtlRsvd01 0xffffc000 508#define AR_RxCtlRsvd01 0xffffc000
@@ -626,6 +652,7 @@ enum ath9k_rx_filter {
626#define ATH9K_RATESERIES_RTS_CTS 0x0001 652#define ATH9K_RATESERIES_RTS_CTS 0x0001
627#define ATH9K_RATESERIES_2040 0x0002 653#define ATH9K_RATESERIES_2040 0x0002
628#define ATH9K_RATESERIES_HALFGI 0x0004 654#define ATH9K_RATESERIES_HALFGI 0x0004
655#define ATH9K_RATESERIES_STBC 0x0008
629 656
630struct ath9k_11n_rate_series { 657struct ath9k_11n_rate_series {
631 u32 Tries; 658 u32 Tries;
@@ -669,33 +696,10 @@ struct ath9k_channel;
669u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); 696u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
670void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); 697void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
671void ath9k_hw_txstart(struct ath_hw *ah, u32 q); 698void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
699void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
672u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); 700u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
673bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); 701bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
674bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); 702bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
675void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
676 u32 segLen, bool firstSeg,
677 bool lastSeg, const struct ath_desc *ds0);
678void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
679int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
680void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
681 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
682 u32 keyIx, enum ath9k_key_type keyType, u32 flags);
683void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
684 struct ath_desc *lastds,
685 u32 durUpdateEn, u32 rtsctsRate,
686 u32 rtsctsDuration,
687 struct ath9k_11n_rate_series series[],
688 u32 nseries, u32 flags);
689void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
690 u32 aggrLen);
691void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
692 u32 numDelims);
693void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
694void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
695void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
696 u32 burstDuration);
697void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
698 u32 vmf);
699void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); 703void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
700bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, 704bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
701 const struct ath9k_tx_queue_info *qinfo); 705 const struct ath9k_tx_queue_info *qinfo);
@@ -706,15 +710,22 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
706bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); 710bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
707bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); 711bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
708int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 712int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
709 u32 pa, struct ath_desc *nds, u64 tsf); 713 struct ath_rx_status *rs, u64 tsf);
710void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 714void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
711 u32 size, u32 flags); 715 u32 size, u32 flags);
712bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); 716bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
713void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); 717void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
714void ath9k_hw_rxena(struct ath_hw *ah);
715void ath9k_hw_startpcureceive(struct ath_hw *ah); 718void ath9k_hw_startpcureceive(struct ath_hw *ah);
716void ath9k_hw_stoppcurecv(struct ath_hw *ah); 719void ath9k_hw_stoppcurecv(struct ath_hw *ah);
720void ath9k_hw_abortpcurecv(struct ath_hw *ah);
717bool ath9k_hw_stopdmarecv(struct ath_hw *ah); 721bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
718int ath9k_hw_beaconq_setup(struct ath_hw *ah); 722int ath9k_hw_beaconq_setup(struct ath_hw *ah);
719 723
724/* Interrupt Handling */
725bool ath9k_hw_intrpend(struct ath_hw *ah);
726enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
727 enum ath9k_int ints);
728
729void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
730
720#endif /* MAC_H */ 731#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 115e1aeedb59..893b552981a0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -225,7 +225,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
225 225
226 ath_cache_conf_rate(sc, &hw->conf); 226 ath_cache_conf_rate(sc, &hw->conf);
227 ath_update_txpow(sc); 227 ath_update_txpow(sc);
228 ath9k_hw_set_interrupts(ah, sc->imask); 228 ath9k_hw_set_interrupts(ah, ah->imask);
229 229
230 ps_restore: 230 ps_restore:
231 ath9k_ps_restore(sc); 231 ath9k_ps_restore(sc);
@@ -401,23 +401,41 @@ void ath9k_tasklet(unsigned long data)
401 struct ath_common *common = ath9k_hw_common(ah); 401 struct ath_common *common = ath9k_hw_common(ah);
402 402
403 u32 status = sc->intrstatus; 403 u32 status = sc->intrstatus;
404 u32 rxmask;
404 405
405 ath9k_ps_wakeup(sc); 406 ath9k_ps_wakeup(sc);
406 407
407 if (status & ATH9K_INT_FATAL) { 408 if ((status & ATH9K_INT_FATAL) ||
409 !ath9k_hw_check_alive(ah)) {
408 ath_reset(sc, false); 410 ath_reset(sc, false);
409 ath9k_ps_restore(sc); 411 ath9k_ps_restore(sc);
410 return; 412 return;
411 } 413 }
412 414
413 if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { 415 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
416 rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
417 ATH9K_INT_RXORN);
418 else
419 rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
420
421 if (status & rxmask) {
414 spin_lock_bh(&sc->rx.rxflushlock); 422 spin_lock_bh(&sc->rx.rxflushlock);
415 ath_rx_tasklet(sc, 0); 423
424 /* Check for high priority Rx first */
425 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
426 (status & ATH9K_INT_RXHP))
427 ath_rx_tasklet(sc, 0, true);
428
429 ath_rx_tasklet(sc, 0, false);
416 spin_unlock_bh(&sc->rx.rxflushlock); 430 spin_unlock_bh(&sc->rx.rxflushlock);
417 } 431 }
418 432
419 if (status & ATH9K_INT_TX) 433 if (status & ATH9K_INT_TX) {
420 ath_tx_tasklet(sc); 434 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
435 ath_tx_edma_tasklet(sc);
436 else
437 ath_tx_tasklet(sc);
438 }
421 439
422 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { 440 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
423 /* 441 /*
@@ -434,7 +452,7 @@ void ath9k_tasklet(unsigned long data)
434 ath_gen_timer_isr(sc->sc_ah); 452 ath_gen_timer_isr(sc->sc_ah);
435 453
436 /* re-enable hardware interrupt */ 454 /* re-enable hardware interrupt */
437 ath9k_hw_set_interrupts(ah, sc->imask); 455 ath9k_hw_set_interrupts(ah, ah->imask);
438 ath9k_ps_restore(sc); 456 ath9k_ps_restore(sc);
439} 457}
440 458
@@ -445,6 +463,8 @@ irqreturn_t ath_isr(int irq, void *dev)
445 ATH9K_INT_RXORN | \ 463 ATH9K_INT_RXORN | \
446 ATH9K_INT_RXEOL | \ 464 ATH9K_INT_RXEOL | \
447 ATH9K_INT_RX | \ 465 ATH9K_INT_RX | \
466 ATH9K_INT_RXLP | \
467 ATH9K_INT_RXHP | \
448 ATH9K_INT_TX | \ 468 ATH9K_INT_TX | \
449 ATH9K_INT_BMISS | \ 469 ATH9K_INT_BMISS | \
450 ATH9K_INT_CST | \ 470 ATH9K_INT_CST | \
@@ -477,7 +497,7 @@ irqreturn_t ath_isr(int irq, void *dev)
477 * value to insure we only process bits we requested. 497 * value to insure we only process bits we requested.
478 */ 498 */
479 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ 499 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
480 status &= sc->imask; /* discard unasked-for bits */ 500 status &= ah->imask; /* discard unasked-for bits */
481 501
482 /* 502 /*
483 * If there are no status bits set, then this interrupt was not 503 * If there are no status bits set, then this interrupt was not
@@ -496,7 +516,8 @@ irqreturn_t ath_isr(int irq, void *dev)
496 * If a FATAL or RXORN interrupt is received, we have to reset the 516 * If a FATAL or RXORN interrupt is received, we have to reset the
497 * chip immediately. 517 * chip immediately.
498 */ 518 */
499 if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN)) 519 if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
520 !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
500 goto chip_reset; 521 goto chip_reset;
501 522
502 if (status & ATH9K_INT_SWBA) 523 if (status & ATH9K_INT_SWBA)
@@ -505,6 +526,13 @@ irqreturn_t ath_isr(int irq, void *dev)
505 if (status & ATH9K_INT_TXURN) 526 if (status & ATH9K_INT_TXURN)
506 ath9k_hw_updatetxtriglevel(ah, true); 527 ath9k_hw_updatetxtriglevel(ah, true);
507 528
529 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
530 if (status & ATH9K_INT_RXEOL) {
531 ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
532 ath9k_hw_set_interrupts(ah, ah->imask);
533 }
534 }
535
508 if (status & ATH9K_INT_MIB) { 536 if (status & ATH9K_INT_MIB) {
509 /* 537 /*
510 * Disable interrupts until we service the MIB 538 * Disable interrupts until we service the MIB
@@ -518,7 +546,7 @@ irqreturn_t ath_isr(int irq, void *dev)
518 * the interrupt. 546 * the interrupt.
519 */ 547 */
520 ath9k_hw_procmibevent(ah); 548 ath9k_hw_procmibevent(ah);
521 ath9k_hw_set_interrupts(ah, sc->imask); 549 ath9k_hw_set_interrupts(ah, ah->imask);
522 } 550 }
523 551
524 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 552 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
@@ -536,7 +564,7 @@ chip_reset:
536 564
537 if (sched) { 565 if (sched) {
538 /* turn off every interrupt except SWBA */ 566 /* turn off every interrupt except SWBA */
539 ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA)); 567 ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
540 tasklet_schedule(&sc->intr_tq); 568 tasklet_schedule(&sc->intr_tq);
541 } 569 }
542 570
@@ -724,6 +752,7 @@ static int ath_key_config(struct ath_common *common,
724 struct ath_hw *ah = common->ah; 752 struct ath_hw *ah = common->ah;
725 struct ath9k_keyval hk; 753 struct ath9k_keyval hk;
726 const u8 *mac = NULL; 754 const u8 *mac = NULL;
755 u8 gmac[ETH_ALEN];
727 int ret = 0; 756 int ret = 0;
728 int idx; 757 int idx;
729 758
@@ -747,9 +776,30 @@ static int ath_key_config(struct ath_common *common,
747 memcpy(hk.kv_val, key->key, key->keylen); 776 memcpy(hk.kv_val, key->key, key->keylen);
748 777
749 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { 778 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
750 /* For now, use the default keys for broadcast keys. This may 779
751 * need to change with virtual interfaces. */ 780 if (key->ap_addr) {
752 idx = key->keyidx; 781 /*
782 * Group keys on hardware that supports multicast frame
783 * key search use a mac that is the sender's address with
784 * the high bit set instead of the app-specified address.
785 */
786 memcpy(gmac, key->ap_addr, ETH_ALEN);
787 gmac[0] |= 0x80;
788 mac = gmac;
789
790 if (key->alg == ALG_TKIP)
791 idx = ath_reserve_key_cache_slot_tkip(common);
792 else
793 idx = ath_reserve_key_cache_slot(common);
794 if (idx < 0)
795 mac = NULL; /* no free key cache entries */
796 }
797
798 if (!mac) {
799 /* For now, use the default keys for broadcast keys. This may
800 * need to change with virtual interfaces. */
801 idx = key->keyidx;
802 }
753 } else if (key->keyidx) { 803 } else if (key->keyidx) {
754 if (WARN_ON(!sta)) 804 if (WARN_ON(!sta))
755 return -EOPNOTSUPP; 805 return -EOPNOTSUPP;
@@ -887,7 +937,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
887 ath_beacon_config(sc, NULL); /* restart beacons */ 937 ath_beacon_config(sc, NULL); /* restart beacons */
888 938
889 /* Re-Enable interrupts */ 939 /* Re-Enable interrupts */
890 ath9k_hw_set_interrupts(ah, sc->imask); 940 ath9k_hw_set_interrupts(ah, ah->imask);
891 941
892 /* Enable LED */ 942 /* Enable LED */
893 ath9k_hw_cfg_output(ah, ah->led_pin, 943 ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -977,7 +1027,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
977 if (sc->sc_flags & SC_OP_BEACONS) 1027 if (sc->sc_flags & SC_OP_BEACONS)
978 ath_beacon_config(sc, NULL); /* restart beacons */ 1028 ath_beacon_config(sc, NULL); /* restart beacons */
979 1029
980 ath9k_hw_set_interrupts(ah, sc->imask); 1030 ath9k_hw_set_interrupts(ah, ah->imask);
981 1031
982 if (retry_tx) { 1032 if (retry_tx) {
983 int i; 1033 int i;
@@ -1162,23 +1212,28 @@ static int ath9k_start(struct ieee80211_hw *hw)
1162 } 1212 }
1163 1213
1164 /* Setup our intr mask. */ 1214 /* Setup our intr mask. */
1165 sc->imask = ATH9K_INT_RX | ATH9K_INT_TX 1215 ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
1166 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN 1216 ATH9K_INT_RXORN | ATH9K_INT_FATAL |
1167 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; 1217 ATH9K_INT_GLOBAL;
1218
1219 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
1220 ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
1221 else
1222 ah->imask |= ATH9K_INT_RX;
1168 1223
1169 if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) 1224 if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
1170 sc->imask |= ATH9K_INT_GTT; 1225 ah->imask |= ATH9K_INT_GTT;
1171 1226
1172 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) 1227 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
1173 sc->imask |= ATH9K_INT_CST; 1228 ah->imask |= ATH9K_INT_CST;
1174 1229
1175 ath_cache_conf_rate(sc, &hw->conf); 1230 ath_cache_conf_rate(sc, &hw->conf);
1176 1231
1177 sc->sc_flags &= ~SC_OP_INVALID; 1232 sc->sc_flags &= ~SC_OP_INVALID;
1178 1233
1179 /* Disable BMISS interrupt when we're not associated */ 1234 /* Disable BMISS interrupt when we're not associated */
1180 sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 1235 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
1181 ath9k_hw_set_interrupts(ah, sc->imask); 1236 ath9k_hw_set_interrupts(ah, ah->imask);
1182 1237
1183 ieee80211_wake_queues(hw); 1238 ieee80211_wake_queues(hw);
1184 1239
@@ -1372,14 +1427,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1372{ 1427{
1373 struct ath_wiphy *aphy = hw->priv; 1428 struct ath_wiphy *aphy = hw->priv;
1374 struct ath_softc *sc = aphy->sc; 1429 struct ath_softc *sc = aphy->sc;
1375 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1430 struct ath_hw *ah = sc->sc_ah;
1431 struct ath_common *common = ath9k_hw_common(ah);
1376 struct ath_vif *avp = (void *)vif->drv_priv; 1432 struct ath_vif *avp = (void *)vif->drv_priv;
1377 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; 1433 enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
1378 int ret = 0; 1434 int ret = 0;
1379 1435
1380 mutex_lock(&sc->mutex); 1436 mutex_lock(&sc->mutex);
1381 1437
1382 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && 1438 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
1383 sc->nvifs > 0) { 1439 sc->nvifs > 0) {
1384 ret = -ENOBUFS; 1440 ret = -ENOBUFS;
1385 goto out; 1441 goto out;
@@ -1414,19 +1470,19 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1414 1470
1415 sc->nvifs++; 1471 sc->nvifs++;
1416 1472
1417 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 1473 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1418 ath9k_set_bssid_mask(hw); 1474 ath9k_set_bssid_mask(hw);
1419 1475
1420 if (sc->nvifs > 1) 1476 if (sc->nvifs > 1)
1421 goto out; /* skip global settings for secondary vif */ 1477 goto out; /* skip global settings for secondary vif */
1422 1478
1423 if (ic_opmode == NL80211_IFTYPE_AP) { 1479 if (ic_opmode == NL80211_IFTYPE_AP) {
1424 ath9k_hw_set_tsfadjust(sc->sc_ah, 1); 1480 ath9k_hw_set_tsfadjust(ah, 1);
1425 sc->sc_flags |= SC_OP_TSF_RESET; 1481 sc->sc_flags |= SC_OP_TSF_RESET;
1426 } 1482 }
1427 1483
1428 /* Set the device opmode */ 1484 /* Set the device opmode */
1429 sc->sc_ah->opmode = ic_opmode; 1485 ah->opmode = ic_opmode;
1430 1486
1431 /* 1487 /*
1432 * Enable MIB interrupts when there are hardware phy counters. 1488 * Enable MIB interrupts when there are hardware phy counters.
@@ -1435,11 +1491,12 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1435 if ((vif->type == NL80211_IFTYPE_STATION) || 1491 if ((vif->type == NL80211_IFTYPE_STATION) ||
1436 (vif->type == NL80211_IFTYPE_ADHOC) || 1492 (vif->type == NL80211_IFTYPE_ADHOC) ||
1437 (vif->type == NL80211_IFTYPE_MESH_POINT)) { 1493 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
1438 sc->imask |= ATH9K_INT_MIB; 1494 if (ah->config.enable_ani)
1439 sc->imask |= ATH9K_INT_TSFOOR; 1495 ah->imask |= ATH9K_INT_MIB;
1496 ah->imask |= ATH9K_INT_TSFOOR;
1440 } 1497 }
1441 1498
1442 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 1499 ath9k_hw_set_interrupts(ah, ah->imask);
1443 1500
1444 if (vif->type == NL80211_IFTYPE_AP || 1501 if (vif->type == NL80211_IFTYPE_AP ||
1445 vif->type == NL80211_IFTYPE_ADHOC || 1502 vif->type == NL80211_IFTYPE_ADHOC ||
@@ -1495,15 +1552,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1495 1552
1496void ath9k_enable_ps(struct ath_softc *sc) 1553void ath9k_enable_ps(struct ath_softc *sc)
1497{ 1554{
1555 struct ath_hw *ah = sc->sc_ah;
1556
1498 sc->ps_enabled = true; 1557 sc->ps_enabled = true;
1499 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 1558 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1500 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { 1559 if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
1501 sc->imask |= ATH9K_INT_TIM_TIMER; 1560 ah->imask |= ATH9K_INT_TIM_TIMER;
1502 ath9k_hw_set_interrupts(sc->sc_ah, 1561 ath9k_hw_set_interrupts(ah, ah->imask);
1503 sc->imask);
1504 } 1562 }
1505 } 1563 }
1506 ath9k_hw_setrxabort(sc->sc_ah, 1); 1564 ath9k_hw_setrxabort(ah, 1);
1507} 1565}
1508 1566
1509static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1567static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -1579,10 +1637,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1579 PS_WAIT_FOR_CAB | 1637 PS_WAIT_FOR_CAB |
1580 PS_WAIT_FOR_PSPOLL_DATA | 1638 PS_WAIT_FOR_PSPOLL_DATA |
1581 PS_WAIT_FOR_TX_ACK); 1639 PS_WAIT_FOR_TX_ACK);
1582 if (sc->imask & ATH9K_INT_TIM_TIMER) { 1640 if (ah->imask & ATH9K_INT_TIM_TIMER) {
1583 sc->imask &= ~ATH9K_INT_TIM_TIMER; 1641 ah->imask &= ~ATH9K_INT_TIM_TIMER;
1584 ath9k_hw_set_interrupts(sc->sc_ah, 1642 ath9k_hw_set_interrupts(sc->sc_ah,
1585 sc->imask); 1643 ah->imask);
1586 } 1644 }
1587 } 1645 }
1588 } 1646 }
@@ -1986,6 +2044,25 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1986 return ret; 2044 return ret;
1987} 2045}
1988 2046
2047static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
2048 struct survey_info *survey)
2049{
2050 struct ath_wiphy *aphy = hw->priv;
2051 struct ath_softc *sc = aphy->sc;
2052 struct ath_hw *ah = sc->sc_ah;
2053 struct ath_common *common = ath9k_hw_common(ah);
2054 struct ieee80211_conf *conf = &hw->conf;
2055
2056 if (idx != 0)
2057 return -ENOENT;
2058
2059 survey->channel = conf->channel;
2060 survey->filled = SURVEY_INFO_NOISE_DBM;
2061 survey->noise = common->ani.noise_floor;
2062
2063 return 0;
2064}
2065
1989static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2066static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
1990{ 2067{
1991 struct ath_wiphy *aphy = hw->priv; 2068 struct ath_wiphy *aphy = hw->priv;
@@ -2057,6 +2134,7 @@ struct ieee80211_ops ath9k_ops = {
2057 .set_tsf = ath9k_set_tsf, 2134 .set_tsf = ath9k_set_tsf,
2058 .reset_tsf = ath9k_reset_tsf, 2135 .reset_tsf = ath9k_reset_tsf,
2059 .ampdu_action = ath9k_ampdu_action, 2136 .ampdu_action = ath9k_ampdu_action,
2137 .get_survey = ath9k_get_survey,
2060 .sw_scan_start = ath9k_sw_scan_start, 2138 .sw_scan_start = ath9k_sw_scan_start,
2061 .sw_scan_complete = ath9k_sw_scan_complete, 2139 .sw_scan_complete = ath9k_sw_scan_complete,
2062 .rfkill_poll = ath9k_rfkill_poll_state, 2140 .rfkill_poll = ath9k_rfkill_poll_state,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 9441c6718a30..257b10ba6f57 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
31 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
31 { 0 } 32 { 0 }
32}; 33};
33 34
@@ -88,6 +89,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
88} 89}
89 90
90static const struct ath_bus_ops ath_pci_bus_ops = { 91static const struct ath_bus_ops ath_pci_bus_ops = {
92 .ath_bus_type = ATH_PCI,
91 .read_cachesize = ath_pci_read_cachesize, 93 .read_cachesize = ath_pci_read_cachesize,
92 .eeprom_read = ath_pci_eeprom_read, 94 .eeprom_read = ath_pci_eeprom_read,
93 .bt_coex_prep = ath_pci_bt_coex_prep, 95 .bt_coex_prep = ath_pci_bt_coex_prep,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
deleted file mode 100644
index 2547b3c4a26c..000000000000
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ /dev/null
@@ -1,978 +0,0 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/**
18 * DOC: Programming Atheros 802.11n analog front end radios
19 *
20 * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
21 * devices have either an external AR2133 analog front end radio for single
22 * band 2.4 GHz communication or an AR5133 analog front end radio for dual
23 * band 2.4 GHz / 5 GHz communication.
24 *
25 * All devices after the AR5416 and AR5418 family starting with the AR9280
26 * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
27 * into a single-chip and require less programming.
28 *
29 * The following single-chips exist with a respective embedded radio:
30 *
31 * AR9280 - 11n dual-band 2x2 MIMO for PCIe
32 * AR9281 - 11n single-band 1x2 MIMO for PCIe
33 * AR9285 - 11n single-band 1x1 for PCIe
34 * AR9287 - 11n single-band 2x2 MIMO for PCIe
35 *
36 * AR9220 - 11n dual-band 2x2 MIMO for PCI
37 * AR9223 - 11n single-band 2x2 MIMO for PCI
38 *
39 * AR9287 - 11n single-band 1x1 MIMO for USB
40 */
41
42#include <linux/slab.h>
43
44#include "hw.h"
45
46/**
47 * ath9k_hw_write_regs - ??
48 *
49 * @ah: atheros hardware structure
50 * @freqIndex:
51 * @regWrites:
52 *
53 * Used for both the chipsets with an external AR2133/AR5133 radios and
54 * single-chip devices.
55 */
56void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
57{
58 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
59}
60
61/**
62 * ath9k_hw_ar9280_set_channel - set channel on single-chip device
63 * @ah: atheros hardware structure
64 * @chan:
65 *
66 * This is the function to change channel on single-chip devices, that is
67 * all devices after ar9280.
68 *
69 * This function takes the channel value in MHz and sets
70 * hardware channel value. Assumes writes have been enabled to analog bus.
71 *
72 * Actual Expression,
73 *
74 * For 2GHz channel,
75 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
76 * (freq_ref = 40MHz)
77 *
78 * For 5GHz channel,
79 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
80 * (freq_ref = 40MHz/(24>>amodeRefSel))
81 */
82int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
83{
84 u16 bMode, fracMode, aModeRefSel = 0;
85 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
86 struct chan_centers centers;
87 u32 refDivA = 24;
88
89 ath9k_hw_get_channel_centers(ah, chan, &centers);
90 freq = centers.synth_center;
91
92 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
93 reg32 &= 0xc0000000;
94
95 if (freq < 4800) { /* 2 GHz, fractional mode */
96 u32 txctl;
97 int regWrites = 0;
98
99 bMode = 1;
100 fracMode = 1;
101 aModeRefSel = 0;
102 channelSel = (freq * 0x10000) / 15;
103
104 if (AR_SREV_9287_11_OR_LATER(ah)) {
105 if (freq == 2484) {
106 /* Enable channel spreading for channel 14 */
107 REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
108 1, regWrites);
109 } else {
110 REG_WRITE_ARRAY(&ah->iniCckfirNormal,
111 1, regWrites);
112 }
113 } else {
114 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
115 if (freq == 2484) {
116 /* Enable channel spreading for channel 14 */
117 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
118 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
119 } else {
120 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
121 txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
122 }
123 }
124 } else {
125 bMode = 0;
126 fracMode = 0;
127
128 switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
129 case 0:
130 if ((freq % 20) == 0) {
131 aModeRefSel = 3;
132 } else if ((freq % 10) == 0) {
133 aModeRefSel = 2;
134 }
135 if (aModeRefSel)
136 break;
137 case 1:
138 default:
139 aModeRefSel = 0;
140 /*
141 * Enable 2G (fractional) mode for channels
142 * which are 5MHz spaced.
143 */
144 fracMode = 1;
145 refDivA = 1;
146 channelSel = (freq * 0x8000) / 15;
147
148 /* RefDivA setting */
149 REG_RMW_FIELD(ah, AR_AN_SYNTH9,
150 AR_AN_SYNTH9_REFDIVA, refDivA);
151
152 }
153
154 if (!fracMode) {
155 ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
156 channelSel = ndiv & 0x1ff;
157 channelFrac = (ndiv & 0xfffffe00) * 2;
158 channelSel = (channelSel << 17) | channelFrac;
159 }
160 }
161
162 reg32 = reg32 |
163 (bMode << 29) |
164 (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
165
166 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
167
168 ah->curchan = chan;
169 ah->curchan_rad_index = -1;
170
171 return 0;
172}
173
174/**
175 * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
176 * @ah: atheros hardware structure
177 * @chan:
178 *
179 * For single-chip solutions. Converts to baseband spur frequency given the
180 * input channel frequency and compute register settings below.
181 */
182void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
183{
184 int bb_spur = AR_NO_SPUR;
185 int freq;
186 int bin, cur_bin;
187 int bb_spur_off, spur_subchannel_sd;
188 int spur_freq_sd;
189 int spur_delta_phase;
190 int denominator;
191 int upper, lower, cur_vit_mask;
192 int tmp, newVal;
193 int i;
194 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
195 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
196 };
197 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
198 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
199 };
200 int inc[4] = { 0, 100, 0, 0 };
201 struct chan_centers centers;
202
203 int8_t mask_m[123];
204 int8_t mask_p[123];
205 int8_t mask_amt;
206 int tmp_mask;
207 int cur_bb_spur;
208 bool is2GHz = IS_CHAN_2GHZ(chan);
209
210 memset(&mask_m, 0, sizeof(int8_t) * 123);
211 memset(&mask_p, 0, sizeof(int8_t) * 123);
212
213 ath9k_hw_get_channel_centers(ah, chan, &centers);
214 freq = centers.synth_center;
215
216 ah->config.spurmode = SPUR_ENABLE_EEPROM;
217 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
218 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
219
220 if (is2GHz)
221 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
222 else
223 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
224
225 if (AR_NO_SPUR == cur_bb_spur)
226 break;
227 cur_bb_spur = cur_bb_spur - freq;
228
229 if (IS_CHAN_HT40(chan)) {
230 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
231 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
232 bb_spur = cur_bb_spur;
233 break;
234 }
235 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
236 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
237 bb_spur = cur_bb_spur;
238 break;
239 }
240 }
241
242 if (AR_NO_SPUR == bb_spur) {
243 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
244 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
245 return;
246 } else {
247 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
248 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
249 }
250
251 bin = bb_spur * 320;
252
253 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
254
255 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
256 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
257 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
258 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
259 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
260
261 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
262 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
263 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
264 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
265 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
266 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
267
268 if (IS_CHAN_HT40(chan)) {
269 if (bb_spur < 0) {
270 spur_subchannel_sd = 1;
271 bb_spur_off = bb_spur + 10;
272 } else {
273 spur_subchannel_sd = 0;
274 bb_spur_off = bb_spur - 10;
275 }
276 } else {
277 spur_subchannel_sd = 0;
278 bb_spur_off = bb_spur;
279 }
280
281 if (IS_CHAN_HT40(chan))
282 spur_delta_phase =
283 ((bb_spur * 262144) /
284 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
285 else
286 spur_delta_phase =
287 ((bb_spur * 524288) /
288 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
289
290 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
291 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
292
293 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
294 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
295 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
296 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
297
298 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
299 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
300
301 cur_bin = -6000;
302 upper = bin + 100;
303 lower = bin - 100;
304
305 for (i = 0; i < 4; i++) {
306 int pilot_mask = 0;
307 int chan_mask = 0;
308 int bp = 0;
309 for (bp = 0; bp < 30; bp++) {
310 if ((cur_bin > lower) && (cur_bin < upper)) {
311 pilot_mask = pilot_mask | 0x1 << bp;
312 chan_mask = chan_mask | 0x1 << bp;
313 }
314 cur_bin += 100;
315 }
316 cur_bin += inc[i];
317 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
318 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
319 }
320
321 cur_vit_mask = 6100;
322 upper = bin + 120;
323 lower = bin - 120;
324
325 for (i = 0; i < 123; i++) {
326 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
327
328 /* workaround for gcc bug #37014 */
329 volatile int tmp_v = abs(cur_vit_mask - bin);
330
331 if (tmp_v < 75)
332 mask_amt = 1;
333 else
334 mask_amt = 0;
335 if (cur_vit_mask < 0)
336 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
337 else
338 mask_p[cur_vit_mask / 100] = mask_amt;
339 }
340 cur_vit_mask -= 100;
341 }
342
343 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
344 | (mask_m[48] << 26) | (mask_m[49] << 24)
345 | (mask_m[50] << 22) | (mask_m[51] << 20)
346 | (mask_m[52] << 18) | (mask_m[53] << 16)
347 | (mask_m[54] << 14) | (mask_m[55] << 12)
348 | (mask_m[56] << 10) | (mask_m[57] << 8)
349 | (mask_m[58] << 6) | (mask_m[59] << 4)
350 | (mask_m[60] << 2) | (mask_m[61] << 0);
351 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
352 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
353
354 tmp_mask = (mask_m[31] << 28)
355 | (mask_m[32] << 26) | (mask_m[33] << 24)
356 | (mask_m[34] << 22) | (mask_m[35] << 20)
357 | (mask_m[36] << 18) | (mask_m[37] << 16)
358 | (mask_m[48] << 14) | (mask_m[39] << 12)
359 | (mask_m[40] << 10) | (mask_m[41] << 8)
360 | (mask_m[42] << 6) | (mask_m[43] << 4)
361 | (mask_m[44] << 2) | (mask_m[45] << 0);
362 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
363 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
364
365 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
366 | (mask_m[18] << 26) | (mask_m[18] << 24)
367 | (mask_m[20] << 22) | (mask_m[20] << 20)
368 | (mask_m[22] << 18) | (mask_m[22] << 16)
369 | (mask_m[24] << 14) | (mask_m[24] << 12)
370 | (mask_m[25] << 10) | (mask_m[26] << 8)
371 | (mask_m[27] << 6) | (mask_m[28] << 4)
372 | (mask_m[29] << 2) | (mask_m[30] << 0);
373 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
374 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
375
376 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
377 | (mask_m[2] << 26) | (mask_m[3] << 24)
378 | (mask_m[4] << 22) | (mask_m[5] << 20)
379 | (mask_m[6] << 18) | (mask_m[7] << 16)
380 | (mask_m[8] << 14) | (mask_m[9] << 12)
381 | (mask_m[10] << 10) | (mask_m[11] << 8)
382 | (mask_m[12] << 6) | (mask_m[13] << 4)
383 | (mask_m[14] << 2) | (mask_m[15] << 0);
384 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
385 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
386
387 tmp_mask = (mask_p[15] << 28)
388 | (mask_p[14] << 26) | (mask_p[13] << 24)
389 | (mask_p[12] << 22) | (mask_p[11] << 20)
390 | (mask_p[10] << 18) | (mask_p[9] << 16)
391 | (mask_p[8] << 14) | (mask_p[7] << 12)
392 | (mask_p[6] << 10) | (mask_p[5] << 8)
393 | (mask_p[4] << 6) | (mask_p[3] << 4)
394 | (mask_p[2] << 2) | (mask_p[1] << 0);
395 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
396 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
397
398 tmp_mask = (mask_p[30] << 28)
399 | (mask_p[29] << 26) | (mask_p[28] << 24)
400 | (mask_p[27] << 22) | (mask_p[26] << 20)
401 | (mask_p[25] << 18) | (mask_p[24] << 16)
402 | (mask_p[23] << 14) | (mask_p[22] << 12)
403 | (mask_p[21] << 10) | (mask_p[20] << 8)
404 | (mask_p[19] << 6) | (mask_p[18] << 4)
405 | (mask_p[17] << 2) | (mask_p[16] << 0);
406 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
407 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
408
409 tmp_mask = (mask_p[45] << 28)
410 | (mask_p[44] << 26) | (mask_p[43] << 24)
411 | (mask_p[42] << 22) | (mask_p[41] << 20)
412 | (mask_p[40] << 18) | (mask_p[39] << 16)
413 | (mask_p[38] << 14) | (mask_p[37] << 12)
414 | (mask_p[36] << 10) | (mask_p[35] << 8)
415 | (mask_p[34] << 6) | (mask_p[33] << 4)
416 | (mask_p[32] << 2) | (mask_p[31] << 0);
417 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
418 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
419
420 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
421 | (mask_p[59] << 26) | (mask_p[58] << 24)
422 | (mask_p[57] << 22) | (mask_p[56] << 20)
423 | (mask_p[55] << 18) | (mask_p[54] << 16)
424 | (mask_p[53] << 14) | (mask_p[52] << 12)
425 | (mask_p[51] << 10) | (mask_p[50] << 8)
426 | (mask_p[49] << 6) | (mask_p[48] << 4)
427 | (mask_p[47] << 2) | (mask_p[46] << 0);
428 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
429 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
430}
431
432/* All code below is for non single-chip solutions */
433
434/**
435 * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
436 * @rfbuf:
437 * @reg32:
438 * @numBits:
439 * @firstBit:
440 * @column:
441 *
442 * Performs analog "swizzling" of parameters into their location.
443 * Used on external AR2133/AR5133 radios.
444 */
445static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
446 u32 numBits, u32 firstBit,
447 u32 column)
448{
449 u32 tmp32, mask, arrayEntry, lastBit;
450 int32_t bitPosition, bitsLeft;
451
452 tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
453 arrayEntry = (firstBit - 1) / 8;
454 bitPosition = (firstBit - 1) % 8;
455 bitsLeft = numBits;
456 while (bitsLeft > 0) {
457 lastBit = (bitPosition + bitsLeft > 8) ?
458 8 : bitPosition + bitsLeft;
459 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
460 (column * 8);
461 rfBuf[arrayEntry] &= ~mask;
462 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
463 (column * 8)) & mask;
464 bitsLeft -= 8 - bitPosition;
465 tmp32 = tmp32 >> (8 - bitPosition);
466 bitPosition = 0;
467 arrayEntry++;
468 }
469}
470
471/*
472 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
473 * rf_pwd_icsyndiv.
474 *
475 * Theoretical Rules:
476 * if 2 GHz band
477 * if forceBiasAuto
478 * if synth_freq < 2412
479 * bias = 0
480 * else if 2412 <= synth_freq <= 2422
481 * bias = 1
482 * else // synth_freq > 2422
483 * bias = 2
484 * else if forceBias > 0
485 * bias = forceBias & 7
486 * else
487 * no change, use value from ini file
488 * else
489 * no change, invalid band
490 *
491 * 1st Mod:
492 * 2422 also uses value of 2
493 * <approved>
494 *
495 * 2nd Mod:
496 * Less than 2412 uses value of 0, 2412 and above uses value of 2
497 */
498static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
499{
500 struct ath_common *common = ath9k_hw_common(ah);
501 u32 tmp_reg;
502 int reg_writes = 0;
503 u32 new_bias = 0;
504
505 if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
506 return;
507 }
508
509 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
510
511 if (synth_freq < 2412)
512 new_bias = 0;
513 else if (synth_freq < 2422)
514 new_bias = 1;
515 else
516 new_bias = 2;
517
518 /* pre-reverse this field */
519 tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
520
521 ath_print(common, ATH_DBG_CONFIG,
522 "Force rf_pwd_icsyndiv to %1d on %4d\n",
523 new_bias, synth_freq);
524
525 /* swizzle rf_pwd_icsyndiv */
526 ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
527
528 /* write Bank 6 with new params */
529 REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
530}
531
532/**
533 * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
534 * @ah: atheros hardware stucture
535 * @chan:
536 *
537 * For the external AR2133/AR5133 radios, takes the MHz channel value and set
538 * the channel value. Assumes writes enabled to analog bus and bank6 register
539 * cache in ah->analogBank6Data.
540 */
541int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
542{
543 struct ath_common *common = ath9k_hw_common(ah);
544 u32 channelSel = 0;
545 u32 bModeSynth = 0;
546 u32 aModeRefSel = 0;
547 u32 reg32 = 0;
548 u16 freq;
549 struct chan_centers centers;
550
551 ath9k_hw_get_channel_centers(ah, chan, &centers);
552 freq = centers.synth_center;
553
554 if (freq < 4800) {
555 u32 txctl;
556
557 if (((freq - 2192) % 5) == 0) {
558 channelSel = ((freq - 672) * 2 - 3040) / 10;
559 bModeSynth = 0;
560 } else if (((freq - 2224) % 5) == 0) {
561 channelSel = ((freq - 704) * 2 - 3040) / 10;
562 bModeSynth = 1;
563 } else {
564 ath_print(common, ATH_DBG_FATAL,
565 "Invalid channel %u MHz\n", freq);
566 return -EINVAL;
567 }
568
569 channelSel = (channelSel << 2) & 0xff;
570 channelSel = ath9k_hw_reverse_bits(channelSel, 8);
571
572 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
573 if (freq == 2484) {
574
575 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
576 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
577 } else {
578 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
579 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
580 }
581
582 } else if ((freq % 20) == 0 && freq >= 5120) {
583 channelSel =
584 ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
585 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
586 } else if ((freq % 10) == 0) {
587 channelSel =
588 ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
589 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
590 aModeRefSel = ath9k_hw_reverse_bits(2, 2);
591 else
592 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
593 } else if ((freq % 5) == 0) {
594 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
595 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
596 } else {
597 ath_print(common, ATH_DBG_FATAL,
598 "Invalid channel %u MHz\n", freq);
599 return -EINVAL;
600 }
601
602 ath9k_hw_force_bias(ah, freq);
603
604 reg32 =
605 (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
606 (1 << 5) | 0x1;
607
608 REG_WRITE(ah, AR_PHY(0x37), reg32);
609
610 ah->curchan = chan;
611 ah->curchan_rad_index = -1;
612
613 return 0;
614}
615
616/**
617 * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
618 * @ah: atheros hardware structure
619 * @chan:
620 *
621 * For non single-chip solutions. Converts to baseband spur frequency given the
622 * input channel frequency and compute register settings below.
623 */
624void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
625{
626 int bb_spur = AR_NO_SPUR;
627 int bin, cur_bin;
628 int spur_freq_sd;
629 int spur_delta_phase;
630 int denominator;
631 int upper, lower, cur_vit_mask;
632 int tmp, new;
633 int i;
634 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
635 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
636 };
637 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
638 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
639 };
640 int inc[4] = { 0, 100, 0, 0 };
641
642 int8_t mask_m[123];
643 int8_t mask_p[123];
644 int8_t mask_amt;
645 int tmp_mask;
646 int cur_bb_spur;
647 bool is2GHz = IS_CHAN_2GHZ(chan);
648
649 memset(&mask_m, 0, sizeof(int8_t) * 123);
650 memset(&mask_p, 0, sizeof(int8_t) * 123);
651
652 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
653 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
654 if (AR_NO_SPUR == cur_bb_spur)
655 break;
656 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
657 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
658 bb_spur = cur_bb_spur;
659 break;
660 }
661 }
662
663 if (AR_NO_SPUR == bb_spur)
664 return;
665
666 bin = bb_spur * 32;
667
668 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
669 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
670 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
671 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
672 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
673
674 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
675
676 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
677 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
678 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
679 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
680 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
681 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
682
683 spur_delta_phase = ((bb_spur * 524288) / 100) &
684 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
685
686 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
687 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
688
689 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
690 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
691 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
692 REG_WRITE(ah, AR_PHY_TIMING11, new);
693
694 cur_bin = -6000;
695 upper = bin + 100;
696 lower = bin - 100;
697
698 for (i = 0; i < 4; i++) {
699 int pilot_mask = 0;
700 int chan_mask = 0;
701 int bp = 0;
702 for (bp = 0; bp < 30; bp++) {
703 if ((cur_bin > lower) && (cur_bin < upper)) {
704 pilot_mask = pilot_mask | 0x1 << bp;
705 chan_mask = chan_mask | 0x1 << bp;
706 }
707 cur_bin += 100;
708 }
709 cur_bin += inc[i];
710 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
711 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
712 }
713
714 cur_vit_mask = 6100;
715 upper = bin + 120;
716 lower = bin - 120;
717
718 for (i = 0; i < 123; i++) {
719 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
720
721 /* workaround for gcc bug #37014 */
722 volatile int tmp_v = abs(cur_vit_mask - bin);
723
724 if (tmp_v < 75)
725 mask_amt = 1;
726 else
727 mask_amt = 0;
728 if (cur_vit_mask < 0)
729 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
730 else
731 mask_p[cur_vit_mask / 100] = mask_amt;
732 }
733 cur_vit_mask -= 100;
734 }
735
736 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
737 | (mask_m[48] << 26) | (mask_m[49] << 24)
738 | (mask_m[50] << 22) | (mask_m[51] << 20)
739 | (mask_m[52] << 18) | (mask_m[53] << 16)
740 | (mask_m[54] << 14) | (mask_m[55] << 12)
741 | (mask_m[56] << 10) | (mask_m[57] << 8)
742 | (mask_m[58] << 6) | (mask_m[59] << 4)
743 | (mask_m[60] << 2) | (mask_m[61] << 0);
744 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
745 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
746
747 tmp_mask = (mask_m[31] << 28)
748 | (mask_m[32] << 26) | (mask_m[33] << 24)
749 | (mask_m[34] << 22) | (mask_m[35] << 20)
750 | (mask_m[36] << 18) | (mask_m[37] << 16)
751 | (mask_m[48] << 14) | (mask_m[39] << 12)
752 | (mask_m[40] << 10) | (mask_m[41] << 8)
753 | (mask_m[42] << 6) | (mask_m[43] << 4)
754 | (mask_m[44] << 2) | (mask_m[45] << 0);
755 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
756 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
757
758 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
759 | (mask_m[18] << 26) | (mask_m[18] << 24)
760 | (mask_m[20] << 22) | (mask_m[20] << 20)
761 | (mask_m[22] << 18) | (mask_m[22] << 16)
762 | (mask_m[24] << 14) | (mask_m[24] << 12)
763 | (mask_m[25] << 10) | (mask_m[26] << 8)
764 | (mask_m[27] << 6) | (mask_m[28] << 4)
765 | (mask_m[29] << 2) | (mask_m[30] << 0);
766 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
767 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
768
769 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
770 | (mask_m[2] << 26) | (mask_m[3] << 24)
771 | (mask_m[4] << 22) | (mask_m[5] << 20)
772 | (mask_m[6] << 18) | (mask_m[7] << 16)
773 | (mask_m[8] << 14) | (mask_m[9] << 12)
774 | (mask_m[10] << 10) | (mask_m[11] << 8)
775 | (mask_m[12] << 6) | (mask_m[13] << 4)
776 | (mask_m[14] << 2) | (mask_m[15] << 0);
777 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
778 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
779
780 tmp_mask = (mask_p[15] << 28)
781 | (mask_p[14] << 26) | (mask_p[13] << 24)
782 | (mask_p[12] << 22) | (mask_p[11] << 20)
783 | (mask_p[10] << 18) | (mask_p[9] << 16)
784 | (mask_p[8] << 14) | (mask_p[7] << 12)
785 | (mask_p[6] << 10) | (mask_p[5] << 8)
786 | (mask_p[4] << 6) | (mask_p[3] << 4)
787 | (mask_p[2] << 2) | (mask_p[1] << 0);
788 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
789 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
790
791 tmp_mask = (mask_p[30] << 28)
792 | (mask_p[29] << 26) | (mask_p[28] << 24)
793 | (mask_p[27] << 22) | (mask_p[26] << 20)
794 | (mask_p[25] << 18) | (mask_p[24] << 16)
795 | (mask_p[23] << 14) | (mask_p[22] << 12)
796 | (mask_p[21] << 10) | (mask_p[20] << 8)
797 | (mask_p[19] << 6) | (mask_p[18] << 4)
798 | (mask_p[17] << 2) | (mask_p[16] << 0);
799 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
800 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
801
802 tmp_mask = (mask_p[45] << 28)
803 | (mask_p[44] << 26) | (mask_p[43] << 24)
804 | (mask_p[42] << 22) | (mask_p[41] << 20)
805 | (mask_p[40] << 18) | (mask_p[39] << 16)
806 | (mask_p[38] << 14) | (mask_p[37] << 12)
807 | (mask_p[36] << 10) | (mask_p[35] << 8)
808 | (mask_p[34] << 6) | (mask_p[33] << 4)
809 | (mask_p[32] << 2) | (mask_p[31] << 0);
810 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
811 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
812
813 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
814 | (mask_p[59] << 26) | (mask_p[58] << 24)
815 | (mask_p[57] << 22) | (mask_p[56] << 20)
816 | (mask_p[55] << 18) | (mask_p[54] << 16)
817 | (mask_p[53] << 14) | (mask_p[52] << 12)
818 | (mask_p[51] << 10) | (mask_p[50] << 8)
819 | (mask_p[49] << 6) | (mask_p[48] << 4)
820 | (mask_p[47] << 2) | (mask_p[46] << 0);
821 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
822 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
823}
824
825/**
826 * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
827 * @ah: atheros hardware structure
828 *
829 * Only required for older devices with external AR2133/AR5133 radios.
830 */
831int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
832{
833#define ATH_ALLOC_BANK(bank, size) do { \
834 bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
835 if (!bank) { \
836 ath_print(common, ATH_DBG_FATAL, \
837 "Cannot allocate RF banks\n"); \
838 return -ENOMEM; \
839 } \
840 } while (0);
841
842 struct ath_common *common = ath9k_hw_common(ah);
843
844 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
845
846 ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
847 ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
848 ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
849 ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
850 ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
851 ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
852 ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
853 ATH_ALLOC_BANK(ah->addac5416_21,
854 ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
855 ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
856
857 return 0;
858#undef ATH_ALLOC_BANK
859}
860
861
862/**
863 * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
864 * @ah: atheros hardware struture
865 * For the external AR2133/AR5133 radios banks.
866 */
867void
868ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
869{
870#define ATH_FREE_BANK(bank) do { \
871 kfree(bank); \
872 bank = NULL; \
873 } while (0);
874
875 BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
876
877 ATH_FREE_BANK(ah->analogBank0Data);
878 ATH_FREE_BANK(ah->analogBank1Data);
879 ATH_FREE_BANK(ah->analogBank2Data);
880 ATH_FREE_BANK(ah->analogBank3Data);
881 ATH_FREE_BANK(ah->analogBank6Data);
882 ATH_FREE_BANK(ah->analogBank6TPCData);
883 ATH_FREE_BANK(ah->analogBank7Data);
884 ATH_FREE_BANK(ah->addac5416_21);
885 ATH_FREE_BANK(ah->bank6Temp);
886
887#undef ATH_FREE_BANK
888}
889
890/* *
891 * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
892 * @ah: atheros hardware structure
893 * @chan:
894 * @modesIndex:
895 *
896 * Used for the external AR2133/AR5133 radios.
897 *
898 * Reads the EEPROM header info from the device structure and programs
899 * all rf registers. This routine requires access to the analog
900 * rf device. This is not required for single-chip devices.
901 */
902bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
903 u16 modesIndex)
904{
905 u32 eepMinorRev;
906 u32 ob5GHz = 0, db5GHz = 0;
907 u32 ob2GHz = 0, db2GHz = 0;
908 int regWrites = 0;
909
910 /*
911 * Software does not need to program bank data
912 * for single chip devices, that is AR9280 or anything
913 * after that.
914 */
915 if (AR_SREV_9280_10_OR_LATER(ah))
916 return true;
917
918 /* Setup rf parameters */
919 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
920
921 /* Setup Bank 0 Write */
922 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
923
924 /* Setup Bank 1 Write */
925 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
926
927 /* Setup Bank 2 Write */
928 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
929
930 /* Setup Bank 6 Write */
931 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
932 modesIndex);
933 {
934 int i;
935 for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
936 ah->analogBank6Data[i] =
937 INI_RA(&ah->iniBank6TPC, i, modesIndex);
938 }
939 }
940
941 /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
942 if (eepMinorRev >= 2) {
943 if (IS_CHAN_2GHZ(chan)) {
944 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
945 db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
946 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
947 ob2GHz, 3, 197, 0);
948 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
949 db2GHz, 3, 194, 0);
950 } else {
951 ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
952 db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
953 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
954 ob5GHz, 3, 203, 0);
955 ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
956 db5GHz, 3, 200, 0);
957 }
958 }
959
960 /* Setup Bank 7 Setup */
961 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
962
963 /* Write Analog registers */
964 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
965 regWrites);
966 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
967 regWrites);
968 REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
969 regWrites);
970 REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
971 regWrites);
972 REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
973 regWrites);
974 REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
975 regWrites);
976
977 return true;
978}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 0999a495fd46..e724c2c1ae2a 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,589 +17,25 @@
17#ifndef PHY_H 17#ifndef PHY_H
18#define PHY_H 18#define PHY_H
19 19
20/* Common between single chip and non single-chip solutions */ 20#define CHANSEL_DIV 15
21void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites); 21#define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV)
22 22#define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV)
23/* Single chip radio settings */
24int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
25void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
26
27/* Routines below are for non single-chip solutions */
28int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
29void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
30
31int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
32void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
33
34bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
35 struct ath9k_channel *chan,
36 u16 modesIndex);
37 23
38#define AR_PHY_BASE 0x9800 24#define AR_PHY_BASE 0x9800
39#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) 25#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
40 26
41#define AR_PHY_TEST 0x9800 27#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX 0x0007E000
42#define PHY_AGC_CLR 0x10000000 28#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
43#define RFSILENT_BB 0x00002000 29#define AR_PHY_TX_GAIN_CLC 0x0000001E
44 30#define AR_PHY_TX_GAIN_CLC_S 1
45#define AR_PHY_TURBO 0x9804 31#define AR_PHY_TX_GAIN 0x0007F000
46#define AR_PHY_FC_TURBO_MODE 0x00000001 32#define AR_PHY_TX_GAIN_S 12
47#define AR_PHY_FC_TURBO_SHORT 0x00000002
48#define AR_PHY_FC_DYN2040_EN 0x00000004
49#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
50#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
51/* For 25 MHz channel spacing -- not used but supported by hw */
52#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
53#define AR_PHY_FC_HT_EN 0x00000040
54#define AR_PHY_FC_SHORT_GI_40 0x00000080
55#define AR_PHY_FC_WALSH 0x00000100
56#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
57#define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800
58
59#define AR_PHY_TEST2 0x9808
60
61#define AR_PHY_TIMING2 0x9810
62#define AR_PHY_TIMING3 0x9814
63#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
64#define AR_PHY_TIMING3_DSC_MAN_S 17
65#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
66#define AR_PHY_TIMING3_DSC_EXP_S 13
67
68#define AR_PHY_CHIP_ID 0x9818
69#define AR_PHY_CHIP_ID_REV_0 0x80
70#define AR_PHY_CHIP_ID_REV_1 0x81
71#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
72
73#define AR_PHY_ACTIVE 0x981C
74#define AR_PHY_ACTIVE_EN 0x00000001
75#define AR_PHY_ACTIVE_DIS 0x00000000
76
77#define AR_PHY_RF_CTL2 0x9824
78#define AR_PHY_TX_END_DATA_START 0x000000FF
79#define AR_PHY_TX_END_DATA_START_S 0
80#define AR_PHY_TX_END_PA_ON 0x0000FF00
81#define AR_PHY_TX_END_PA_ON_S 8
82
83#define AR_PHY_RF_CTL3 0x9828
84#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
85#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
86
87#define AR_PHY_ADC_CTL 0x982C
88#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
89#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
90#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
91#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
92#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
93#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
94#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
95
96#define AR_PHY_ADC_SERIAL_CTL 0x9830
97#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
98#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
99
100#define AR_PHY_RF_CTL4 0x9834
101#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
102#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
103#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
104#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
105#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
106#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
107#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
108#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
109
110#define AR_PHY_TSTDAC_CONST 0x983c
111
112#define AR_PHY_SETTLING 0x9844
113#define AR_PHY_SETTLING_SWITCH 0x00003F80
114#define AR_PHY_SETTLING_SWITCH_S 7
115
116#define AR_PHY_RXGAIN 0x9848
117#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
118#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
119#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
120#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
121#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
122#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
123#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
124#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
125
126#define AR_PHY_DESIRED_SZ 0x9850
127#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
128#define AR_PHY_DESIRED_SZ_ADC_S 0
129#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
130#define AR_PHY_DESIRED_SZ_PGA_S 8
131#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
132#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
133
134#define AR_PHY_FIND_SIG 0x9858
135#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
136#define AR_PHY_FIND_SIG_FIRSTEP_S 12
137#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
138#define AR_PHY_FIND_SIG_FIRPWR_S 18
139
140#define AR_PHY_AGC_CTL1 0x985C
141#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
142#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
143#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
144#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
145
146#define AR_PHY_AGC_CONTROL 0x9860
147#define AR_PHY_AGC_CONTROL_CAL 0x00000001
148#define AR_PHY_AGC_CONTROL_NF 0x00000002
149#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
150#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
151#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
152
153#define AR_PHY_CCA 0x9864
154#define AR_PHY_MINCCA_PWR 0x0FF80000
155#define AR_PHY_MINCCA_PWR_S 19
156#define AR_PHY_CCA_THRESH62 0x0007F000
157#define AR_PHY_CCA_THRESH62_S 12
158#define AR9280_PHY_MINCCA_PWR 0x1FF00000
159#define AR9280_PHY_MINCCA_PWR_S 20
160#define AR9280_PHY_CCA_THRESH62 0x000FF000
161#define AR9280_PHY_CCA_THRESH62_S 12
162
163#define AR_PHY_SFCORR_LOW 0x986C
164#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
165#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
166#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
167#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
168#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
169#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
170#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
171
172#define AR_PHY_SFCORR 0x9868
173#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
174#define AR_PHY_SFCORR_M2COUNT_THR_S 0
175#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
176#define AR_PHY_SFCORR_M1_THRESH_S 17
177#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
178#define AR_PHY_SFCORR_M2_THRESH_S 24
179
180#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
181#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
182#define AR_PHY_SYNTH_CONTROL 0x9874
183#define AR_PHY_SLEEP_SCAL 0x9878
184
185#define AR_PHY_PLL_CTL 0x987c
186#define AR_PHY_PLL_CTL_40 0xaa
187#define AR_PHY_PLL_CTL_40_5413 0x04
188#define AR_PHY_PLL_CTL_44 0xab
189#define AR_PHY_PLL_CTL_44_2133 0xeb
190#define AR_PHY_PLL_CTL_40_2133 0xea
191
192#define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */
193#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1
194#define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */
195#define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */
196#define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/
197#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/
198#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/
199#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4
200#define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/
201#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
202#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
203#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
204#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
205#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/
206
207#define AR_PHY_RX_DELAY 0x9914
208#define AR_PHY_SEARCH_START_DELAY 0x9918
209#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
210
211#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
212#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
213#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
214#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
215#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
216#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
217#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
218#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
219#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
220
221#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
222#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
223#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
224#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
225
226#define AR_PHY_TIMING5 0x9924
227#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
228#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
229
230#define AR_PHY_POWER_TX_RATE1 0x9934
231#define AR_PHY_POWER_TX_RATE2 0x9938
232#define AR_PHY_POWER_TX_RATE_MAX 0x993c
233#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
234
235#define AR_PHY_FRAME_CTL 0x9944
236#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
237#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
238
239#define AR_PHY_TXPWRADJ 0x994C
240#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
241#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
242#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
243#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
244
245#define AR_PHY_RADAR_EXT 0x9940
246#define AR_PHY_RADAR_EXT_ENA 0x00004000
247
248#define AR_PHY_RADAR_0 0x9954
249#define AR_PHY_RADAR_0_ENA 0x00000001
250#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
251#define AR_PHY_RADAR_0_INBAND 0x0000003e
252#define AR_PHY_RADAR_0_INBAND_S 1
253#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
254#define AR_PHY_RADAR_0_PRSSI_S 6
255#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
256#define AR_PHY_RADAR_0_HEIGHT_S 12
257#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
258#define AR_PHY_RADAR_0_RRSSI_S 18
259#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
260#define AR_PHY_RADAR_0_FIRPWR_S 24
261
262#define AR_PHY_RADAR_1 0x9958
263#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
264#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
265#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
266#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
267#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
268#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
269#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
270#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
271#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
272#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
273#define AR_PHY_RADAR_1_MAXLEN_S 0
274
275#define AR_PHY_SWITCH_CHAIN_0 0x9960
276#define AR_PHY_SWITCH_COM 0x9964
277
278#define AR_PHY_SIGMA_DELTA 0x996C
279#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
280#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
281#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
282#define AR_PHY_SIGMA_DELTA_FILT2_S 3
283#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
284#define AR_PHY_SIGMA_DELTA_FILT1_S 8
285#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
286#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
287
288#define AR_PHY_RESTART 0x9970
289#define AR_PHY_RESTART_DIV_GC 0x001C0000
290#define AR_PHY_RESTART_DIV_GC_S 18
291
292#define AR_PHY_RFBUS_REQ 0x997C
293#define AR_PHY_RFBUS_REQ_EN 0x00000001
294
295#define AR_PHY_TIMING7 0x9980
296#define AR_PHY_TIMING8 0x9984
297#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
298#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
299
300#define AR_PHY_BIN_MASK2_1 0x9988
301#define AR_PHY_BIN_MASK2_2 0x998c
302#define AR_PHY_BIN_MASK2_3 0x9990
303#define AR_PHY_BIN_MASK2_4 0x9994
304
305#define AR_PHY_BIN_MASK_1 0x9900
306#define AR_PHY_BIN_MASK_2 0x9904
307#define AR_PHY_BIN_MASK_3 0x9908
308
309#define AR_PHY_MASK_CTL 0x990c
310
311#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
312#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
313
314#define AR_PHY_TIMING9 0x9998
315#define AR_PHY_TIMING10 0x999c
316#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
317#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
318
319#define AR_PHY_TIMING11 0x99a0
320#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
321#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
322#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
323#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
324#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
325#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
326
327#define AR_PHY_RX_CHAINMASK 0x99a4
328#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
329#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
330#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
331
332#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
333#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
334#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
335#define AR_PHY_9285_ANT_DIV_CTL_S 24
336#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
337#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
338#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
339#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
340#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
341#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
342#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
343#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
344#define AR_PHY_9285_ANT_DIV_LNA1 2
345#define AR_PHY_9285_ANT_DIV_LNA2 1
346#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
347#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
348#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
349#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
350 33
351#define AR_PHY_EXT_CCA0 0x99b8 34#define AR_PHY_CLC_TBL1 0xa35c
352#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF 35#define AR_PHY_CLC_I0 0x07ff0000
353#define AR_PHY_EXT_CCA0_THRESH62_S 0 36#define AR_PHY_CLC_I0_S 16
354 37#define AR_PHY_CLC_Q0 0x0000ffd0
355#define AR_PHY_EXT_CCA 0x99bc 38#define AR_PHY_CLC_Q0_S 5
356#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
357#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
358#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
359#define AR_PHY_EXT_CCA_THRESH62_S 16
360#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
361#define AR_PHY_EXT_MINCCA_PWR_S 23
362#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
363#define AR9280_PHY_EXT_MINCCA_PWR_S 16
364
365#define AR_PHY_SFCORR_EXT 0x99c0
366#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
367#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
368#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
369#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
370#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
371#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
372#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
373#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
374#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
375
376#define AR_PHY_HALFGI 0x99D0
377#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
378#define AR_PHY_HALFGI_DSC_MAN_S 4
379#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
380#define AR_PHY_HALFGI_DSC_EXP_S 0
381
382#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
383#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
384
385#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
386
387#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC
388#define AR_PHY_RIFS_INIT_DELAY 0x03ff0000
389
390#define AR_PHY_M_SLEEP 0x99f0
391#define AR_PHY_REFCLKDLY 0x99f4
392#define AR_PHY_REFCLKPD 0x99f8
393
394#define AR_PHY_CALMODE 0x99f0
395
396#define AR_PHY_CALMODE_IQ 0x00000000
397#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
398#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
399#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
400
401#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
402#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
403#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
404#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
405
406#define AR_PHY_CURRENT_RSSI 0x9c1c
407#define AR9280_PHY_CURRENT_RSSI 0x9c3c
408
409#define AR_PHY_RFBUS_GRANT 0x9C20
410#define AR_PHY_RFBUS_GRANT_EN 0x00000001
411
412#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
413#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
414
415#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
416
417#define AR_PHY_MODE 0xA200
418#define AR_PHY_MODE_ASYNCFIFO 0x80
419#define AR_PHY_MODE_AR2133 0x08
420#define AR_PHY_MODE_AR5111 0x00
421#define AR_PHY_MODE_AR5112 0x08
422#define AR_PHY_MODE_DYNAMIC 0x04
423#define AR_PHY_MODE_RF2GHZ 0x02
424#define AR_PHY_MODE_RF5GHZ 0x00
425#define AR_PHY_MODE_CCK 0x01
426#define AR_PHY_MODE_OFDM 0x00
427#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
428
429#define AR_PHY_CCK_TX_CTRL 0xA204
430#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
431#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
432#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
433
434#define AR_PHY_CCK_DETECT 0xA208
435#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
436#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
437/* [12:6] settling time for antenna switch */
438#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
439#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
440#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
441#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
442
443#define AR_PHY_GAIN_2GHZ 0xA20C
444#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
445#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
446#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
447#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
448#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
449#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
450
451#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
452#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
453#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
454#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
455#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
456#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
457#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
458#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
459
460#define AR_PHY_CCK_RXCTRL4 0xA21C
461#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
462#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
463
464#define AR_PHY_DAG_CTRLCCK 0xA228
465#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
466#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
467#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
468
469#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
470#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
471
472#define AR_PHY_POWER_TX_RATE3 0xA234
473#define AR_PHY_POWER_TX_RATE4 0xA238
474
475#define AR_PHY_SCRM_SEQ_XR 0xA23C
476#define AR_PHY_HEADER_DETECT_XR 0xA240
477#define AR_PHY_CHIRP_DETECTED_XR 0xA244
478#define AR_PHY_BLUETOOTH 0xA254
479
480#define AR_PHY_TPCRG1 0xA258
481#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
482#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
483
484#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
485#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
486#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
487#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
488#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
489#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
490
491#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
492#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
493
494#define AR_PHY_TX_PWRCTRL4 0xa264
495#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
496#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
497#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
498#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
499
500#define AR_PHY_TX_PWRCTRL6_0 0xa270
501#define AR_PHY_TX_PWRCTRL6_1 0xb270
502#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
503#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
504
505#define AR_PHY_TX_PWRCTRL7 0xa274
506#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
507#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
508
509#define AR_PHY_TX_PWRCTRL9 0xa27C
510#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
511#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
512#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
513#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
514
515#define AR_PHY_TX_GAIN_TBL1 0xa300
516#define AR_PHY_TX_GAIN 0x0007F000
517#define AR_PHY_TX_GAIN_S 12
518
519#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
520#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
521#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
522#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
523
524#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
525#define AR_PHY_MASK2_M_31_45 0xa3a4
526#define AR_PHY_MASK2_M_16_30 0xa3a8
527#define AR_PHY_MASK2_M_00_15 0xa3ac
528#define AR_PHY_MASK2_P_15_01 0xa3b8
529#define AR_PHY_MASK2_P_30_16 0xa3bc
530#define AR_PHY_MASK2_P_45_31 0xa3c0
531#define AR_PHY_MASK2_P_61_45 0xa3c4
532#define AR_PHY_SPUR_REG 0x994c
533
534#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
535#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
536
537#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
538#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
539#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
540#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
541#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
542#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
543
544#define AR_PHY_PILOT_MASK_01_30 0xa3b0
545#define AR_PHY_PILOT_MASK_31_60 0xa3b4
546
547#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
548#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
549
550#define AR_PHY_ANALOG_SWAP 0xa268
551#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
552
553#define AR_PHY_TPCRG5 0xA26C
554#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
555#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
556#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
557#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
558#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
559#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
560#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
561#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
562#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
563#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
564
565/* Carrier leak calibration control, do it after AGC calibration */
566#define AR_PHY_CL_CAL_CTL 0xA358
567#define AR_PHY_CL_CAL_ENABLE 0x00000002
568#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
569
570#define AR_PHY_POWER_TX_RATE5 0xA38C
571#define AR_PHY_POWER_TX_RATE6 0xA390
572
573#define AR_PHY_CAL_CHAINMASK 0xA39C
574
575#define AR_PHY_POWER_TX_SUB 0xA3C8
576#define AR_PHY_POWER_TX_RATE7 0xA3CC
577#define AR_PHY_POWER_TX_RATE8 0xA3D0
578#define AR_PHY_POWER_TX_RATE9 0xA3D4
579
580#define AR_PHY_XPA_CFG 0xA3D8
581#define AR_PHY_FORCE_XPA_CFG 0x000000001
582#define AR_PHY_FORCE_XPA_CFG_S 0
583
584#define AR_PHY_CH1_CCA 0xa864
585#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
586#define AR_PHY_CH1_MINCCA_PWR_S 19
587#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
588#define AR9280_PHY_CH1_MINCCA_PWR_S 20
589
590#define AR_PHY_CH2_CCA 0xb864
591#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
592#define AR_PHY_CH2_MINCCA_PWR_S 19
593
594#define AR_PHY_CH1_EXT_CCA 0xa9bc
595#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
596#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
597#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
598#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
599
600#define AR_PHY_CH2_EXT_CCA 0xb9bc
601#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
602#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
603 39
604#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ 40#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
605 int r; \ 41 int r; \
@@ -615,6 +51,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
615#define ANTSWAP_AB 0x0001 51#define ANTSWAP_AB 0x0001
616#define REDUCE_CHAIN_0 0x00000050 52#define REDUCE_CHAIN_0 0x00000050
617#define REDUCE_CHAIN_1 0x00000051 53#define REDUCE_CHAIN_1 0x00000051
54#define AR_PHY_CHIP_ID 0x9818
618 55
619#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ 56#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
620 int i; \ 57 int i; \
@@ -622,4 +59,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
622 (_bank)[i] = INI_RA((_iniarray), i, _col);; \ 59 (_bank)[i] = INI_RA((_iniarray), i, _col);; \
623 } while (0) 60 } while (0)
624 61
62#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
63#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
64
625#endif 65#endif
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 244e1c629177..8519452c95f1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -691,6 +691,19 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
691 rate_table = sc->cur_rate_table; 691 rate_table = sc->cur_rate_table;
692 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 692 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
693 693
694 /*
695 * If we're in HT mode and both us and our peer supports LDPC.
696 * We don't need to check our own device's capabilities as our own
697 * ht capabilities would have already been intersected with our peer's.
698 */
699 if (conf_is_ht(&sc->hw->conf) &&
700 (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
701 tx_info->flags |= IEEE80211_TX_CTL_LDPC;
702
703 if (conf_is_ht(&sc->hw->conf) &&
704 (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
705 tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
706
694 if (is_probe) { 707 if (is_probe) {
695 /* set one try for probe rates. For the 708 /* set one try for probe rates. For the
696 * probes don't enable rts */ 709 * probes don't enable rts */
@@ -1228,8 +1241,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1228 long_retry = rate->count - 1; 1241 long_retry = rate->count - 1;
1229 } 1242 }
1230 1243
1231 if (!priv_sta || !ieee80211_is_data(fc) || 1244 if (!priv_sta || !ieee80211_is_data(fc))
1232 !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) 1245 return;
1246
1247 /* This packet was aggregated but doesn't carry status info */
1248 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1249 !(tx_info->flags & IEEE80211_TX_STAT_AMPDU))
1233 return; 1250 return;
1234 1251
1235 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) 1252 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 4f6d6fd442f4..3d8d40cdc99e 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -110,8 +110,8 @@ struct ath_rate_table {
110 int rate_cnt; 110 int rate_cnt;
111 int mcs_start; 111 int mcs_start;
112 struct { 112 struct {
113 int valid; 113 u8 valid;
114 int valid_single_stream; 114 u8 valid_single_stream;
115 u8 phy; 115 u8 phy;
116 u32 ratekbps; 116 u32 ratekbps;
117 u32 user_ratekbps; 117 u32 user_ratekbps;
@@ -172,14 +172,13 @@ struct ath_rate_priv {
172 172
173#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) 173#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
174#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) 174#define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1)
175#define ATH_TX_INFO_UPDATE_RC (1 << 2)
176#define ATH_TX_INFO_XRETRY (1 << 3) 175#define ATH_TX_INFO_XRETRY (1 << 3)
177#define ATH_TX_INFO_UNDERRUN (1 << 4) 176#define ATH_TX_INFO_UNDERRUN (1 << 4)
178 177
179enum ath9k_internal_frame_type { 178enum ath9k_internal_frame_type {
180 ATH9K_NOT_INTERNAL, 179 ATH9K_IFT_NOT_INTERNAL,
181 ATH9K_INT_PAUSE, 180 ATH9K_IFT_PAUSE,
182 ATH9K_INT_UNPAUSE 181 ATH9K_IFT_UNPAUSE
183}; 182};
184 183
185int ath_rate_control_register(void); 184int ath_rate_control_register(void);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 1ca42e5148c8..ba139132c85f 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -15,6 +15,9 @@
15 */ 15 */
16 16
17#include "ath9k.h" 17#include "ath9k.h"
18#include "ar9003_mac.h"
19
20#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))
18 21
19static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, 22static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
20 struct ieee80211_hdr *hdr) 23 struct ieee80211_hdr *hdr)
@@ -115,56 +118,244 @@ static void ath_opmode_init(struct ath_softc *sc)
115 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); 118 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
116} 119}
117 120
118int ath_rx_init(struct ath_softc *sc, int nbufs) 121static bool ath_rx_edma_buf_link(struct ath_softc *sc,
122 enum ath9k_rx_qtype qtype)
119{ 123{
120 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 124 struct ath_hw *ah = sc->sc_ah;
125 struct ath_rx_edma *rx_edma;
121 struct sk_buff *skb; 126 struct sk_buff *skb;
122 struct ath_buf *bf; 127 struct ath_buf *bf;
123 int error = 0;
124 128
125 spin_lock_init(&sc->rx.rxflushlock); 129 rx_edma = &sc->rx.rx_edma[qtype];
126 sc->sc_flags &= ~SC_OP_RXFLUSH; 130 if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize)
127 spin_lock_init(&sc->rx.rxbuflock); 131 return false;
128 132
129 common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, 133 bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
130 min(common->cachelsz, (u16)64)); 134 list_del_init(&bf->list);
131 135
132 ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", 136 skb = bf->bf_mpdu;
133 common->cachelsz, common->rx_bufsize); 137
138 ATH_RXBUF_RESET(bf);
139 memset(skb->data, 0, ah->caps.rx_status_len);
140 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
141 ah->caps.rx_status_len, DMA_TO_DEVICE);
134 142
135 /* Initialize rx descriptors */ 143 SKB_CB_ATHBUF(skb) = bf;
144 ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
145 skb_queue_tail(&rx_edma->rx_fifo, skb);
136 146
137 error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, 147 return true;
138 "rx", nbufs, 1); 148}
139 if (error != 0) { 149
140 ath_print(common, ATH_DBG_FATAL, 150static void ath_rx_addbuffer_edma(struct ath_softc *sc,
141 "failed to allocate rx descriptors: %d\n", error); 151 enum ath9k_rx_qtype qtype, int size)
142 goto err; 152{
153 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
154 u32 nbuf = 0;
155
156 if (list_empty(&sc->rx.rxbuf)) {
157 ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
158 return;
143 } 159 }
144 160
161 while (!list_empty(&sc->rx.rxbuf)) {
162 nbuf++;
163
164 if (!ath_rx_edma_buf_link(sc, qtype))
165 break;
166
167 if (nbuf >= size)
168 break;
169 }
170}
171
172static void ath_rx_remove_buffer(struct ath_softc *sc,
173 enum ath9k_rx_qtype qtype)
174{
175 struct ath_buf *bf;
176 struct ath_rx_edma *rx_edma;
177 struct sk_buff *skb;
178
179 rx_edma = &sc->rx.rx_edma[qtype];
180
181 while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) {
182 bf = SKB_CB_ATHBUF(skb);
183 BUG_ON(!bf);
184 list_add_tail(&bf->list, &sc->rx.rxbuf);
185 }
186}
187
188static void ath_rx_edma_cleanup(struct ath_softc *sc)
189{
190 struct ath_buf *bf;
191
192 ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
193 ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
194
145 list_for_each_entry(bf, &sc->rx.rxbuf, list) { 195 list_for_each_entry(bf, &sc->rx.rxbuf, list) {
196 if (bf->bf_mpdu)
197 dev_kfree_skb_any(bf->bf_mpdu);
198 }
199
200 INIT_LIST_HEAD(&sc->rx.rxbuf);
201
202 kfree(sc->rx.rx_bufptr);
203 sc->rx.rx_bufptr = NULL;
204}
205
206static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
207{
208 skb_queue_head_init(&rx_edma->rx_fifo);
209 skb_queue_head_init(&rx_edma->rx_buffers);
210 rx_edma->rx_fifo_hwsize = size;
211}
212
213static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
214{
215 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
216 struct ath_hw *ah = sc->sc_ah;
217 struct sk_buff *skb;
218 struct ath_buf *bf;
219 int error = 0, i;
220 u32 size;
221
222
223 common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
224 ah->caps.rx_status_len,
225 min(common->cachelsz, (u16)64));
226
227 ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
228 ah->caps.rx_status_len);
229
230 ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_LP],
231 ah->caps.rx_lp_qdepth);
232 ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP],
233 ah->caps.rx_hp_qdepth);
234
235 size = sizeof(struct ath_buf) * nbufs;
236 bf = kzalloc(size, GFP_KERNEL);
237 if (!bf)
238 return -ENOMEM;
239
240 INIT_LIST_HEAD(&sc->rx.rxbuf);
241 sc->rx.rx_bufptr = bf;
242
243 for (i = 0; i < nbufs; i++, bf++) {
146 skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); 244 skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL);
147 if (skb == NULL) { 245 if (!skb) {
148 error = -ENOMEM; 246 error = -ENOMEM;
149 goto err; 247 goto rx_init_fail;
150 } 248 }
151 249
250 memset(skb->data, 0, common->rx_bufsize);
152 bf->bf_mpdu = skb; 251 bf->bf_mpdu = skb;
252
153 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, 253 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
154 common->rx_bufsize, 254 common->rx_bufsize,
155 DMA_FROM_DEVICE); 255 DMA_BIDIRECTIONAL);
156 if (unlikely(dma_mapping_error(sc->dev, 256 if (unlikely(dma_mapping_error(sc->dev,
157 bf->bf_buf_addr))) { 257 bf->bf_buf_addr))) {
158 dev_kfree_skb_any(skb); 258 dev_kfree_skb_any(skb);
159 bf->bf_mpdu = NULL; 259 bf->bf_mpdu = NULL;
260 ath_print(common, ATH_DBG_FATAL,
261 "dma_mapping_error() on RX init\n");
262 error = -ENOMEM;
263 goto rx_init_fail;
264 }
265
266 list_add_tail(&bf->list, &sc->rx.rxbuf);
267 }
268
269 return 0;
270
271rx_init_fail:
272 ath_rx_edma_cleanup(sc);
273 return error;
274}
275
276static void ath_edma_start_recv(struct ath_softc *sc)
277{
278 spin_lock_bh(&sc->rx.rxbuflock);
279
280 ath9k_hw_rxena(sc->sc_ah);
281
282 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
283 sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize);
284
285 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP,
286 sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize);
287
288 spin_unlock_bh(&sc->rx.rxbuflock);
289
290 ath_opmode_init(sc);
291
292 ath9k_hw_startpcureceive(sc->sc_ah);
293}
294
295static void ath_edma_stop_recv(struct ath_softc *sc)
296{
297 spin_lock_bh(&sc->rx.rxbuflock);
298 ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
299 ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
300 spin_unlock_bh(&sc->rx.rxbuflock);
301}
302
303int ath_rx_init(struct ath_softc *sc, int nbufs)
304{
305 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
306 struct sk_buff *skb;
307 struct ath_buf *bf;
308 int error = 0;
309
310 spin_lock_init(&sc->rx.rxflushlock);
311 sc->sc_flags &= ~SC_OP_RXFLUSH;
312 spin_lock_init(&sc->rx.rxbuflock);
313
314 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
315 return ath_rx_edma_init(sc, nbufs);
316 } else {
317 common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
318 min(common->cachelsz, (u16)64));
319
320 ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
321 common->cachelsz, common->rx_bufsize);
322
323 /* Initialize rx descriptors */
324
325 error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
326 "rx", nbufs, 1, 0);
327 if (error != 0) {
160 ath_print(common, ATH_DBG_FATAL, 328 ath_print(common, ATH_DBG_FATAL,
161 "dma_mapping_error() on RX init\n"); 329 "failed to allocate rx descriptors: %d\n",
162 error = -ENOMEM; 330 error);
163 goto err; 331 goto err;
164 } 332 }
165 bf->bf_dmacontext = bf->bf_buf_addr; 333
334 list_for_each_entry(bf, &sc->rx.rxbuf, list) {
335 skb = ath_rxbuf_alloc(common, common->rx_bufsize,
336 GFP_KERNEL);
337 if (skb == NULL) {
338 error = -ENOMEM;
339 goto err;
340 }
341
342 bf->bf_mpdu = skb;
343 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
344 common->rx_bufsize,
345 DMA_FROM_DEVICE);
346 if (unlikely(dma_mapping_error(sc->dev,
347 bf->bf_buf_addr))) {
348 dev_kfree_skb_any(skb);
349 bf->bf_mpdu = NULL;
350 ath_print(common, ATH_DBG_FATAL,
351 "dma_mapping_error() on RX init\n");
352 error = -ENOMEM;
353 goto err;
354 }
355 bf->bf_dmacontext = bf->bf_buf_addr;
356 }
357 sc->rx.rxlink = NULL;
166 } 358 }
167 sc->rx.rxlink = NULL;
168 359
169err: 360err:
170 if (error) 361 if (error)
@@ -180,17 +371,23 @@ void ath_rx_cleanup(struct ath_softc *sc)
180 struct sk_buff *skb; 371 struct sk_buff *skb;
181 struct ath_buf *bf; 372 struct ath_buf *bf;
182 373
183 list_for_each_entry(bf, &sc->rx.rxbuf, list) { 374 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
184 skb = bf->bf_mpdu; 375 ath_rx_edma_cleanup(sc);
185 if (skb) { 376 return;
186 dma_unmap_single(sc->dev, bf->bf_buf_addr, 377 } else {
187 common->rx_bufsize, DMA_FROM_DEVICE); 378 list_for_each_entry(bf, &sc->rx.rxbuf, list) {
188 dev_kfree_skb(skb); 379 skb = bf->bf_mpdu;
380 if (skb) {
381 dma_unmap_single(sc->dev, bf->bf_buf_addr,
382 common->rx_bufsize,
383 DMA_FROM_DEVICE);
384 dev_kfree_skb(skb);
385 }
189 } 386 }
190 }
191 387
192 if (sc->rx.rxdma.dd_desc_len != 0) 388 if (sc->rx.rxdma.dd_desc_len != 0)
193 ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); 389 ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
390 }
194} 391}
195 392
196/* 393/*
@@ -273,6 +470,11 @@ int ath_startrecv(struct ath_softc *sc)
273 struct ath_hw *ah = sc->sc_ah; 470 struct ath_hw *ah = sc->sc_ah;
274 struct ath_buf *bf, *tbf; 471 struct ath_buf *bf, *tbf;
275 472
473 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
474 ath_edma_start_recv(sc);
475 return 0;
476 }
477
276 spin_lock_bh(&sc->rx.rxbuflock); 478 spin_lock_bh(&sc->rx.rxbuflock);
277 if (list_empty(&sc->rx.rxbuf)) 479 if (list_empty(&sc->rx.rxbuf))
278 goto start_recv; 480 goto start_recv;
@@ -306,7 +508,11 @@ bool ath_stoprecv(struct ath_softc *sc)
306 ath9k_hw_stoppcurecv(ah); 508 ath9k_hw_stoppcurecv(ah);
307 ath9k_hw_setrxfilter(ah, 0); 509 ath9k_hw_setrxfilter(ah, 0);
308 stopped = ath9k_hw_stopdmarecv(ah); 510 stopped = ath9k_hw_stopdmarecv(ah);
309 sc->rx.rxlink = NULL; 511
512 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
513 ath_edma_stop_recv(sc);
514 else
515 sc->rx.rxlink = NULL;
310 516
311 return stopped; 517 return stopped;
312} 518}
@@ -315,7 +521,9 @@ void ath_flushrecv(struct ath_softc *sc)
315{ 521{
316 spin_lock_bh(&sc->rx.rxflushlock); 522 spin_lock_bh(&sc->rx.rxflushlock);
317 sc->sc_flags |= SC_OP_RXFLUSH; 523 sc->sc_flags |= SC_OP_RXFLUSH;
318 ath_rx_tasklet(sc, 1); 524 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
525 ath_rx_tasklet(sc, 1, true);
526 ath_rx_tasklet(sc, 1, false);
319 sc->sc_flags &= ~SC_OP_RXFLUSH; 527 sc->sc_flags &= ~SC_OP_RXFLUSH;
320 spin_unlock_bh(&sc->rx.rxflushlock); 528 spin_unlock_bh(&sc->rx.rxflushlock);
321} 529}
@@ -469,15 +677,148 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
469 ieee80211_rx(hw, skb); 677 ieee80211_rx(hw, skb);
470} 678}
471 679
472int ath_rx_tasklet(struct ath_softc *sc, int flush) 680static bool ath_edma_get_buffers(struct ath_softc *sc,
681 enum ath9k_rx_qtype qtype)
473{ 682{
474#define PA2DESC(_sc, _pa) \ 683 struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
475 ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \ 684 struct ath_hw *ah = sc->sc_ah;
476 ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr))) 685 struct ath_common *common = ath9k_hw_common(ah);
686 struct sk_buff *skb;
687 struct ath_buf *bf;
688 int ret;
689
690 skb = skb_peek(&rx_edma->rx_fifo);
691 if (!skb)
692 return false;
693
694 bf = SKB_CB_ATHBUF(skb);
695 BUG_ON(!bf);
696
697 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
698 common->rx_bufsize, DMA_FROM_DEVICE);
699
700 ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
701 if (ret == -EINPROGRESS)
702 return false;
703
704 __skb_unlink(skb, &rx_edma->rx_fifo);
705 if (ret == -EINVAL) {
706 /* corrupt descriptor, skip this one and the following one */
707 list_add_tail(&bf->list, &sc->rx.rxbuf);
708 ath_rx_edma_buf_link(sc, qtype);
709 skb = skb_peek(&rx_edma->rx_fifo);
710 if (!skb)
711 return true;
712
713 bf = SKB_CB_ATHBUF(skb);
714 BUG_ON(!bf);
715
716 __skb_unlink(skb, &rx_edma->rx_fifo);
717 list_add_tail(&bf->list, &sc->rx.rxbuf);
718 ath_rx_edma_buf_link(sc, qtype);
719 return true;
720 }
721 skb_queue_tail(&rx_edma->rx_buffers, skb);
722
723 return true;
724}
477 725
726static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
727 struct ath_rx_status *rs,
728 enum ath9k_rx_qtype qtype)
729{
730 struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
731 struct sk_buff *skb;
478 struct ath_buf *bf; 732 struct ath_buf *bf;
733
734 while (ath_edma_get_buffers(sc, qtype));
735 skb = __skb_dequeue(&rx_edma->rx_buffers);
736 if (!skb)
737 return NULL;
738
739 bf = SKB_CB_ATHBUF(skb);
740 ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
741 return bf;
742}
743
744static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
745 struct ath_rx_status *rs)
746{
747 struct ath_hw *ah = sc->sc_ah;
748 struct ath_common *common = ath9k_hw_common(ah);
479 struct ath_desc *ds; 749 struct ath_desc *ds;
480 struct ath_rx_status *rx_stats; 750 struct ath_buf *bf;
751 int ret;
752
753 if (list_empty(&sc->rx.rxbuf)) {
754 sc->rx.rxlink = NULL;
755 return NULL;
756 }
757
758 bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
759 ds = bf->bf_desc;
760
761 /*
762 * Must provide the virtual address of the current
763 * descriptor, the physical address, and the virtual
764 * address of the next descriptor in the h/w chain.
765 * This allows the HAL to look ahead to see if the
766 * hardware is done with a descriptor by checking the
767 * done bit in the following descriptor and the address
768 * of the current descriptor the DMA engine is working
769 * on. All this is necessary because of our use of
770 * a self-linked list to avoid rx overruns.
771 */
772 ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
773 if (ret == -EINPROGRESS) {
774 struct ath_rx_status trs;
775 struct ath_buf *tbf;
776 struct ath_desc *tds;
777
778 memset(&trs, 0, sizeof(trs));
779 if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
780 sc->rx.rxlink = NULL;
781 return NULL;
782 }
783
784 tbf = list_entry(bf->list.next, struct ath_buf, list);
785
786 /*
787 * On some hardware the descriptor status words could
788 * get corrupted, including the done bit. Because of
789 * this, check if the next descriptor's done bit is
790 * set or not.
791 *
792 * If the next descriptor's done bit is set, the current
793 * descriptor has been corrupted. Force s/w to discard
794 * this descriptor and continue...
795 */
796
797 tds = tbf->bf_desc;
798 ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
799 if (ret == -EINPROGRESS)
800 return NULL;
801 }
802
803 if (!bf->bf_mpdu)
804 return bf;
805
806 /*
807 * Synchronize the DMA transfer with CPU before
808 * 1. accessing the frame
809 * 2. requeueing the same buffer to h/w
810 */
811 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
812 common->rx_bufsize,
813 DMA_FROM_DEVICE);
814
815 return bf;
816}
817
818
819int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
820{
821 struct ath_buf *bf;
481 struct sk_buff *skb = NULL, *requeue_skb; 822 struct sk_buff *skb = NULL, *requeue_skb;
482 struct ieee80211_rx_status *rxs; 823 struct ieee80211_rx_status *rxs;
483 struct ath_hw *ah = sc->sc_ah; 824 struct ath_hw *ah = sc->sc_ah;
@@ -491,7 +832,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
491 struct ieee80211_hdr *hdr; 832 struct ieee80211_hdr *hdr;
492 int retval; 833 int retval;
493 bool decrypt_error = false; 834 bool decrypt_error = false;
835 struct ath_rx_status rs;
836 enum ath9k_rx_qtype qtype;
837 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
838 int dma_type;
494 839
840 if (edma)
841 dma_type = DMA_FROM_DEVICE;
842 else
843 dma_type = DMA_BIDIRECTIONAL;
844
845 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
495 spin_lock_bh(&sc->rx.rxbuflock); 846 spin_lock_bh(&sc->rx.rxbuflock);
496 847
497 do { 848 do {
@@ -499,79 +850,25 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
499 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) 850 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
500 break; 851 break;
501 852
502 if (list_empty(&sc->rx.rxbuf)) { 853 memset(&rs, 0, sizeof(rs));
503 sc->rx.rxlink = NULL; 854 if (edma)
504 break; 855 bf = ath_edma_get_next_rx_buf(sc, &rs, qtype);
505 } 856 else
506 857 bf = ath_get_next_rx_buf(sc, &rs);
507 bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
508 ds = bf->bf_desc;
509
510 /*
511 * Must provide the virtual address of the current
512 * descriptor, the physical address, and the virtual
513 * address of the next descriptor in the h/w chain.
514 * This allows the HAL to look ahead to see if the
515 * hardware is done with a descriptor by checking the
516 * done bit in the following descriptor and the address
517 * of the current descriptor the DMA engine is working
518 * on. All this is necessary because of our use of
519 * a self-linked list to avoid rx overruns.
520 */
521 retval = ath9k_hw_rxprocdesc(ah, ds,
522 bf->bf_daddr,
523 PA2DESC(sc, ds->ds_link),
524 0);
525 if (retval == -EINPROGRESS) {
526 struct ath_buf *tbf;
527 struct ath_desc *tds;
528
529 if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
530 sc->rx.rxlink = NULL;
531 break;
532 }
533 858
534 tbf = list_entry(bf->list.next, struct ath_buf, list); 859 if (!bf)
535 860 break;
536 /*
537 * On some hardware the descriptor status words could
538 * get corrupted, including the done bit. Because of
539 * this, check if the next descriptor's done bit is
540 * set or not.
541 *
542 * If the next descriptor's done bit is set, the current
543 * descriptor has been corrupted. Force s/w to discard
544 * this descriptor and continue...
545 */
546
547 tds = tbf->bf_desc;
548 retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
549 PA2DESC(sc, tds->ds_link), 0);
550 if (retval == -EINPROGRESS) {
551 break;
552 }
553 }
554 861
555 skb = bf->bf_mpdu; 862 skb = bf->bf_mpdu;
556 if (!skb) 863 if (!skb)
557 continue; 864 continue;
558 865
559 /*
560 * Synchronize the DMA transfer with CPU before
561 * 1. accessing the frame
562 * 2. requeueing the same buffer to h/w
563 */
564 dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
565 common->rx_bufsize,
566 DMA_FROM_DEVICE);
567
568 hdr = (struct ieee80211_hdr *) skb->data; 866 hdr = (struct ieee80211_hdr *) skb->data;
569 rxs = IEEE80211_SKB_RXCB(skb); 867 rxs = IEEE80211_SKB_RXCB(skb);
570 868
571 hw = ath_get_virt_hw(sc, hdr); 869 hw = ath_get_virt_hw(sc, hdr);
572 rx_stats = &ds->ds_rxstat;
573 870
574 ath_debug_stat_rx(sc, bf); 871 ath_debug_stat_rx(sc, &rs);
575 872
576 /* 873 /*
577 * If we're asked to flush receive queue, directly 874 * If we're asked to flush receive queue, directly
@@ -580,7 +877,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
580 if (flush) 877 if (flush)
581 goto requeue; 878 goto requeue;
582 879
583 retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, rx_stats, 880 retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs,
584 rxs, &decrypt_error); 881 rxs, &decrypt_error);
585 if (retval) 882 if (retval)
586 goto requeue; 883 goto requeue;
@@ -599,18 +896,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
599 /* Unmap the frame */ 896 /* Unmap the frame */
600 dma_unmap_single(sc->dev, bf->bf_buf_addr, 897 dma_unmap_single(sc->dev, bf->bf_buf_addr,
601 common->rx_bufsize, 898 common->rx_bufsize,
602 DMA_FROM_DEVICE); 899 dma_type);
603 900
604 skb_put(skb, rx_stats->rs_datalen); 901 skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len);
902 if (ah->caps.rx_status_len)
903 skb_pull(skb, ah->caps.rx_status_len);
605 904
606 ath9k_cmn_rx_skb_postprocess(common, skb, rx_stats, 905 ath9k_cmn_rx_skb_postprocess(common, skb, &rs,
607 rxs, decrypt_error); 906 rxs, decrypt_error);
608 907
609 /* We will now give hardware our shiny new allocated skb */ 908 /* We will now give hardware our shiny new allocated skb */
610 bf->bf_mpdu = requeue_skb; 909 bf->bf_mpdu = requeue_skb;
611 bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, 910 bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
612 common->rx_bufsize, 911 common->rx_bufsize,
613 DMA_FROM_DEVICE); 912 dma_type);
614 if (unlikely(dma_mapping_error(sc->dev, 913 if (unlikely(dma_mapping_error(sc->dev,
615 bf->bf_buf_addr))) { 914 bf->bf_buf_addr))) {
616 dev_kfree_skb_any(requeue_skb); 915 dev_kfree_skb_any(requeue_skb);
@@ -626,9 +925,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
626 * change the default rx antenna if rx diversity chooses the 925 * change the default rx antenna if rx diversity chooses the
627 * other antenna 3 times in a row. 926 * other antenna 3 times in a row.
628 */ 927 */
629 if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { 928 if (sc->rx.defant != rs.rs_antenna) {
630 if (++sc->rx.rxotherant >= 3) 929 if (++sc->rx.rxotherant >= 3)
631 ath_setdefantenna(sc, rx_stats->rs_antenna); 930 ath_setdefantenna(sc, rs.rs_antenna);
632 } else { 931 } else {
633 sc->rx.rxotherant = 0; 932 sc->rx.rxotherant = 0;
634 } 933 }
@@ -641,12 +940,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
641 ath_rx_send_to_mac80211(hw, sc, skb, rxs); 940 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
642 941
643requeue: 942requeue:
644 list_move_tail(&bf->list, &sc->rx.rxbuf); 943 if (edma) {
645 ath_rx_buf_link(sc, bf); 944 list_add_tail(&bf->list, &sc->rx.rxbuf);
945 ath_rx_edma_buf_link(sc, qtype);
946 } else {
947 list_move_tail(&bf->list, &sc->rx.rxbuf);
948 ath_rx_buf_link(sc, bf);
949 }
646 } while (1); 950 } while (1);
647 951
648 spin_unlock_bh(&sc->rx.rxbuflock); 952 spin_unlock_bh(&sc->rx.rxbuflock);
649 953
650 return 0; 954 return 0;
651#undef PA2DESC
652} 955}
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 72cfa8ebd9ae..d4371a43bdaa 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -20,7 +20,7 @@
20#include "../reg.h" 20#include "../reg.h"
21 21
22#define AR_CR 0x0008 22#define AR_CR 0x0008
23#define AR_CR_RXE 0x00000004 23#define AR_CR_RXE (AR_SREV_9300_20_OR_LATER(ah) ? 0x0000000c : 0x00000004)
24#define AR_CR_RXD 0x00000020 24#define AR_CR_RXD 0x00000020
25#define AR_CR_SWI 0x00000040 25#define AR_CR_SWI 0x00000040
26 26
@@ -39,6 +39,12 @@
39#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 39#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000
40#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 40#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
41 41
42#define AR_RXBP_THRESH 0x0018
43#define AR_RXBP_THRESH_HP 0x0000000f
44#define AR_RXBP_THRESH_HP_S 0
45#define AR_RXBP_THRESH_LP 0x00003f00
46#define AR_RXBP_THRESH_LP_S 8
47
42#define AR_MIRT 0x0020 48#define AR_MIRT 0x0020
43#define AR_MIRT_VAL 0x0000ffff 49#define AR_MIRT_VAL 0x0000ffff
44#define AR_MIRT_VAL_S 16 50#define AR_MIRT_VAL_S 16
@@ -144,6 +150,9 @@
144#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15 150#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
145#define AR_MACMISC_MISC_OBS_BUS_1 1 151#define AR_MACMISC_MISC_OBS_BUS_1 1
146 152
153#define AR_DATABUF_SIZE 0x0060
154#define AR_DATABUF_SIZE_MASK 0x00000FFF
155
147#define AR_GTXTO 0x0064 156#define AR_GTXTO 0x0064
148#define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF 157#define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF
149#define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000 158#define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000
@@ -160,9 +169,14 @@
160#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000 169#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
161#define AR_CST_TIMEOUT_LIMIT_S 16 170#define AR_CST_TIMEOUT_LIMIT_S 16
162 171
172#define AR_HP_RXDP 0x0074
173#define AR_LP_RXDP 0x0078
174
163#define AR_ISR 0x0080 175#define AR_ISR 0x0080
164#define AR_ISR_RXOK 0x00000001 176#define AR_ISR_RXOK 0x00000001
165#define AR_ISR_RXDESC 0x00000002 177#define AR_ISR_RXDESC 0x00000002
178#define AR_ISR_HP_RXOK 0x00000001
179#define AR_ISR_LP_RXOK 0x00000002
166#define AR_ISR_RXERR 0x00000004 180#define AR_ISR_RXERR 0x00000004
167#define AR_ISR_RXNOPKT 0x00000008 181#define AR_ISR_RXNOPKT 0x00000008
168#define AR_ISR_RXEOL 0x00000010 182#define AR_ISR_RXEOL 0x00000010
@@ -232,7 +246,6 @@
232#define AR_ISR_S5_TIMER_THRESH 0x0007FE00 246#define AR_ISR_S5_TIMER_THRESH 0x0007FE00
233#define AR_ISR_S5_TIM_TIMER 0x00000010 247#define AR_ISR_S5_TIM_TIMER 0x00000010
234#define AR_ISR_S5_DTIM_TIMER 0x00000020 248#define AR_ISR_S5_DTIM_TIMER 0x00000020
235#define AR_ISR_S5_S 0x00d8
236#define AR_IMR_S5 0x00b8 249#define AR_IMR_S5 0x00b8
237#define AR_IMR_S5_TIM_TIMER 0x00000010 250#define AR_IMR_S5_TIM_TIMER 0x00000010
238#define AR_IMR_S5_DTIM_TIMER 0x00000020 251#define AR_IMR_S5_DTIM_TIMER 0x00000020
@@ -240,7 +253,6 @@
240#define AR_ISR_S5_GENTIMER_TRIG_S 0 253#define AR_ISR_S5_GENTIMER_TRIG_S 0
241#define AR_ISR_S5_GENTIMER_THRESH 0xFF800000 254#define AR_ISR_S5_GENTIMER_THRESH 0xFF800000
242#define AR_ISR_S5_GENTIMER_THRESH_S 16 255#define AR_ISR_S5_GENTIMER_THRESH_S 16
243#define AR_ISR_S5_S 0x00d8
244#define AR_IMR_S5_GENTIMER_TRIG 0x0000FF80 256#define AR_IMR_S5_GENTIMER_TRIG 0x0000FF80
245#define AR_IMR_S5_GENTIMER_TRIG_S 0 257#define AR_IMR_S5_GENTIMER_TRIG_S 0
246#define AR_IMR_S5_GENTIMER_THRESH 0xFF800000 258#define AR_IMR_S5_GENTIMER_THRESH 0xFF800000
@@ -249,6 +261,8 @@
249#define AR_IMR 0x00a0 261#define AR_IMR 0x00a0
250#define AR_IMR_RXOK 0x00000001 262#define AR_IMR_RXOK 0x00000001
251#define AR_IMR_RXDESC 0x00000002 263#define AR_IMR_RXDESC 0x00000002
264#define AR_IMR_RXOK_HP 0x00000001
265#define AR_IMR_RXOK_LP 0x00000002
252#define AR_IMR_RXERR 0x00000004 266#define AR_IMR_RXERR 0x00000004
253#define AR_IMR_RXNOPKT 0x00000008 267#define AR_IMR_RXNOPKT 0x00000008
254#define AR_IMR_RXEOL 0x00000010 268#define AR_IMR_RXEOL 0x00000010
@@ -332,10 +346,10 @@
332#define AR_ISR_S1_QCU_TXEOL 0x03FF0000 346#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
333#define AR_ISR_S1_QCU_TXEOL_S 16 347#define AR_ISR_S1_QCU_TXEOL_S 16
334 348
335#define AR_ISR_S2_S 0x00cc 349#define AR_ISR_S2_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d0 : 0x00cc)
336#define AR_ISR_S3_S 0x00d0 350#define AR_ISR_S3_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d4 : 0x00d0)
337#define AR_ISR_S4_S 0x00d4 351#define AR_ISR_S4_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d8 : 0x00d4)
338#define AR_ISR_S5_S 0x00d8 352#define AR_ISR_S5_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00dc : 0x00d8)
339#define AR_DMADBG_0 0x00e0 353#define AR_DMADBG_0 0x00e0
340#define AR_DMADBG_1 0x00e4 354#define AR_DMADBG_1 0x00e4
341#define AR_DMADBG_2 0x00e8 355#define AR_DMADBG_2 0x00e8
@@ -369,6 +383,9 @@
369#define AR_Q9_TXDP 0x0824 383#define AR_Q9_TXDP 0x0824
370#define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2)) 384#define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2))
371 385
386#define AR_Q_STATUS_RING_START 0x830
387#define AR_Q_STATUS_RING_END 0x834
388
372#define AR_Q_TXE 0x0840 389#define AR_Q_TXE 0x0840
373#define AR_Q_TXE_M 0x000003FF 390#define AR_Q_TXE_M 0x000003FF
374 391
@@ -461,6 +478,10 @@
461#define AR_Q_RDYTIMESHDN 0x0a40 478#define AR_Q_RDYTIMESHDN 0x0a40
462#define AR_Q_RDYTIMESHDN_M 0x000003FF 479#define AR_Q_RDYTIMESHDN_M 0x000003FF
463 480
481/* MAC Descriptor CRC check */
482#define AR_Q_DESC_CRCCHK 0xa44
483/* Enable CRC check on the descriptor fetched from host */
484#define AR_Q_DESC_CRCCHK_EN 1
464 485
465#define AR_NUM_DCU 10 486#define AR_NUM_DCU 10
466#define AR_DCU_0 0x0001 487#define AR_DCU_0 0x0001
@@ -679,7 +700,7 @@
679 700
680#define AR_WA 0x4004 701#define AR_WA 0x4004
681#define AR_WA_D3_L1_DISABLE (1 << 14) 702#define AR_WA_D3_L1_DISABLE (1 << 14)
682#define AR9285_WA_DEFAULT 0x004a05cb 703#define AR9285_WA_DEFAULT 0x004a050b
683#define AR9280_WA_DEFAULT 0x0040073b 704#define AR9280_WA_DEFAULT 0x0040073b
684#define AR_WA_DEFAULT 0x0000073f 705#define AR_WA_DEFAULT 0x0000073f
685 706
@@ -759,6 +780,8 @@
759#define AR_SREV_VERSION_9271 0x140 780#define AR_SREV_VERSION_9271 0x140
760#define AR_SREV_REVISION_9271_10 0 781#define AR_SREV_REVISION_9271_10 0
761#define AR_SREV_REVISION_9271_11 1 782#define AR_SREV_REVISION_9271_11 1
783#define AR_SREV_VERSION_9300 0x1c0
784#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
762 785
763#define AR_SREV_5416(_ah) \ 786#define AR_SREV_5416(_ah) \
764 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 787 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -844,6 +867,19 @@
844#define AR_SREV_9271_11(_ah) \ 867#define AR_SREV_9271_11(_ah) \
845 (AR_SREV_9271(_ah) && \ 868 (AR_SREV_9271(_ah) && \
846 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) 869 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
870#define AR_SREV_9300(_ah) \
871 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
872#define AR_SREV_9300_20(_ah) \
873 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
874 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
875#define AR_SREV_9300_20_OR_LATER(_ah) \
876 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
877 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
878 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
879
880#define AR_SREV_9285E_20(_ah) \
881 (AR_SREV_9285_12_OR_LATER(_ah) && \
882 ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
847 883
848#define AR_RADIO_SREV_MAJOR 0xf0 884#define AR_RADIO_SREV_MAJOR 0xf0
849#define AR_RAD5133_SREV_MAJOR 0xc0 885#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -940,6 +976,8 @@ enum {
940#define AR928X_NUM_GPIO 10 976#define AR928X_NUM_GPIO 10
941#define AR9285_NUM_GPIO 12 977#define AR9285_NUM_GPIO 12
942#define AR9287_NUM_GPIO 11 978#define AR9287_NUM_GPIO 11
979#define AR9271_NUM_GPIO 16
980#define AR9300_NUM_GPIO 17
943 981
944#define AR_GPIO_IN_OUT 0x4048 982#define AR_GPIO_IN_OUT 0x4048
945#define AR_GPIO_IN_VAL 0x0FFFC000 983#define AR_GPIO_IN_VAL 0x0FFFC000
@@ -950,19 +988,23 @@ enum {
950#define AR9285_GPIO_IN_VAL_S 12 988#define AR9285_GPIO_IN_VAL_S 12
951#define AR9287_GPIO_IN_VAL 0x003FF800 989#define AR9287_GPIO_IN_VAL 0x003FF800
952#define AR9287_GPIO_IN_VAL_S 11 990#define AR9287_GPIO_IN_VAL_S 11
991#define AR9271_GPIO_IN_VAL 0xFFFF0000
992#define AR9271_GPIO_IN_VAL_S 16
993#define AR9300_GPIO_IN_VAL 0x0001FFFF
994#define AR9300_GPIO_IN_VAL_S 0
953 995
954#define AR_GPIO_OE_OUT 0x404c 996#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
955#define AR_GPIO_OE_OUT_DRV 0x3 997#define AR_GPIO_OE_OUT_DRV 0x3
956#define AR_GPIO_OE_OUT_DRV_NO 0x0 998#define AR_GPIO_OE_OUT_DRV_NO 0x0
957#define AR_GPIO_OE_OUT_DRV_LOW 0x1 999#define AR_GPIO_OE_OUT_DRV_LOW 0x1
958#define AR_GPIO_OE_OUT_DRV_HI 0x2 1000#define AR_GPIO_OE_OUT_DRV_HI 0x2
959#define AR_GPIO_OE_OUT_DRV_ALL 0x3 1001#define AR_GPIO_OE_OUT_DRV_ALL 0x3
960 1002
961#define AR_GPIO_INTR_POL 0x4050 1003#define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
962#define AR_GPIO_INTR_POL_VAL 0x00001FFF 1004#define AR_GPIO_INTR_POL_VAL 0x0001FFFF
963#define AR_GPIO_INTR_POL_VAL_S 0 1005#define AR_GPIO_INTR_POL_VAL_S 0
964 1006
965#define AR_GPIO_INPUT_EN_VAL 0x4054 1007#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
966#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 1008#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
967#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 1009#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
968#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 1010#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
@@ -980,13 +1022,13 @@ enum {
980#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 1022#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
981#define AR_GPIO_JTAG_DISABLE 0x00020000 1023#define AR_GPIO_JTAG_DISABLE 0x00020000
982 1024
983#define AR_GPIO_INPUT_MUX1 0x4058 1025#define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
984#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 1026#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
985#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 1027#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
986#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 1028#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
987#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 1029#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
988 1030
989#define AR_GPIO_INPUT_MUX2 0x405c 1031#define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
990#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f 1032#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
991#define AR_GPIO_INPUT_MUX2_CLK25_S 0 1033#define AR_GPIO_INPUT_MUX2_CLK25_S 0
992#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 1034#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
@@ -994,13 +1036,13 @@ enum {
994#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 1036#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
995#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 1037#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
996 1038
997#define AR_GPIO_OUTPUT_MUX1 0x4060 1039#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
998#define AR_GPIO_OUTPUT_MUX2 0x4064 1040#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
999#define AR_GPIO_OUTPUT_MUX3 0x4068 1041#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
1000 1042
1001#define AR_INPUT_STATE 0x406c 1043#define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
1002 1044
1003#define AR_EEPROM_STATUS_DATA 0x407c 1045#define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
1004#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff 1046#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
1005#define AR_EEPROM_STATUS_DATA_VAL_S 0 1047#define AR_EEPROM_STATUS_DATA_VAL_S 0
1006#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 1048#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
@@ -1008,13 +1050,24 @@ enum {
1008#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 1050#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
1009#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 1051#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
1010 1052
1011#define AR_OBS 0x4080 1053#define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
1012 1054
1013#define AR_GPIO_PDPU 0x4088 1055#define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
1014 1056
1015#define AR_PCIE_MSI 0x4094 1057#define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
1016#define AR_PCIE_MSI_ENABLE 0x00000001 1058#define AR_PCIE_MSI_ENABLE 0x00000001
1017 1059
1060#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
1061#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
1062#define AR_INTR_PRIO_SYNC_MASK 0x40cc
1063#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
1064
1065#define AR_RTC_9300_PLL_DIV 0x000003ff
1066#define AR_RTC_9300_PLL_DIV_S 0
1067#define AR_RTC_9300_PLL_REFDIV 0x00003C00
1068#define AR_RTC_9300_PLL_REFDIV_S 10
1069#define AR_RTC_9300_PLL_CLKSEL 0x0000C000
1070#define AR_RTC_9300_PLL_CLKSEL_S 14
1018 1071
1019#define AR_RTC_9160_PLL_DIV 0x000003ff 1072#define AR_RTC_9160_PLL_DIV 0x000003ff
1020#define AR_RTC_9160_PLL_DIV_S 0 1073#define AR_RTC_9160_PLL_DIV_S 0
@@ -1032,6 +1085,16 @@ enum {
1032#define AR_RTC_RC_COLD_RESET 0x00000004 1085#define AR_RTC_RC_COLD_RESET 0x00000004
1033#define AR_RTC_RC_WARM_RESET 0x00000008 1086#define AR_RTC_RC_WARM_RESET 0x00000008
1034 1087
1088/* Crystal Control */
1089#define AR_RTC_XTAL_CONTROL 0x7004
1090
1091/* Reg Control 0 */
1092#define AR_RTC_REG_CONTROL0 0x7008
1093
1094/* Reg Control 1 */
1095#define AR_RTC_REG_CONTROL1 0x700c
1096#define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001
1097
1035#define AR_RTC_PLL_CONTROL \ 1098#define AR_RTC_PLL_CONTROL \
1036 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) 1099 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
1037 1100
@@ -1062,6 +1125,7 @@ enum {
1062#define AR_RTC_SLEEP_CLK \ 1125#define AR_RTC_SLEEP_CLK \
1063 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) 1126 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
1064#define AR_RTC_FORCE_DERIVED_CLK 0x2 1127#define AR_RTC_FORCE_DERIVED_CLK 0x2
1128#define AR_RTC_FORCE_SWREG_PRD 0x00000004
1065 1129
1066#define AR_RTC_FORCE_WAKE \ 1130#define AR_RTC_FORCE_WAKE \
1067 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) 1131 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
@@ -1178,6 +1242,13 @@ enum {
1178#define AR9285_AN_RF2G4_DB2_4 0x00003800 1242#define AR9285_AN_RF2G4_DB2_4 0x00003800
1179#define AR9285_AN_RF2G4_DB2_4_S 11 1243#define AR9285_AN_RF2G4_DB2_4_S 11
1180 1244
1245#define AR9285_RF2G5 0x7830
1246#define AR9285_RF2G5_IC50TX 0xfffff8ff
1247#define AR9285_RF2G5_IC50TX_SET 0x00000400
1248#define AR9285_RF2G5_IC50TX_XE_SET 0x00000500
1249#define AR9285_RF2G5_IC50TX_CLEAR 0x00000700
1250#define AR9285_RF2G5_IC50TX_CLEAR_S 8
1251
1181/* AR9271 : 0x7828, 0x782c different setting from AR9285 */ 1252/* AR9271 : 0x7828, 0x782c different setting from AR9285 */
1182#define AR9271_AN_RF2G3_OB_cck 0x001C0000 1253#define AR9271_AN_RF2G3_OB_cck 0x001C0000
1183#define AR9271_AN_RF2G3_OB_cck_S 18 1254#define AR9271_AN_RF2G3_OB_cck_S 18
@@ -1519,7 +1590,7 @@ enum {
1519#define AR_TSFOOR_THRESHOLD 0x813c 1590#define AR_TSFOOR_THRESHOLD 0x813c
1520#define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF 1591#define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF
1521 1592
1522#define AR_PHY_ERR_EIFS_MASK 8144 1593#define AR_PHY_ERR_EIFS_MASK 0x8144
1523 1594
1524#define AR_PHY_ERR_3 0x8168 1595#define AR_PHY_ERR_3 0x8168
1525#define AR_PHY_ERR_3_COUNT 0x00FFFFFF 1596#define AR_PHY_ERR_3_COUNT 0x00FFFFFF
@@ -1585,24 +1656,26 @@ enum {
1585#define AR_FIRST_NDP_TIMER 7 1656#define AR_FIRST_NDP_TIMER 7
1586#define AR_NDP2_PERIOD 0x81a0 1657#define AR_NDP2_PERIOD 0x81a0
1587#define AR_NDP2_TIMER_MODE 0x81c0 1658#define AR_NDP2_TIMER_MODE 0x81c0
1588#define AR_NEXT_TBTT_TIMER 0x8200 1659
1589#define AR_NEXT_DMA_BEACON_ALERT 0x8204 1660#define AR_GEN_TIMERS(_i) (0x8200 + ((_i) << 2))
1590#define AR_NEXT_SWBA 0x8208 1661#define AR_NEXT_TBTT_TIMER AR_GEN_TIMERS(0)
1591#define AR_NEXT_CFP 0x8208 1662#define AR_NEXT_DMA_BEACON_ALERT AR_GEN_TIMERS(1)
1592#define AR_NEXT_HCF 0x820C 1663#define AR_NEXT_SWBA AR_GEN_TIMERS(2)
1593#define AR_NEXT_TIM 0x8210 1664#define AR_NEXT_CFP AR_GEN_TIMERS(2)
1594#define AR_NEXT_DTIM 0x8214 1665#define AR_NEXT_HCF AR_GEN_TIMERS(3)
1595#define AR_NEXT_QUIET_TIMER 0x8218 1666#define AR_NEXT_TIM AR_GEN_TIMERS(4)
1596#define AR_NEXT_NDP_TIMER 0x821C 1667#define AR_NEXT_DTIM AR_GEN_TIMERS(5)
1597 1668#define AR_NEXT_QUIET_TIMER AR_GEN_TIMERS(6)
1598#define AR_BEACON_PERIOD 0x8220 1669#define AR_NEXT_NDP_TIMER AR_GEN_TIMERS(7)
1599#define AR_DMA_BEACON_PERIOD 0x8224 1670
1600#define AR_SWBA_PERIOD 0x8228 1671#define AR_BEACON_PERIOD AR_GEN_TIMERS(8)
1601#define AR_HCF_PERIOD 0x822C 1672#define AR_DMA_BEACON_PERIOD AR_GEN_TIMERS(9)
1602#define AR_TIM_PERIOD 0x8230 1673#define AR_SWBA_PERIOD AR_GEN_TIMERS(10)
1603#define AR_DTIM_PERIOD 0x8234 1674#define AR_HCF_PERIOD AR_GEN_TIMERS(11)
1604#define AR_QUIET_PERIOD 0x8238 1675#define AR_TIM_PERIOD AR_GEN_TIMERS(12)
1605#define AR_NDP_PERIOD 0x823C 1676#define AR_DTIM_PERIOD AR_GEN_TIMERS(13)
1677#define AR_QUIET_PERIOD AR_GEN_TIMERS(14)
1678#define AR_NDP_PERIOD AR_GEN_TIMERS(15)
1606 1679
1607#define AR_TIMER_MODE 0x8240 1680#define AR_TIMER_MODE 0x8240
1608#define AR_TBTT_TIMER_EN 0x00000001 1681#define AR_TBTT_TIMER_EN 0x00000001
@@ -1716,4 +1789,32 @@ enum {
1716#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ 1789#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */
1717#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ 1790#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */
1718 1791
1792#define AR_AGG_WEP_ENABLE_FIX 0x00000008 /* This allows the use of AR_AGG_WEP_ENABLE */
1793#define AR_ADHOC_MCAST_KEYID_ENABLE 0x00000040 /* This bit enables the Multicast search
1794 * based on both MAC Address and Key ID.
1795 * If bit is 0, then Multicast search is
1796 * based on MAC address only.
1797 * For Merlin and above only.
1798 */
1799#define AR_AGG_WEP_ENABLE 0x00020000 /* This field enables AGG_WEP feature,
1800 * when it is enable, AGG_WEP would takes
1801 * charge of the encryption interface of
1802 * pcu_txsm.
1803 */
1804
1805#define AR9300_SM_BASE 0xa200
1806#define AR9002_PHY_AGC_CONTROL 0x9860
1807#define AR9003_PHY_AGC_CONTROL AR9300_SM_BASE + 0xc4
1808#define AR_PHY_AGC_CONTROL (AR_SREV_9300_20_OR_LATER(ah) ? AR9003_PHY_AGC_CONTROL : AR9002_PHY_AGC_CONTROL)
1809#define AR_PHY_AGC_CONTROL_CAL 0x00000001 /* do internal calibration */
1810#define AR_PHY_AGC_CONTROL_NF 0x00000002 /* do noise-floor calibration */
1811#define AR_PHY_AGC_CONTROL_OFFSET_CAL 0x00000800 /* allow offset calibration */
1812#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 /* enable noise floor calibration to happen */
1813#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 /* allow tx filter calibration */
1814#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */
1815#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */
1816#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */
1817#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
1818#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
1819
1719#endif 1820#endif
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 00c0e21a4af7..105ad40968f6 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -220,7 +220,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
220 220
221 memset(&txctl, 0, sizeof(struct ath_tx_control)); 221 memset(&txctl, 0, sizeof(struct ath_tx_control));
222 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; 222 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
223 txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; 223 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
224 224
225 if (ath_tx_start(aphy->hw, skb, &txctl) != 0) 225 if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
226 goto exit; 226 goto exit;
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
new file mode 100644
index 000000000000..e23172c9caaf
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -0,0 +1,336 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
20{
21 switch (wmi_cmd) {
22 case WMI_ECHO_CMDID:
23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID:
43 return "WMI_DRAIN_TXQ_CMDID";
44 case WMI_DRAIN_TXQ_ALL_CMDID:
45 return "WMI_DRAIN_TXQ_ALL_CMDID";
46 case WMI_START_RECV_CMDID:
47 return "WMI_START_RECV_CMDID";
48 case WMI_STOP_RECV_CMDID:
49 return "WMI_STOP_RECV_CMDID";
50 case WMI_FLUSH_RECV_CMDID:
51 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID:
59 return "WMI_NODE_REMOVE_CMDID";
60 case WMI_VAP_REMOVE_CMDID:
61 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID:
69 return "WMI_REG_WRITE_CMDID";
70 case WMI_RC_STATE_CHANGE_CMDID:
71 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID";
88 }
89
90 return "Bogus";
91}
92
93struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
94{
95 struct wmi *wmi;
96
97 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
98 if (!wmi)
99 return NULL;
100
101 wmi->drv_priv = priv;
102 wmi->stopped = false;
103 mutex_init(&wmi->op_mutex);
104 mutex_init(&wmi->multi_write_mutex);
105 init_completion(&wmi->cmd_wait);
106
107 return wmi;
108}
109
110void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
111{
112 struct wmi *wmi = priv->wmi;
113
114 mutex_lock(&wmi->op_mutex);
115 wmi->stopped = true;
116 mutex_unlock(&wmi->op_mutex);
117
118 kfree(priv->wmi);
119}
120
121void ath9k_wmi_tasklet(unsigned long data)
122{
123 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
124 struct ath_common *common = ath9k_hw_common(priv->ah);
125 struct wmi_cmd_hdr *hdr;
126 struct wmi_swba *swba_hdr;
127 enum wmi_event_id event;
128 struct sk_buff *skb;
129 void *wmi_event;
130 unsigned long flags;
131#ifdef CONFIG_ATH9K_HTC_DEBUGFS
132 __be32 txrate;
133#endif
134
135 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
136 skb = priv->wmi->wmi_skb;
137 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
138
139 hdr = (struct wmi_cmd_hdr *) skb->data;
140 event = be16_to_cpu(hdr->command_id);
141 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
142
143 ath_print(common, ATH_DBG_WMI,
144 "WMI Event: 0x%x\n", event);
145
146 switch (event) {
147 case WMI_TGT_RDY_EVENTID:
148 break;
149 case WMI_SWBA_EVENTID:
150 swba_hdr = (struct wmi_swba *) wmi_event;
151 ath9k_htc_swba(priv, swba_hdr->beacon_pending);
152 break;
153 case WMI_FATAL_EVENTID:
154 break;
155 case WMI_TXTO_EVENTID:
156 break;
157 case WMI_BMISS_EVENTID:
158 break;
159 case WMI_WLAN_TXCOMP_EVENTID:
160 break;
161 case WMI_DELBA_EVENTID:
162 break;
163 case WMI_TXRATE_EVENTID:
164#ifdef CONFIG_ATH9K_HTC_DEBUGFS
165 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
166 priv->debug.txrate = be32_to_cpu(txrate);
167#endif
168 break;
169 default:
170 break;
171 }
172
173 kfree_skb(skb);
174}
175
176static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
177{
178 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
179
180 if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
181 memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
182
183 complete(&wmi->cmd_wait);
184}
185
186static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
187 enum htc_endpoint_id epid)
188{
189 struct wmi *wmi = (struct wmi *) priv;
190 struct wmi_cmd_hdr *hdr;
191 u16 cmd_id;
192
193 if (unlikely(wmi->stopped))
194 goto free_skb;
195
196 hdr = (struct wmi_cmd_hdr *) skb->data;
197 cmd_id = be16_to_cpu(hdr->command_id);
198
199 if (cmd_id & 0x1000) {
200 spin_lock(&wmi->wmi_lock);
201 wmi->wmi_skb = skb;
202 spin_unlock(&wmi->wmi_lock);
203 tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
204 return;
205 }
206
207 /* Check if there has been a timeout. */
208 spin_lock(&wmi->wmi_lock);
209 if (cmd_id != wmi->last_cmd_id) {
210 spin_unlock(&wmi->wmi_lock);
211 goto free_skb;
212 }
213 spin_unlock(&wmi->wmi_lock);
214
215 /* WMI command response */
216 ath9k_wmi_rsp_callback(wmi, skb);
217
218free_skb:
219 kfree_skb(skb);
220}
221
222static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb,
223 enum htc_endpoint_id epid, bool txok)
224{
225 kfree_skb(skb);
226}
227
228int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
229 enum htc_endpoint_id *wmi_ctrl_epid)
230{
231 struct htc_service_connreq connect;
232 int ret;
233
234 wmi->htc = htc;
235
236 memset(&connect, 0, sizeof(connect));
237
238 connect.ep_callbacks.priv = wmi;
239 connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx;
240 connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx;
241 connect.service_id = WMI_CONTROL_SVC;
242
243 ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid);
244 if (ret)
245 return ret;
246
247 *wmi_ctrl_epid = wmi->ctrl_epid;
248
249 return 0;
250}
251
252static int ath9k_wmi_cmd_issue(struct wmi *wmi,
253 struct sk_buff *skb,
254 enum wmi_cmd_id cmd, u16 len)
255{
256 struct wmi_cmd_hdr *hdr;
257
258 hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr));
259 hdr->command_id = cpu_to_be16(cmd);
260 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
261
262 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
263}
264
265int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
266 u8 *cmd_buf, u32 cmd_len,
267 u8 *rsp_buf, u32 rsp_len,
268 u32 timeout)
269{
270 struct ath_hw *ah = wmi->drv_priv->ah;
271 struct ath_common *common = ath9k_hw_common(ah);
272 u16 headroom = sizeof(struct htc_frame_hdr) +
273 sizeof(struct wmi_cmd_hdr);
274 struct sk_buff *skb;
275 u8 *data;
276 int time_left, ret = 0;
277 unsigned long flags;
278
279 if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
280 return 0;
281
282 if (!wmi)
283 return -EINVAL;
284
285 skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
286 if (!skb)
287 return -ENOMEM;
288
289 skb_reserve(skb, headroom);
290
291 if (cmd_len != 0 && cmd_buf != NULL) {
292 data = (u8 *) skb_put(skb, cmd_len);
293 memcpy(data, cmd_buf, cmd_len);
294 }
295
296 mutex_lock(&wmi->op_mutex);
297
298 /* check if wmi stopped flag is set */
299 if (unlikely(wmi->stopped)) {
300 ret = -EPROTO;
301 goto out;
302 }
303
304 /* record the rsp buffer and length */
305 wmi->cmd_rsp_buf = rsp_buf;
306 wmi->cmd_rsp_len = rsp_len;
307
308 spin_lock_irqsave(&wmi->wmi_lock, flags);
309 wmi->last_cmd_id = cmd_id;
310 spin_unlock_irqrestore(&wmi->wmi_lock, flags);
311
312 ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
313 if (ret)
314 goto out;
315
316 time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
317 if (!time_left) {
318 ath_print(common, ATH_DBG_WMI,
319 "Timeout waiting for WMI command: %s\n",
320 wmi_cmd_to_name(cmd_id));
321 mutex_unlock(&wmi->op_mutex);
322 return -ETIMEDOUT;
323 }
324
325 mutex_unlock(&wmi->op_mutex);
326
327 return 0;
328
329out:
330 ath_print(common, ATH_DBG_WMI,
331 "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
332 mutex_unlock(&wmi->op_mutex);
333 kfree_skb(skb);
334
335 return ret;
336}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
new file mode 100644
index 000000000000..765db5faa2d3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef WMI_H
18#define WMI_H
19
20
21struct wmi_event_txrate {
22 __be32 txrate;
23 struct {
24 u8 rssi_thresh;
25 u8 per;
26 } rc_stats;
27} __packed;
28
29struct wmi_cmd_hdr {
30 __be16 command_id;
31 __be16 seq_no;
32} __packed;
33
34struct wmi_swba {
35 u8 beacon_pending;
36} __packed;
37
38enum wmi_cmd_id {
39 WMI_ECHO_CMDID = 0x0001,
40 WMI_ACCESS_MEMORY_CMDID,
41
42 /* Commands to Target */
43 WMI_DISABLE_INTR_CMDID,
44 WMI_ENABLE_INTR_CMDID,
45 WMI_RX_LINK_CMDID,
46 WMI_ATH_INIT_CMDID,
47 WMI_ABORT_TXQ_CMDID,
48 WMI_STOP_TX_DMA_CMDID,
49 WMI_STOP_DMA_RECV_CMDID,
50 WMI_ABORT_TX_DMA_CMDID,
51 WMI_DRAIN_TXQ_CMDID,
52 WMI_DRAIN_TXQ_ALL_CMDID,
53 WMI_START_RECV_CMDID,
54 WMI_STOP_RECV_CMDID,
55 WMI_FLUSH_RECV_CMDID,
56 WMI_SET_MODE_CMDID,
57 WMI_RESET_CMDID,
58 WMI_NODE_CREATE_CMDID,
59 WMI_NODE_REMOVE_CMDID,
60 WMI_VAP_REMOVE_CMDID,
61 WMI_VAP_CREATE_CMDID,
62 WMI_BEACON_UPDATE_CMDID,
63 WMI_REG_READ_CMDID,
64 WMI_REG_WRITE_CMDID,
65 WMI_RC_STATE_CHANGE_CMDID,
66 WMI_RC_RATE_UPDATE_CMDID,
67 WMI_DEBUG_INFO_CMDID,
68 WMI_HOST_ATTACH,
69 WMI_TARGET_IC_UPDATE_CMDID,
70 WMI_TGT_STATS_CMDID,
71 WMI_TX_AGGR_ENABLE_CMDID,
72 WMI_TGT_DETACH_CMDID,
73 WMI_TGT_TXQ_ENABLE_CMDID,
74};
75
76enum wmi_event_id {
77 WMI_TGT_RDY_EVENTID = 0x1001,
78 WMI_SWBA_EVENTID,
79 WMI_FATAL_EVENTID,
80 WMI_TXTO_EVENTID,
81 WMI_BMISS_EVENTID,
82 WMI_WLAN_TXCOMP_EVENTID,
83 WMI_DELBA_EVENTID,
84 WMI_TXRATE_EVENTID,
85};
86
87#define MAX_CMD_NUMBER 62
88
89struct register_write {
90 __be32 reg;
91 __be32 val;
92};
93
94struct wmi {
95 struct ath9k_htc_priv *drv_priv;
96 struct htc_target *htc;
97 enum htc_endpoint_id ctrl_epid;
98 struct mutex op_mutex;
99 struct completion cmd_wait;
100 enum wmi_cmd_id last_cmd_id;
101 u16 tx_seq_id;
102 u8 *cmd_rsp_buf;
103 u32 cmd_rsp_len;
104 bool stopped;
105
106 struct sk_buff *wmi_skb;
107 spinlock_t wmi_lock;
108
109 atomic_t mwrite_cnt;
110 struct register_write multi_write[MAX_CMD_NUMBER];
111 u32 multi_write_idx;
112 struct mutex multi_write_mutex;
113};
114
115struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
116void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
117int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
118 enum htc_endpoint_id *wmi_ctrl_epid);
119int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
120 u8 *cmd_buf, u32 cmd_len,
121 u8 *rsp_buf, u32 rsp_len,
122 u32 timeout);
123void ath9k_wmi_tasklet(unsigned long data);
124
125#define WMI_CMD(_wmi_cmd) \
126 do { \
127 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \
128 (u8 *) &cmd_rsp, \
129 sizeof(cmd_rsp), HZ*2); \
130 } while (0)
131
132#define WMI_CMD_BUF(_wmi_cmd, _buf) \
133 do { \
134 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \
135 (u8 *) _buf, sizeof(*_buf), \
136 &cmd_rsp, sizeof(cmd_rsp), HZ*2); \
137 } while (0)
138
139#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 294b486bc3ed..3db19172b43b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -15,10 +15,11 @@
15 */ 15 */
16 16
17#include "ath9k.h" 17#include "ath9k.h"
18#include "ar9003_mac.h"
18 19
19#define BITS_PER_BYTE 8 20#define BITS_PER_BYTE 8
20#define OFDM_PLCP_BITS 22 21#define OFDM_PLCP_BITS 22
21#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f) 22#define HT_RC_2_MCS(_rc) ((_rc) & 0x1f)
22#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 23#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
23#define L_STF 8 24#define L_STF 8
24#define L_LTF 8 25#define L_LTF 8
@@ -33,7 +34,7 @@
33 34
34#define OFDM_SIFS_TIME 16 35#define OFDM_SIFS_TIME 16
35 36
36static u32 bits_per_symbol[][2] = { 37static u16 bits_per_symbol[][2] = {
37 /* 20MHz 40MHz */ 38 /* 20MHz 40MHz */
38 { 26, 54 }, /* 0: BPSK */ 39 { 26, 54 }, /* 0: BPSK */
39 { 52, 108 }, /* 1: QPSK 1/2 */ 40 { 52, 108 }, /* 1: QPSK 1/2 */
@@ -43,14 +44,6 @@ static u32 bits_per_symbol[][2] = {
43 { 208, 432 }, /* 5: 64-QAM 2/3 */ 44 { 208, 432 }, /* 5: 64-QAM 2/3 */
44 { 234, 486 }, /* 6: 64-QAM 3/4 */ 45 { 234, 486 }, /* 6: 64-QAM 3/4 */
45 { 260, 540 }, /* 7: 64-QAM 5/6 */ 46 { 260, 540 }, /* 7: 64-QAM 5/6 */
46 { 52, 108 }, /* 8: BPSK */
47 { 104, 216 }, /* 9: QPSK 1/2 */
48 { 156, 324 }, /* 10: QPSK 3/4 */
49 { 208, 432 }, /* 11: 16-QAM 1/2 */
50 { 312, 648 }, /* 12: 16-QAM 3/4 */
51 { 416, 864 }, /* 13: 64-QAM 2/3 */
52 { 468, 972 }, /* 14: 64-QAM 3/4 */
53 { 520, 1080 }, /* 15: 64-QAM 5/6 */
54}; 47};
55 48
56#define IS_HT_RATE(_rate) ((_rate) & 0x80) 49#define IS_HT_RATE(_rate) ((_rate) & 0x80)
@@ -59,40 +52,50 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
59 struct ath_atx_tid *tid, 52 struct ath_atx_tid *tid,
60 struct list_head *bf_head); 53 struct list_head *bf_head);
61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 54static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
62 struct ath_txq *txq, 55 struct ath_txq *txq, struct list_head *bf_q,
63 struct list_head *bf_q, 56 struct ath_tx_status *ts, int txok, int sendbar);
64 int txok, int sendbar);
65static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 57static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
66 struct list_head *head); 58 struct list_head *head);
67static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); 59static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
68static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 60static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
69 int txok); 61 struct ath_tx_status *ts, int txok);
70static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 62static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
71 int nbad, int txok, bool update_rc); 63 int nbad, int txok, bool update_rc);
72 64
73enum { 65enum {
74 MCS_DEFAULT, 66 MCS_HT20,
67 MCS_HT20_SGI,
75 MCS_HT40, 68 MCS_HT40,
76 MCS_HT40_SGI, 69 MCS_HT40_SGI,
77}; 70};
78 71
79static int ath_max_4ms_framelen[3][16] = { 72static int ath_max_4ms_framelen[4][32] = {
80 [MCS_DEFAULT] = { 73 [MCS_HT20] = {
81 3216, 6434, 9650, 12868, 19304, 25740, 28956, 32180, 74 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172,
82 6430, 12860, 19300, 25736, 38600, 51472, 57890, 64320, 75 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280,
76 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532,
77 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532,
78 },
79 [MCS_HT20_SGI] = {
80 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744,
81 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532,
82 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532,
83 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532,
83 }, 84 },
84 [MCS_HT40] = { 85 [MCS_HT40] = {
85 6684, 13368, 20052, 26738, 40104, 53476, 60156, 66840, 86 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532,
86 13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600, 87 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532,
88 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532,
89 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532,
87 }, 90 },
88 [MCS_HT40_SGI] = { 91 [MCS_HT40_SGI] = {
89 /* TODO: Only MCS 7 and 15 updated, recalculate the rest */ 92 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532,
90 6684, 13368, 20052, 26738, 40104, 53476, 60156, 74200, 93 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532,
91 13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400, 94 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532,
95 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532,
92 } 96 }
93}; 97};
94 98
95
96/*********************/ 99/*********************/
97/* Aggregation logic */ 100/* Aggregation logic */
98/*********************/ 101/*********************/
@@ -223,6 +226,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
223{ 226{
224 struct ath_buf *bf; 227 struct ath_buf *bf;
225 struct list_head bf_head; 228 struct list_head bf_head;
229 struct ath_tx_status ts;
230
231 memset(&ts, 0, sizeof(ts));
226 INIT_LIST_HEAD(&bf_head); 232 INIT_LIST_HEAD(&bf_head);
227 233
228 for (;;) { 234 for (;;) {
@@ -236,7 +242,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
236 ath_tx_update_baw(sc, tid, bf->bf_seqno); 242 ath_tx_update_baw(sc, tid, bf->bf_seqno);
237 243
238 spin_unlock(&txq->axq_lock); 244 spin_unlock(&txq->axq_lock);
239 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 245 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
240 spin_lock(&txq->axq_lock); 246 spin_lock(&txq->axq_lock);
241 } 247 }
242 248
@@ -259,25 +265,46 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
259 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); 265 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
260} 266}
261 267
262static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) 268static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
263{ 269{
264 struct ath_buf *tbf; 270 struct ath_buf *bf = NULL;
265 271
266 spin_lock_bh(&sc->tx.txbuflock); 272 spin_lock_bh(&sc->tx.txbuflock);
267 if (WARN_ON(list_empty(&sc->tx.txbuf))) { 273
274 if (unlikely(list_empty(&sc->tx.txbuf))) {
268 spin_unlock_bh(&sc->tx.txbuflock); 275 spin_unlock_bh(&sc->tx.txbuflock);
269 return NULL; 276 return NULL;
270 } 277 }
271 tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); 278
272 list_del(&tbf->list); 279 bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
280 list_del(&bf->list);
281
273 spin_unlock_bh(&sc->tx.txbuflock); 282 spin_unlock_bh(&sc->tx.txbuflock);
274 283
284 return bf;
285}
286
287static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
288{
289 spin_lock_bh(&sc->tx.txbuflock);
290 list_add_tail(&bf->list, &sc->tx.txbuf);
291 spin_unlock_bh(&sc->tx.txbuflock);
292}
293
294static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
295{
296 struct ath_buf *tbf;
297
298 tbf = ath_tx_get_buffer(sc);
299 if (WARN_ON(!tbf))
300 return NULL;
301
275 ATH_TXBUF_RESET(tbf); 302 ATH_TXBUF_RESET(tbf);
276 303
277 tbf->aphy = bf->aphy; 304 tbf->aphy = bf->aphy;
278 tbf->bf_mpdu = bf->bf_mpdu; 305 tbf->bf_mpdu = bf->bf_mpdu;
279 tbf->bf_buf_addr = bf->bf_buf_addr; 306 tbf->bf_buf_addr = bf->bf_buf_addr;
280 *(tbf->bf_desc) = *(bf->bf_desc); 307 memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
281 tbf->bf_state = bf->bf_state; 308 tbf->bf_state = bf->bf_state;
282 tbf->bf_dmacontext = bf->bf_dmacontext; 309 tbf->bf_dmacontext = bf->bf_dmacontext;
283 310
@@ -286,7 +313,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
286 313
287static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, 314static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
288 struct ath_buf *bf, struct list_head *bf_q, 315 struct ath_buf *bf, struct list_head *bf_q,
289 int txok) 316 struct ath_tx_status *ts, int txok)
290{ 317{
291 struct ath_node *an = NULL; 318 struct ath_node *an = NULL;
292 struct sk_buff *skb; 319 struct sk_buff *skb;
@@ -296,7 +323,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
296 struct ieee80211_tx_info *tx_info; 323 struct ieee80211_tx_info *tx_info;
297 struct ath_atx_tid *tid = NULL; 324 struct ath_atx_tid *tid = NULL;
298 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 325 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
299 struct ath_desc *ds = bf_last->bf_desc;
300 struct list_head bf_head, bf_pending; 326 struct list_head bf_head, bf_pending;
301 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; 327 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
302 u32 ba[WME_BA_BMP_SIZE >> 5]; 328 u32 ba[WME_BA_BMP_SIZE >> 5];
@@ -325,10 +351,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
325 memset(ba, 0, WME_BA_BMP_SIZE >> 3); 351 memset(ba, 0, WME_BA_BMP_SIZE >> 3);
326 352
327 if (isaggr && txok) { 353 if (isaggr && txok) {
328 if (ATH_DS_TX_BA(ds)) { 354 if (ts->ts_flags & ATH9K_TX_BA) {
329 seq_st = ATH_DS_BA_SEQ(ds); 355 seq_st = ts->ts_seqnum;
330 memcpy(ba, ATH_DS_BA_BITMAP(ds), 356 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
331 WME_BA_BMP_SIZE >> 3);
332 } else { 357 } else {
333 /* 358 /*
334 * AR5416 can become deaf/mute when BA 359 * AR5416 can become deaf/mute when BA
@@ -345,7 +370,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
345 INIT_LIST_HEAD(&bf_pending); 370 INIT_LIST_HEAD(&bf_pending);
346 INIT_LIST_HEAD(&bf_head); 371 INIT_LIST_HEAD(&bf_head);
347 372
348 nbad = ath_tx_num_badfrms(sc, bf, txok); 373 nbad = ath_tx_num_badfrms(sc, bf, ts, txok);
349 while (bf) { 374 while (bf) {
350 txfail = txpending = 0; 375 txfail = txpending = 0;
351 bf_next = bf->bf_next; 376 bf_next = bf->bf_next;
@@ -359,7 +384,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
359 acked_cnt++; 384 acked_cnt++;
360 } else { 385 } else {
361 if (!(tid->state & AGGR_CLEANUP) && 386 if (!(tid->state & AGGR_CLEANUP) &&
362 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 387 !bf_last->bf_tx_aborted) {
363 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 388 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
364 ath_tx_set_retry(sc, txq, bf); 389 ath_tx_set_retry(sc, txq, bf);
365 txpending = 1; 390 txpending = 1;
@@ -378,7 +403,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
378 } 403 }
379 } 404 }
380 405
381 if (bf_next == NULL) { 406 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
407 bf_next == NULL) {
382 /* 408 /*
383 * Make sure the last desc is reclaimed if it 409 * Make sure the last desc is reclaimed if it
384 * not a holding desc. 410 * not a holding desc.
@@ -402,45 +428,53 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
402 spin_unlock_bh(&txq->axq_lock); 428 spin_unlock_bh(&txq->axq_lock);
403 429
404 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 430 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
405 ath_tx_rc_status(bf, ds, nbad, txok, true); 431 ath_tx_rc_status(bf, ts, nbad, txok, true);
406 rc_update = false; 432 rc_update = false;
407 } else { 433 } else {
408 ath_tx_rc_status(bf, ds, nbad, txok, false); 434 ath_tx_rc_status(bf, ts, nbad, txok, false);
409 } 435 }
410 436
411 ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar); 437 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
438 !txfail, sendbar);
412 } else { 439 } else {
413 /* retry the un-acked ones */ 440 /* retry the un-acked ones */
414 if (bf->bf_next == NULL && bf_last->bf_stale) { 441 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
415 struct ath_buf *tbf; 442 if (bf->bf_next == NULL && bf_last->bf_stale) {
416 443 struct ath_buf *tbf;
417 tbf = ath_clone_txbuf(sc, bf_last); 444
418 /* 445 tbf = ath_clone_txbuf(sc, bf_last);
419 * Update tx baw and complete the frame with 446 /*
420 * failed status if we run out of tx buf 447 * Update tx baw and complete the
421 */ 448 * frame with failed status if we
422 if (!tbf) { 449 * run out of tx buf.
423 spin_lock_bh(&txq->axq_lock); 450 */
424 ath_tx_update_baw(sc, tid, 451 if (!tbf) {
425 bf->bf_seqno); 452 spin_lock_bh(&txq->axq_lock);
426 spin_unlock_bh(&txq->axq_lock); 453 ath_tx_update_baw(sc, tid,
427 454 bf->bf_seqno);
428 bf->bf_state.bf_type |= BUF_XRETRY; 455 spin_unlock_bh(&txq->axq_lock);
429 ath_tx_rc_status(bf, ds, nbad, 456
430 0, false); 457 bf->bf_state.bf_type |=
431 ath_tx_complete_buf(sc, bf, txq, 458 BUF_XRETRY;
432 &bf_head, 0, 0); 459 ath_tx_rc_status(bf, ts, nbad,
433 break; 460 0, false);
461 ath_tx_complete_buf(sc, bf, txq,
462 &bf_head,
463 ts, 0, 0);
464 break;
465 }
466
467 ath9k_hw_cleartxdesc(sc->sc_ah,
468 tbf->bf_desc);
469 list_add_tail(&tbf->list, &bf_head);
470 } else {
471 /*
472 * Clear descriptor status words for
473 * software retry
474 */
475 ath9k_hw_cleartxdesc(sc->sc_ah,
476 bf->bf_desc);
434 } 477 }
435
436 ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
437 list_add_tail(&tbf->list, &bf_head);
438 } else {
439 /*
440 * Clear descriptor status words for
441 * software retry
442 */
443 ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
444 } 478 }
445 479
446 /* 480 /*
@@ -508,12 +542,13 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
508 break; 542 break;
509 } 543 }
510 544
511 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) 545 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
512 modeidx = MCS_HT40_SGI;
513 else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
514 modeidx = MCS_HT40; 546 modeidx = MCS_HT40;
515 else 547 else
516 modeidx = MCS_DEFAULT; 548 modeidx = MCS_HT20;
549
550 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
551 modeidx++;
517 552
518 frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; 553 frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
519 max_4ms_framelen = min(max_4ms_framelen, frmlen); 554 max_4ms_framelen = min(max_4ms_framelen, frmlen);
@@ -558,7 +593,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
558 u32 nsymbits, nsymbols; 593 u32 nsymbits, nsymbols;
559 u16 minlen; 594 u16 minlen;
560 u8 flags, rix; 595 u8 flags, rix;
561 int width, half_gi, ndelim, mindelim; 596 int width, streams, half_gi, ndelim, mindelim;
562 597
563 /* Select standard number of delimiters based on frame length alone */ 598 /* Select standard number of delimiters based on frame length alone */
564 ndelim = ATH_AGGR_GET_NDELIM(frmlen); 599 ndelim = ATH_AGGR_GET_NDELIM(frmlen);
@@ -598,7 +633,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
598 if (nsymbols == 0) 633 if (nsymbols == 0)
599 nsymbols = 1; 634 nsymbols = 1;
600 635
601 nsymbits = bits_per_symbol[rix][width]; 636 streams = HT_RC_2_STREAMS(rix);
637 nsymbits = bits_per_symbol[rix % 8][width] * streams;
602 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; 638 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
603 639
604 if (frmlen < minlen) { 640 if (frmlen < minlen) {
@@ -664,7 +700,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
664 bpad = PADBYTES(al_delta) + (ndelim << 2); 700 bpad = PADBYTES(al_delta) + (ndelim << 2);
665 701
666 bf->bf_next = NULL; 702 bf->bf_next = NULL;
667 bf->bf_desc->ds_link = 0; 703 ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
668 704
669 /* link buffers of this frame to the aggregate */ 705 /* link buffers of this frame to the aggregate */
670 ath_tx_addto_baw(sc, tid, bf); 706 ath_tx_addto_baw(sc, tid, bf);
@@ -672,7 +708,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
672 list_move_tail(&bf->list, bf_q); 708 list_move_tail(&bf->list, bf_q);
673 if (bf_prev) { 709 if (bf_prev) {
674 bf_prev->bf_next = bf; 710 bf_prev->bf_next = bf;
675 bf_prev->bf_desc->ds_link = bf->bf_daddr; 711 ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
712 bf->bf_daddr);
676 } 713 }
677 bf_prev = bf; 714 bf_prev = bf;
678 715
@@ -752,8 +789,11 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
752 struct ath_node *an = (struct ath_node *)sta->drv_priv; 789 struct ath_node *an = (struct ath_node *)sta->drv_priv;
753 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); 790 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
754 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; 791 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
792 struct ath_tx_status ts;
755 struct ath_buf *bf; 793 struct ath_buf *bf;
756 struct list_head bf_head; 794 struct list_head bf_head;
795
796 memset(&ts, 0, sizeof(ts));
757 INIT_LIST_HEAD(&bf_head); 797 INIT_LIST_HEAD(&bf_head);
758 798
759 if (txtid->state & AGGR_CLEANUP) 799 if (txtid->state & AGGR_CLEANUP)
@@ -780,7 +820,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
780 } 820 }
781 list_move_tail(&bf->list, &bf_head); 821 list_move_tail(&bf->list, &bf_head);
782 ath_tx_update_baw(sc, txtid, bf->bf_seqno); 822 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
783 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 823 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
784 } 824 }
785 spin_unlock_bh(&txq->axq_lock); 825 spin_unlock_bh(&txq->axq_lock);
786 826
@@ -849,7 +889,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
849 struct ath_hw *ah = sc->sc_ah; 889 struct ath_hw *ah = sc->sc_ah;
850 struct ath_common *common = ath9k_hw_common(ah); 890 struct ath_common *common = ath9k_hw_common(ah);
851 struct ath9k_tx_queue_info qi; 891 struct ath9k_tx_queue_info qi;
852 int qnum; 892 int qnum, i;
853 893
854 memset(&qi, 0, sizeof(qi)); 894 memset(&qi, 0, sizeof(qi));
855 qi.tqi_subtype = subtype; 895 qi.tqi_subtype = subtype;
@@ -873,11 +913,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
873 * The UAPSD queue is an exception, since we take a desc- 913 * The UAPSD queue is an exception, since we take a desc-
874 * based intr on the EOSP frames. 914 * based intr on the EOSP frames.
875 */ 915 */
876 if (qtype == ATH9K_TX_QUEUE_UAPSD) 916 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
877 qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; 917 qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
878 else 918 TXQ_FLAG_TXERRINT_ENABLE;
879 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | 919 } else {
880 TXQ_FLAG_TXDESCINT_ENABLE; 920 if (qtype == ATH9K_TX_QUEUE_UAPSD)
921 qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
922 else
923 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
924 TXQ_FLAG_TXDESCINT_ENABLE;
925 }
881 qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); 926 qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
882 if (qnum == -1) { 927 if (qnum == -1) {
883 /* 928 /*
@@ -904,6 +949,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
904 txq->axq_depth = 0; 949 txq->axq_depth = 0;
905 txq->axq_tx_inprogress = false; 950 txq->axq_tx_inprogress = false;
906 sc->tx.txqsetup |= 1<<qnum; 951 sc->tx.txqsetup |= 1<<qnum;
952
953 txq->txq_headidx = txq->txq_tailidx = 0;
954 for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
955 INIT_LIST_HEAD(&txq->txq_fifo[i]);
956 INIT_LIST_HEAD(&txq->txq_fifo_pending);
907 } 957 }
908 return &sc->tx.txq[qnum]; 958 return &sc->tx.txq[qnum];
909} 959}
@@ -1028,45 +1078,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1028{ 1078{
1029 struct ath_buf *bf, *lastbf; 1079 struct ath_buf *bf, *lastbf;
1030 struct list_head bf_head; 1080 struct list_head bf_head;
1081 struct ath_tx_status ts;
1031 1082
1083 memset(&ts, 0, sizeof(ts));
1032 INIT_LIST_HEAD(&bf_head); 1084 INIT_LIST_HEAD(&bf_head);
1033 1085
1034 for (;;) { 1086 for (;;) {
1035 spin_lock_bh(&txq->axq_lock); 1087 spin_lock_bh(&txq->axq_lock);
1036 1088
1037 if (list_empty(&txq->axq_q)) { 1089 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
1038 txq->axq_link = NULL; 1090 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
1039 spin_unlock_bh(&txq->axq_lock); 1091 txq->txq_headidx = txq->txq_tailidx = 0;
1040 break; 1092 spin_unlock_bh(&txq->axq_lock);
1041 } 1093 break;
1042 1094 } else {
1043 bf = list_first_entry(&txq->axq_q, struct ath_buf, list); 1095 bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
1096 struct ath_buf, list);
1097 }
1098 } else {
1099 if (list_empty(&txq->axq_q)) {
1100 txq->axq_link = NULL;
1101 spin_unlock_bh(&txq->axq_lock);
1102 break;
1103 }
1104 bf = list_first_entry(&txq->axq_q, struct ath_buf,
1105 list);
1044 1106
1045 if (bf->bf_stale) { 1107 if (bf->bf_stale) {
1046 list_del(&bf->list); 1108 list_del(&bf->list);
1047 spin_unlock_bh(&txq->axq_lock); 1109 spin_unlock_bh(&txq->axq_lock);
1048 1110
1049 spin_lock_bh(&sc->tx.txbuflock); 1111 ath_tx_return_buffer(sc, bf);
1050 list_add_tail(&bf->list, &sc->tx.txbuf); 1112 continue;
1051 spin_unlock_bh(&sc->tx.txbuflock); 1113 }
1052 continue;
1053 } 1114 }
1054 1115
1055 lastbf = bf->bf_lastbf; 1116 lastbf = bf->bf_lastbf;
1056 if (!retry_tx) 1117 if (!retry_tx)
1057 lastbf->bf_desc->ds_txstat.ts_flags = 1118 lastbf->bf_tx_aborted = true;
1058 ATH9K_TX_SW_ABORTED; 1119
1120 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
1121 list_cut_position(&bf_head,
1122 &txq->txq_fifo[txq->txq_tailidx],
1123 &lastbf->list);
1124 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
1125 } else {
1126 /* remove ath_buf's of the same mpdu from txq */
1127 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
1128 }
1059 1129
1060 /* remove ath_buf's of the same mpdu from txq */
1061 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
1062 txq->axq_depth--; 1130 txq->axq_depth--;
1063 1131
1064 spin_unlock_bh(&txq->axq_lock); 1132 spin_unlock_bh(&txq->axq_lock);
1065 1133
1066 if (bf_isampdu(bf)) 1134 if (bf_isampdu(bf))
1067 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); 1135 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0);
1068 else 1136 else
1069 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 1137 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
1070 } 1138 }
1071 1139
1072 spin_lock_bh(&txq->axq_lock); 1140 spin_lock_bh(&txq->axq_lock);
@@ -1081,6 +1149,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1081 spin_unlock_bh(&txq->axq_lock); 1149 spin_unlock_bh(&txq->axq_lock);
1082 } 1150 }
1083 } 1151 }
1152
1153 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
1154 spin_lock_bh(&txq->axq_lock);
1155 while (!list_empty(&txq->txq_fifo_pending)) {
1156 bf = list_first_entry(&txq->txq_fifo_pending,
1157 struct ath_buf, list);
1158 list_cut_position(&bf_head,
1159 &txq->txq_fifo_pending,
1160 &bf->bf_lastbf->list);
1161 spin_unlock_bh(&txq->axq_lock);
1162
1163 if (bf_isampdu(bf))
1164 ath_tx_complete_aggr(sc, txq, bf, &bf_head,
1165 &ts, 0);
1166 else
1167 ath_tx_complete_buf(sc, bf, txq, &bf_head,
1168 &ts, 0, 0);
1169 spin_lock_bh(&txq->axq_lock);
1170 }
1171 spin_unlock_bh(&txq->axq_lock);
1172 }
1084} 1173}
1085 1174
1086void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) 1175void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
@@ -1218,44 +1307,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1218 1307
1219 bf = list_first_entry(head, struct ath_buf, list); 1308 bf = list_first_entry(head, struct ath_buf, list);
1220 1309
1221 list_splice_tail_init(head, &txq->axq_q);
1222 txq->axq_depth++;
1223
1224 ath_print(common, ATH_DBG_QUEUE, 1310 ath_print(common, ATH_DBG_QUEUE,
1225 "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); 1311 "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
1226 1312
1227 if (txq->axq_link == NULL) { 1313 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
1314 if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
1315 list_splice_tail_init(head, &txq->txq_fifo_pending);
1316 return;
1317 }
1318 if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
1319 ath_print(common, ATH_DBG_XMIT,
1320 "Initializing tx fifo %d which "
1321 "is non-empty\n",
1322 txq->txq_headidx);
1323 INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
1324 list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
1325 INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
1228 ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); 1326 ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
1229 ath_print(common, ATH_DBG_XMIT, 1327 ath_print(common, ATH_DBG_XMIT,
1230 "TXDP[%u] = %llx (%p)\n", 1328 "TXDP[%u] = %llx (%p)\n",
1231 txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); 1329 txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
1232 } else { 1330 } else {
1233 *txq->axq_link = bf->bf_daddr; 1331 list_splice_tail_init(head, &txq->axq_q);
1234 ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
1235 txq->axq_qnum, txq->axq_link,
1236 ito64(bf->bf_daddr), bf->bf_desc);
1237 }
1238 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
1239 ath9k_hw_txstart(ah, txq->axq_qnum);
1240}
1241 1332
1242static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) 1333 if (txq->axq_link == NULL) {
1243{ 1334 ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
1244 struct ath_buf *bf = NULL; 1335 ath_print(common, ATH_DBG_XMIT,
1245 1336 "TXDP[%u] = %llx (%p)\n",
1246 spin_lock_bh(&sc->tx.txbuflock); 1337 txq->axq_qnum, ito64(bf->bf_daddr),
1247 1338 bf->bf_desc);
1248 if (unlikely(list_empty(&sc->tx.txbuf))) { 1339 } else {
1249 spin_unlock_bh(&sc->tx.txbuflock); 1340 *txq->axq_link = bf->bf_daddr;
1250 return NULL; 1341 ath_print(common, ATH_DBG_XMIT,
1342 "link[%u] (%p)=%llx (%p)\n",
1343 txq->axq_qnum, txq->axq_link,
1344 ito64(bf->bf_daddr), bf->bf_desc);
1345 }
1346 ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
1347 &txq->axq_link);
1348 ath9k_hw_txstart(ah, txq->axq_qnum);
1251 } 1349 }
1252 1350 txq->axq_depth++;
1253 bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
1254 list_del(&bf->list);
1255
1256 spin_unlock_bh(&sc->tx.txbuflock);
1257
1258 return bf;
1259} 1351}
1260 1352
1261static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, 1353static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
@@ -1402,8 +1494,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb,
1402 INCR(tid->seq_next, IEEE80211_SEQ_MAX); 1494 INCR(tid->seq_next, IEEE80211_SEQ_MAX);
1403} 1495}
1404 1496
1405static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, 1497static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
1406 struct ath_txq *txq)
1407{ 1498{
1408 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1499 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1409 int flags = 0; 1500 int flags = 0;
@@ -1414,6 +1505,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
1414 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) 1505 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
1415 flags |= ATH9K_TXDESC_NOACK; 1506 flags |= ATH9K_TXDESC_NOACK;
1416 1507
1508 if (use_ldpc)
1509 flags |= ATH9K_TXDESC_LDPC;
1510
1417 return flags; 1511 return flags;
1418} 1512}
1419 1513
@@ -1432,8 +1526,9 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
1432 pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; 1526 pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
1433 1527
1434 /* find number of symbols: PLCP + data */ 1528 /* find number of symbols: PLCP + data */
1529 streams = HT_RC_2_STREAMS(rix);
1435 nbits = (pktlen << 3) + OFDM_PLCP_BITS; 1530 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
1436 nsymbits = bits_per_symbol[rix][width]; 1531 nsymbits = bits_per_symbol[rix % 8][width] * streams;
1437 nsymbols = (nbits + nsymbits - 1) / nsymbits; 1532 nsymbols = (nbits + nsymbits - 1) / nsymbits;
1438 1533
1439 if (!half_gi) 1534 if (!half_gi)
@@ -1442,7 +1537,6 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
1442 duration = SYMBOL_TIME_HALFGI(nsymbols); 1537 duration = SYMBOL_TIME_HALFGI(nsymbols);
1443 1538
1444 /* addup duration for legacy/ht training and signal fields */ 1539 /* addup duration for legacy/ht training and signal fields */
1445 streams = HT_RC_2_STREAMS(rix);
1446 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); 1540 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
1447 1541
1448 return duration; 1542 return duration;
@@ -1513,6 +1607,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1513 series[i].Rate = rix | 0x80; 1607 series[i].Rate = rix | 0x80;
1514 series[i].PktDuration = ath_pkt_duration(sc, rix, bf, 1608 series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
1515 is_40, is_sgi, is_sp); 1609 is_40, is_sgi, is_sp);
1610 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
1611 series[i].RateFlags |= ATH9K_RATESERIES_STBC;
1516 continue; 1612 continue;
1517 } 1613 }
1518 1614
@@ -1565,15 +1661,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1565 int hdrlen; 1661 int hdrlen;
1566 __le16 fc; 1662 __le16 fc;
1567 int padpos, padsize; 1663 int padpos, padsize;
1664 bool use_ldpc = false;
1568 1665
1569 tx_info->pad[0] = 0; 1666 tx_info->pad[0] = 0;
1570 switch (txctl->frame_type) { 1667 switch (txctl->frame_type) {
1571 case ATH9K_NOT_INTERNAL: 1668 case ATH9K_IFT_NOT_INTERNAL:
1572 break; 1669 break;
1573 case ATH9K_INT_PAUSE: 1670 case ATH9K_IFT_PAUSE:
1574 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; 1671 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE;
1575 /* fall through */ 1672 /* fall through */
1576 case ATH9K_INT_UNPAUSE: 1673 case ATH9K_IFT_UNPAUSE:
1577 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; 1674 tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL;
1578 break; 1675 break;
1579 } 1676 }
@@ -1591,10 +1688,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1591 bf->bf_frmlen -= padsize; 1688 bf->bf_frmlen -= padsize;
1592 } 1689 }
1593 1690
1594 if (conf_is_ht(&hw->conf)) 1691 if (conf_is_ht(&hw->conf)) {
1595 bf->bf_state.bf_type |= BUF_HT; 1692 bf->bf_state.bf_type |= BUF_HT;
1693 if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
1694 use_ldpc = true;
1695 }
1596 1696
1597 bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); 1697 bf->bf_flags = setup_tx_flags(skb, use_ldpc);
1598 1698
1599 bf->bf_keytype = get_hw_crypto_keytype(skb); 1699 bf->bf_keytype = get_hw_crypto_keytype(skb);
1600 if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { 1700 if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
@@ -1653,8 +1753,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1653 list_add_tail(&bf->list, &bf_head); 1753 list_add_tail(&bf->list, &bf_head);
1654 1754
1655 ds = bf->bf_desc; 1755 ds = bf->bf_desc;
1656 ds->ds_link = 0; 1756 ath9k_hw_set_desc_link(ah, ds, 0);
1657 ds->ds_data = bf->bf_buf_addr;
1658 1757
1659 ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, 1758 ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
1660 bf->bf_keyix, bf->bf_keytype, bf->bf_flags); 1759 bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
@@ -1663,7 +1762,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1663 skb->len, /* segment length */ 1762 skb->len, /* segment length */
1664 true, /* first segment */ 1763 true, /* first segment */
1665 true, /* last segment */ 1764 true, /* last segment */
1666 ds); /* first descriptor */ 1765 ds, /* first descriptor */
1766 bf->bf_buf_addr,
1767 txctl->txq->axq_qnum);
1667 1768
1668 spin_lock_bh(&txctl->txq->axq_lock); 1769 spin_lock_bh(&txctl->txq->axq_lock);
1669 1770
@@ -1732,9 +1833,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1732 } 1833 }
1733 spin_unlock_bh(&txq->axq_lock); 1834 spin_unlock_bh(&txq->axq_lock);
1734 1835
1735 spin_lock_bh(&sc->tx.txbuflock); 1836 ath_tx_return_buffer(sc, bf);
1736 list_add_tail(&bf->list, &sc->tx.txbuf);
1737 spin_unlock_bh(&sc->tx.txbuflock);
1738 1837
1739 return r; 1838 return r;
1740 } 1839 }
@@ -1852,9 +1951,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1852} 1951}
1853 1952
1854static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1953static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1855 struct ath_txq *txq, 1954 struct ath_txq *txq, struct list_head *bf_q,
1856 struct list_head *bf_q, 1955 struct ath_tx_status *ts, int txok, int sendbar)
1857 int txok, int sendbar)
1858{ 1956{
1859 struct sk_buff *skb = bf->bf_mpdu; 1957 struct sk_buff *skb = bf->bf_mpdu;
1860 unsigned long flags; 1958 unsigned long flags;
@@ -1872,7 +1970,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1872 1970
1873 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1971 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1874 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1972 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1875 ath_debug_stat_tx(sc, txq, bf); 1973 ath_debug_stat_tx(sc, txq, bf, ts);
1876 1974
1877 /* 1975 /*
1878 * Return the list of ath_buf of this mpdu to free queue 1976 * Return the list of ath_buf of this mpdu to free queue
@@ -1883,23 +1981,21 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1883} 1981}
1884 1982
1885static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 1983static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1886 int txok) 1984 struct ath_tx_status *ts, int txok)
1887{ 1985{
1888 struct ath_buf *bf_last = bf->bf_lastbf;
1889 struct ath_desc *ds = bf_last->bf_desc;
1890 u16 seq_st = 0; 1986 u16 seq_st = 0;
1891 u32 ba[WME_BA_BMP_SIZE >> 5]; 1987 u32 ba[WME_BA_BMP_SIZE >> 5];
1892 int ba_index; 1988 int ba_index;
1893 int nbad = 0; 1989 int nbad = 0;
1894 int isaggr = 0; 1990 int isaggr = 0;
1895 1991
1896 if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) 1992 if (bf->bf_tx_aborted)
1897 return 0; 1993 return 0;
1898 1994
1899 isaggr = bf_isaggr(bf); 1995 isaggr = bf_isaggr(bf);
1900 if (isaggr) { 1996 if (isaggr) {
1901 seq_st = ATH_DS_BA_SEQ(ds); 1997 seq_st = ts->ts_seqnum;
1902 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); 1998 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
1903 } 1999 }
1904 2000
1905 while (bf) { 2001 while (bf) {
@@ -1913,7 +2009,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1913 return nbad; 2009 return nbad;
1914} 2010}
1915 2011
1916static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 2012static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1917 int nbad, int txok, bool update_rc) 2013 int nbad, int txok, bool update_rc)
1918{ 2014{
1919 struct sk_buff *skb = bf->bf_mpdu; 2015 struct sk_buff *skb = bf->bf_mpdu;
@@ -1923,24 +2019,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1923 u8 i, tx_rateindex; 2019 u8 i, tx_rateindex;
1924 2020
1925 if (txok) 2021 if (txok)
1926 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; 2022 tx_info->status.ack_signal = ts->ts_rssi;
1927 2023
1928 tx_rateindex = ds->ds_txstat.ts_rateindex; 2024 tx_rateindex = ts->ts_rateindex;
1929 WARN_ON(tx_rateindex >= hw->max_rates); 2025 WARN_ON(tx_rateindex >= hw->max_rates);
1930 2026
1931 if (update_rc) 2027 if (ts->ts_status & ATH9K_TXERR_FILT)
1932 tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC;
1933 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1934 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 2028 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
2029 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
2030 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1935 2031
1936 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 2032 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
1937 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { 2033 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1938 if (ieee80211_is_data(hdr->frame_control)) { 2034 if (ieee80211_is_data(hdr->frame_control)) {
1939 if (ds->ds_txstat.ts_flags & 2035 if (ts->ts_flags &
1940 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) 2036 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
1941 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; 2037 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
1942 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || 2038 if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
1943 (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) 2039 (ts->ts_status & ATH9K_TXERR_FIFO))
1944 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; 2040 tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
1945 tx_info->status.ampdu_len = bf->bf_nframes; 2041 tx_info->status.ampdu_len = bf->bf_nframes;
1946 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; 2042 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
@@ -1978,6 +2074,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1978 struct ath_buf *bf, *lastbf, *bf_held = NULL; 2074 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1979 struct list_head bf_head; 2075 struct list_head bf_head;
1980 struct ath_desc *ds; 2076 struct ath_desc *ds;
2077 struct ath_tx_status ts;
1981 int txok; 2078 int txok;
1982 int status; 2079 int status;
1983 2080
@@ -2017,7 +2114,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2017 lastbf = bf->bf_lastbf; 2114 lastbf = bf->bf_lastbf;
2018 ds = lastbf->bf_desc; 2115 ds = lastbf->bf_desc;
2019 2116
2020 status = ath9k_hw_txprocdesc(ah, ds); 2117 memset(&ts, 0, sizeof(ts));
2118 status = ath9k_hw_txprocdesc(ah, ds, &ts);
2021 if (status == -EINPROGRESS) { 2119 if (status == -EINPROGRESS) {
2022 spin_unlock_bh(&txq->axq_lock); 2120 spin_unlock_bh(&txq->axq_lock);
2023 break; 2121 break;
@@ -2028,7 +2126,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2028 * can disable RX. 2126 * can disable RX.
2029 */ 2127 */
2030 if (bf->bf_isnullfunc && 2128 if (bf->bf_isnullfunc &&
2031 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2129 (ts.ts_status & ATH9K_TX_ACKED)) {
2032 if ((sc->ps_flags & PS_ENABLED)) 2130 if ((sc->ps_flags & PS_ENABLED))
2033 ath9k_enable_ps(sc); 2131 ath9k_enable_ps(sc);
2034 else 2132 else
@@ -2047,31 +2145,30 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2047 &txq->axq_q, lastbf->list.prev); 2145 &txq->axq_q, lastbf->list.prev);
2048 2146
2049 txq->axq_depth--; 2147 txq->axq_depth--;
2050 txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); 2148 txok = !(ts.ts_status & ATH9K_TXERR_MASK);
2051 txq->axq_tx_inprogress = false; 2149 txq->axq_tx_inprogress = false;
2150 if (bf_held)
2151 list_del(&bf_held->list);
2052 spin_unlock_bh(&txq->axq_lock); 2152 spin_unlock_bh(&txq->axq_lock);
2053 2153
2054 if (bf_held) { 2154 if (bf_held)
2055 spin_lock_bh(&sc->tx.txbuflock); 2155 ath_tx_return_buffer(sc, bf_held);
2056 list_move_tail(&bf_held->list, &sc->tx.txbuf);
2057 spin_unlock_bh(&sc->tx.txbuflock);
2058 }
2059 2156
2060 if (!bf_isampdu(bf)) { 2157 if (!bf_isampdu(bf)) {
2061 /* 2158 /*
2062 * This frame is sent out as a single frame. 2159 * This frame is sent out as a single frame.
2063 * Use hardware retry status for this frame. 2160 * Use hardware retry status for this frame.
2064 */ 2161 */
2065 bf->bf_retries = ds->ds_txstat.ts_longretry; 2162 bf->bf_retries = ts.ts_longretry;
2066 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2163 if (ts.ts_status & ATH9K_TXERR_XRETRY)
2067 bf->bf_state.bf_type |= BUF_XRETRY; 2164 bf->bf_state.bf_type |= BUF_XRETRY;
2068 ath_tx_rc_status(bf, ds, 0, txok, true); 2165 ath_tx_rc_status(bf, &ts, 0, txok, true);
2069 } 2166 }
2070 2167
2071 if (bf_isampdu(bf)) 2168 if (bf_isampdu(bf))
2072 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2169 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
2073 else 2170 else
2074 ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0); 2171 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
2075 2172
2076 ath_wake_mac80211_queue(sc, txq); 2173 ath_wake_mac80211_queue(sc, txq);
2077 2174
@@ -2133,10 +2230,121 @@ void ath_tx_tasklet(struct ath_softc *sc)
2133 } 2230 }
2134} 2231}
2135 2232
2233void ath_tx_edma_tasklet(struct ath_softc *sc)
2234{
2235 struct ath_tx_status txs;
2236 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2237 struct ath_hw *ah = sc->sc_ah;
2238 struct ath_txq *txq;
2239 struct ath_buf *bf, *lastbf;
2240 struct list_head bf_head;
2241 int status;
2242 int txok;
2243
2244 for (;;) {
2245 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
2246 if (status == -EINPROGRESS)
2247 break;
2248 if (status == -EIO) {
2249 ath_print(common, ATH_DBG_XMIT,
2250 "Error processing tx status\n");
2251 break;
2252 }
2253
2254 /* Skip beacon completions */
2255 if (txs.qid == sc->beacon.beaconq)
2256 continue;
2257
2258 txq = &sc->tx.txq[txs.qid];
2259
2260 spin_lock_bh(&txq->axq_lock);
2261 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
2262 spin_unlock_bh(&txq->axq_lock);
2263 return;
2264 }
2265
2266 bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
2267 struct ath_buf, list);
2268 lastbf = bf->bf_lastbf;
2269
2270 INIT_LIST_HEAD(&bf_head);
2271 list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
2272 &lastbf->list);
2273 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
2274 txq->axq_depth--;
2275 txq->axq_tx_inprogress = false;
2276 spin_unlock_bh(&txq->axq_lock);
2277
2278 txok = !(txs.ts_status & ATH9K_TXERR_MASK);
2279
2280 if (!bf_isampdu(bf)) {
2281 bf->bf_retries = txs.ts_longretry;
2282 if (txs.ts_status & ATH9K_TXERR_XRETRY)
2283 bf->bf_state.bf_type |= BUF_XRETRY;
2284 ath_tx_rc_status(bf, &txs, 0, txok, true);
2285 }
2286
2287 if (bf_isampdu(bf))
2288 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
2289 else
2290 ath_tx_complete_buf(sc, bf, txq, &bf_head,
2291 &txs, txok, 0);
2292
2293 ath_wake_mac80211_queue(sc, txq);
2294
2295 spin_lock_bh(&txq->axq_lock);
2296 if (!list_empty(&txq->txq_fifo_pending)) {
2297 INIT_LIST_HEAD(&bf_head);
2298 bf = list_first_entry(&txq->txq_fifo_pending,
2299 struct ath_buf, list);
2300 list_cut_position(&bf_head, &txq->txq_fifo_pending,
2301 &bf->bf_lastbf->list);
2302 ath_tx_txqaddbuf(sc, txq, &bf_head);
2303 } else if (sc->sc_flags & SC_OP_TXAGGR)
2304 ath_txq_schedule(sc, txq);
2305 spin_unlock_bh(&txq->axq_lock);
2306 }
2307}
2308
2136/*****************/ 2309/*****************/
2137/* Init, Cleanup */ 2310/* Init, Cleanup */
2138/*****************/ 2311/*****************/
2139 2312
2313static int ath_txstatus_setup(struct ath_softc *sc, int size)
2314{
2315 struct ath_descdma *dd = &sc->txsdma;
2316 u8 txs_len = sc->sc_ah->caps.txs_len;
2317
2318 dd->dd_desc_len = size * txs_len;
2319 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
2320 &dd->dd_desc_paddr, GFP_KERNEL);
2321 if (!dd->dd_desc)
2322 return -ENOMEM;
2323
2324 return 0;
2325}
2326
2327static int ath_tx_edma_init(struct ath_softc *sc)
2328{
2329 int err;
2330
2331 err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
2332 if (!err)
2333 ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
2334 sc->txsdma.dd_desc_paddr,
2335 ATH_TXSTATUS_RING_SIZE);
2336
2337 return err;
2338}
2339
2340static void ath_tx_edma_cleanup(struct ath_softc *sc)
2341{
2342 struct ath_descdma *dd = &sc->txsdma;
2343
2344 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2345 dd->dd_desc_paddr);
2346}
2347
2140int ath_tx_init(struct ath_softc *sc, int nbufs) 2348int ath_tx_init(struct ath_softc *sc, int nbufs)
2141{ 2349{
2142 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2350 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2145,7 +2353,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
2145 spin_lock_init(&sc->tx.txbuflock); 2353 spin_lock_init(&sc->tx.txbuflock);
2146 2354
2147 error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, 2355 error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
2148 "tx", nbufs, 1); 2356 "tx", nbufs, 1, 1);
2149 if (error != 0) { 2357 if (error != 0) {
2150 ath_print(common, ATH_DBG_FATAL, 2358 ath_print(common, ATH_DBG_FATAL,
2151 "Failed to allocate tx descriptors: %d\n", error); 2359 "Failed to allocate tx descriptors: %d\n", error);
@@ -2153,7 +2361,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
2153 } 2361 }
2154 2362
2155 error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, 2363 error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
2156 "beacon", ATH_BCBUF, 1); 2364 "beacon", ATH_BCBUF, 1, 1);
2157 if (error != 0) { 2365 if (error != 0) {
2158 ath_print(common, ATH_DBG_FATAL, 2366 ath_print(common, ATH_DBG_FATAL,
2159 "Failed to allocate beacon descriptors: %d\n", error); 2367 "Failed to allocate beacon descriptors: %d\n", error);
@@ -2162,6 +2370,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
2162 2370
2163 INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); 2371 INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
2164 2372
2373 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
2374 error = ath_tx_edma_init(sc);
2375 if (error)
2376 goto err;
2377 }
2378
2165err: 2379err:
2166 if (error != 0) 2380 if (error != 0)
2167 ath_tx_cleanup(sc); 2381 ath_tx_cleanup(sc);
@@ -2176,6 +2390,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
2176 2390
2177 if (sc->tx.txdma.dd_desc_len != 0) 2391 if (sc->tx.txdma.dd_desc_len != 0)
2178 ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); 2392 ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
2393
2394 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
2395 ath_tx_edma_cleanup(sc);
2179} 2396}
2180 2397
2181void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) 2398void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 8263633c003c..873bf526e11f 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -59,6 +59,7 @@ enum ATH_DEBUG {
59 ATH_DBG_PS = 0x00000800, 59 ATH_DBG_PS = 0x00000800,
60 ATH_DBG_HWTIMER = 0x00001000, 60 ATH_DBG_HWTIMER = 0x00001000,
61 ATH_DBG_BTCOEX = 0x00002000, 61 ATH_DBG_BTCOEX = 0x00002000,
62 ATH_DBG_WMI = 0x00004000,
62 ATH_DBG_ANY = 0xffffffff 63 ATH_DBG_ANY = 0xffffffff
63}; 64};
64 65
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index ecc9eb01f4fa..a8f81ea09f14 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -19,8 +19,8 @@
19#include "ath.h" 19#include "ath.h"
20#include "reg.h" 20#include "reg.h"
21 21
22#define REG_READ common->ops->read 22#define REG_READ (common->ops->read)
23#define REG_WRITE common->ops->write 23#define REG_WRITE (common->ops->write)
24 24
25/** 25/**
26 * ath_hw_set_bssid_mask - filter out bssids we listen 26 * ath_hw_set_bssid_mask - filter out bssids we listen
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 00489c40be0c..3f4244f56ce5 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -50,6 +50,7 @@
50 50
51#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ 51#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \
52 ATH9K_5GHZ_5470_5850 52 ATH9K_5GHZ_5470_5850
53
53/* This one skips what we call "mid band" */ 54/* This one skips what we call "mid band" */
54#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ 55#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
55 ATH9K_5GHZ_5725_5850 56 ATH9K_5GHZ_5725_5850
@@ -332,7 +333,6 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
332 ath_reg_apply_active_scan_flags(wiphy, initiator); 333 ath_reg_apply_active_scan_flags(wiphy, initiator);
333 break; 334 break;
334 } 335 }
335 return;
336} 336}
337 337
338int ath_reg_notifier_apply(struct wiphy *wiphy, 338int ath_reg_notifier_apply(struct wiphy *wiphy,
@@ -360,7 +360,7 @@ EXPORT_SYMBOL(ath_reg_notifier_apply);
360 360
361static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) 361static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
362{ 362{
363 u16 rd = ath_regd_get_eepromRD(reg); 363 u16 rd = ath_regd_get_eepromRD(reg);
364 int i; 364 int i;
365 365
366 if (rd & COUNTRY_ERD_FLAG) { 366 if (rd & COUNTRY_ERD_FLAG) {
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 3edbbcf0f548..c8f7090b27d3 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -865,7 +865,6 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
865 865
866 /* low bit of first byte of destination tells us if broadcast */ 866 /* low bit of first byte of destination tells us if broadcast */
867 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA); 867 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
868 dev->trans_start = jiffies;
869 dev->stats.tx_bytes += len; 868 dev->stats.tx_bytes += len;
870 869
871 spin_unlock_irqrestore(&priv->irqlock, flags); 870 spin_unlock_irqrestore(&priv->irqlock, flags);
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index b8807fb12c92..3a003e6803a5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -104,6 +104,7 @@
104#define B43_MMIO_MACFILTER_CONTROL 0x420 104#define B43_MMIO_MACFILTER_CONTROL 0x420
105#define B43_MMIO_MACFILTER_DATA 0x422 105#define B43_MMIO_MACFILTER_DATA 0x422
106#define B43_MMIO_RCMTA_COUNT 0x43C 106#define B43_MMIO_RCMTA_COUNT 0x43C
107#define B43_MMIO_PSM_PHY_HDR 0x492
107#define B43_MMIO_RADIO_HWENABLED_LO 0x49A 108#define B43_MMIO_RADIO_HWENABLED_LO 0x49A
108#define B43_MMIO_GPIO_CONTROL 0x49C 109#define B43_MMIO_GPIO_CONTROL 0x49C
109#define B43_MMIO_GPIO_MASK 0x49E 110#define B43_MMIO_GPIO_MASK 0x49E
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9a374ef83a22..7965b70efbab 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4349,11 +4349,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4349 b43_set_phytxctl_defaults(dev); 4349 b43_set_phytxctl_defaults(dev);
4350 4350
4351 /* Minimum Contention Window */ 4351 /* Minimum Contention Window */
4352 if (phy->type == B43_PHYTYPE_B) { 4352 if (phy->type == B43_PHYTYPE_B)
4353 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F); 4353 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F);
4354 } else { 4354 else
4355 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF); 4355 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF);
4356 }
4357 /* Maximum Contention Window */ 4356 /* Maximum Contention Window */
4358 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4357 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4359 4358
@@ -4572,6 +4571,23 @@ static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
4572 mutex_unlock(&wl->mutex); 4571 mutex_unlock(&wl->mutex);
4573} 4572}
4574 4573
4574static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
4575 struct survey_info *survey)
4576{
4577 struct b43_wl *wl = hw_to_b43_wl(hw);
4578 struct b43_wldev *dev = wl->current_dev;
4579 struct ieee80211_conf *conf = &hw->conf;
4580
4581 if (idx != 0)
4582 return -ENOENT;
4583
4584 survey->channel = conf->channel;
4585 survey->filled = SURVEY_INFO_NOISE_DBM;
4586 survey->noise = dev->stats.link_noise;
4587
4588 return 0;
4589}
4590
4575static const struct ieee80211_ops b43_hw_ops = { 4591static const struct ieee80211_ops b43_hw_ops = {
4576 .tx = b43_op_tx, 4592 .tx = b43_op_tx,
4577 .conf_tx = b43_op_conf_tx, 4593 .conf_tx = b43_op_conf_tx,
@@ -4591,6 +4607,7 @@ static const struct ieee80211_ops b43_hw_ops = {
4591 .sta_notify = b43_op_sta_notify, 4607 .sta_notify = b43_op_sta_notify,
4592 .sw_scan_start = b43_op_sw_scan_start_notifier, 4608 .sw_scan_start = b43_op_sw_scan_start_notifier,
4593 .sw_scan_complete = b43_op_sw_scan_complete_notifier, 4609 .sw_scan_complete = b43_op_sw_scan_complete_notifier,
4610 .get_survey = b43_op_get_survey,
4594 .rfkill_poll = b43_rfkill_poll, 4611 .rfkill_poll = b43_rfkill_poll,
4595}; 4612};
4596 4613
@@ -4906,8 +4923,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4906 4923
4907 /* fill hw info */ 4924 /* fill hw info */
4908 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 4925 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
4909 IEEE80211_HW_SIGNAL_DBM | 4926 IEEE80211_HW_SIGNAL_DBM;
4910 IEEE80211_HW_NOISE_DBM;
4911 4927
4912 hw->wiphy->interface_modes = 4928 hw->wiphy->interface_modes =
4913 BIT(NL80211_IFTYPE_AP) | 4929 BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 9c7cd282e46c..3d6b33775964 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -73,6 +73,22 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
73 u16 value, u8 core, bool off); 73 u16 value, u8 core, bool off);
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core); 75 u16 value, u8 core);
76static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
77
78static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
79{
80 return !chanspec->channel && !chanspec->sideband &&
81 !chanspec->b_width && !chanspec->b_freq;
82}
83
84static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
85 struct b43_chanspec *chanspec2)
86{
87 return (chanspec1->channel == chanspec2->channel &&
88 chanspec1->sideband == chanspec2->sideband &&
89 chanspec1->b_width == chanspec2->b_width &&
90 chanspec1->b_freq == chanspec2->b_freq);
91}
76 92
77void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 93void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
78{//TODO 94{//TODO
@@ -89,34 +105,44 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
89} 105}
90 106
91static void b43_chantab_radio_upload(struct b43_wldev *dev, 107static void b43_chantab_radio_upload(struct b43_wldev *dev,
92 const struct b43_nphy_channeltab_entry *e) 108 const struct b43_nphy_channeltab_entry_rev2 *e)
93{ 109{
94 b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref); 110 b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref);
95 b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); 111 b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
96 b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); 112 b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
97 b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); 113 b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
98 b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1); 114 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
99 b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2); 115
100 b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); 116 b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
101 b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); 117 b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
102 b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); 118 b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
103 b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); 119 b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
104 b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); 120 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
105 b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); 121
106 b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); 122 b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
107 b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); 123 b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
108 b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); 124 b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
109 b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); 125 b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
110 b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); 126 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
111 b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); 127
112 b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); 128 b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
113 b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); 129 b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
114 b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); 130 b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
115 b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); 131 b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
132 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
133
134 b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
135 b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
136 b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
137 b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
138 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
139
140 b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
141 b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
116} 142}
117 143
118static void b43_chantab_phy_upload(struct b43_wldev *dev, 144static void b43_chantab_phy_upload(struct b43_wldev *dev,
119 const struct b43_nphy_channeltab_entry *e) 145 const struct b43_phy_n_sfo_cfg *e)
120{ 146{
121 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a); 147 b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
122 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2); 148 b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
@@ -131,34 +157,20 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
131 //TODO 157 //TODO
132} 158}
133 159
134/* Tune the hardware to a new channel. */
135static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
136{
137 const struct b43_nphy_channeltab_entry *tabent;
138 160
139 tabent = b43_nphy_get_chantabent(dev, channel); 161/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
140 if (!tabent) 162static void b43_radio_2055_setup(struct b43_wldev *dev,
141 return -ESRCH; 163 const struct b43_nphy_channeltab_entry_rev2 *e)
164{
165 B43_WARN_ON(dev->phy.rev >= 3);
142 166
143 //FIXME enable/disable band select upper20 in RXCTL 167 b43_chantab_radio_upload(dev, e);
144 if (0 /*FIXME 5Ghz*/)
145 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20);
146 else
147 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50);
148 b43_chantab_radio_upload(dev, tabent);
149 udelay(50); 168 udelay(50);
150 b43_radio_write16(dev, B2055_VCO_CAL10, 5); 169 b43_radio_write(dev, B2055_VCO_CAL10, 0x05);
151 b43_radio_write16(dev, B2055_VCO_CAL10, 45); 170 b43_radio_write(dev, B2055_VCO_CAL10, 0x45);
152 b43_radio_write16(dev, B2055_VCO_CAL10, 65); 171 b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
172 b43_radio_write(dev, B2055_VCO_CAL10, 0x65);
153 udelay(300); 173 udelay(300);
154 if (0 /*FIXME 5Ghz*/)
155 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
156 else
157 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
158 b43_chantab_phy_upload(dev, tabent);
159 b43_nphy_tx_power_fix(dev);
160
161 return 0;
162} 174}
163 175
164static void b43_radio_init2055_pre(struct b43_wldev *dev) 176static void b43_radio_init2055_pre(struct b43_wldev *dev)
@@ -174,52 +186,64 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
174 186
175static void b43_radio_init2055_post(struct b43_wldev *dev) 187static void b43_radio_init2055_post(struct b43_wldev *dev)
176{ 188{
189 struct b43_phy_n *nphy = dev->phy.n;
177 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 190 struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
178 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); 191 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
179 int i; 192 int i;
180 u16 val; 193 u16 val;
194 bool workaround = false;
195
196 if (sprom->revision < 4)
197 workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM ||
198 binfo->type != 0x46D ||
199 binfo->rev < 0x41);
200 else
201 workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0);
181 202
182 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 203 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
183 msleep(1); 204 if (workaround) {
184 if ((sprom->revision != 4) || 205 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
185 !(sprom->boardflags_hi & B43_BFH_RSSIINV)) { 206 b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F);
186 if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
187 (binfo->type != 0x46D) ||
188 (binfo->rev < 0x41)) {
189 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
190 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
191 msleep(1);
192 }
193 } 207 }
194 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C); 208 b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C);
195 msleep(1); 209 b43_radio_write(dev, B2055_CAL_MISC, 0x3C);
196 b43_radio_write16(dev, B2055_CAL_MISC, 0x3C);
197 msleep(1);
198 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); 210 b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
199 msleep(1);
200 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); 211 b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
201 msleep(1);
202 b43_radio_set(dev, B2055_CAL_MISC, 0x1); 212 b43_radio_set(dev, B2055_CAL_MISC, 0x1);
203 msleep(1); 213 msleep(1);
204 b43_radio_set(dev, B2055_CAL_MISC, 0x40); 214 b43_radio_set(dev, B2055_CAL_MISC, 0x40);
205 msleep(1); 215 for (i = 0; i < 200; i++) {
206 for (i = 0; i < 100; i++) { 216 val = b43_radio_read(dev, B2055_CAL_COUT2);
207 val = b43_radio_read16(dev, B2055_CAL_COUT2); 217 if (val & 0x80) {
208 if (val & 0x80) 218 i = 0;
209 break; 219 break;
220 }
210 udelay(10); 221 udelay(10);
211 } 222 }
212 msleep(1); 223 if (i)
224 b43err(dev->wl, "radio post init timeout\n");
213 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 225 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
214 msleep(1);
215 nphy_channel_switch(dev, dev->phy.channel); 226 nphy_channel_switch(dev, dev->phy.channel);
216 b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); 227 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
217 b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); 228 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
218 b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 229 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
219 b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83); 230 b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
231 b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6);
232 b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6);
233 if (!nphy->gain_boost) {
234 b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2);
235 b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2);
236 } else {
237 b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD);
238 b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD);
239 }
240 udelay(2);
220} 241}
221 242
222/* Initialize a Broadcom 2055 N-radio */ 243/*
244 * Initialize a Broadcom 2055 N-radio
245 * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
246 */
223static void b43_radio_init2055(struct b43_wldev *dev) 247static void b43_radio_init2055(struct b43_wldev *dev)
224{ 248{
225 b43_radio_init2055_pre(dev); 249 b43_radio_init2055_pre(dev);
@@ -230,16 +254,15 @@ static void b43_radio_init2055(struct b43_wldev *dev)
230 b43_radio_init2055_post(dev); 254 b43_radio_init2055_post(dev);
231} 255}
232 256
233void b43_nphy_radio_turn_on(struct b43_wldev *dev) 257/*
258 * Initialize a Broadcom 2056 N-radio
259 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
260 */
261static void b43_radio_init2056(struct b43_wldev *dev)
234{ 262{
235 b43_radio_init2055(dev); 263 /* TODO */
236} 264}
237 265
238void b43_nphy_radio_turn_off(struct b43_wldev *dev)
239{
240 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
241 ~B43_NPHY_RFCTL_CMD_EN);
242}
243 266
244/* 267/*
245 * Upload the N-PHY tables. 268 * Upload the N-PHY tables.
@@ -647,6 +670,41 @@ static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
647 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); 670 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
648} 671}
649 672
673/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
674static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
675{
676 if (dev->phy.rev >= 3) {
677 if (!init)
678 return;
679 if (0 /* FIXME */) {
680 b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211);
681 b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222);
682 b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144);
683 b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188);
684 }
685 } else {
686 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
687 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
688
689 ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00,
690 0xFC00);
691 b43_write32(dev, B43_MMIO_MACCTL,
692 b43_read32(dev, B43_MMIO_MACCTL) &
693 ~B43_MACCTL_GPOUTSMSK);
694 b43_write16(dev, B43_MMIO_GPIO_MASK,
695 b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
696 b43_write16(dev, B43_MMIO_GPIO_CONTROL,
697 b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
698
699 if (init) {
700 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
701 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
702 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
703 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
704 }
705 }
706}
707
650/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ 708/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
651static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) 709static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
652{ 710{
@@ -723,7 +781,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
723{ 781{
724 struct b43_phy_n *nphy = dev->phy.n; 782 struct b43_phy_n *nphy = dev->phy.n;
725 783
726 unsigned int channel; 784 u8 channel = nphy->radio_chanspec.channel;
727 int tone[2] = { 57, 58 }; 785 int tone[2] = { 57, 58 };
728 u32 noise[2] = { 0x3FF, 0x3FF }; 786 u32 noise[2] = { 0x3FF, 0x3FF };
729 787
@@ -732,8 +790,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
732 if (nphy->hang_avoid) 790 if (nphy->hang_avoid)
733 b43_nphy_stay_in_carrier_search(dev, 1); 791 b43_nphy_stay_in_carrier_search(dev, 1);
734 792
735 /* FIXME: channel = radio_chanspec */
736
737 if (nphy->gband_spurwar_en) { 793 if (nphy->gband_spurwar_en) {
738 /* TODO: N PHY Adjust Analog Pfbw (7) */ 794 /* TODO: N PHY Adjust Analog Pfbw (7) */
739 if (channel == 11 && dev->phy.is_40mhz) 795 if (channel == 11 && dev->phy.is_40mhz)
@@ -779,6 +835,62 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
779 b43_nphy_stay_in_carrier_search(dev, 0); 835 b43_nphy_stay_in_carrier_search(dev, 0);
780} 836}
781 837
838/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
839static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
840{
841 struct b43_phy_n *nphy = dev->phy.n;
842
843 u8 i;
844 s16 tmp;
845 u16 data[4];
846 s16 gain[2];
847 u16 minmax[2];
848 u16 lna_gain[4] = { -2, 10, 19, 25 };
849
850 if (nphy->hang_avoid)
851 b43_nphy_stay_in_carrier_search(dev, 1);
852
853 if (nphy->gain_boost) {
854 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
855 gain[0] = 6;
856 gain[1] = 6;
857 } else {
858 tmp = 40370 - 315 * nphy->radio_chanspec.channel;
859 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
860 tmp = 23242 - 224 * nphy->radio_chanspec.channel;
861 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
862 }
863 } else {
864 gain[0] = 0;
865 gain[1] = 0;
866 }
867
868 for (i = 0; i < 2; i++) {
869 if (nphy->elna_gain_config) {
870 data[0] = 19 + gain[i];
871 data[1] = 25 + gain[i];
872 data[2] = 25 + gain[i];
873 data[3] = 25 + gain[i];
874 } else {
875 data[0] = lna_gain[0] + gain[i];
876 data[1] = lna_gain[1] + gain[i];
877 data[2] = lna_gain[2] + gain[i];
878 data[3] = lna_gain[3] + gain[i];
879 }
880 b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data);
881
882 minmax[i] = 23 + gain[i];
883 }
884
885 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN,
886 minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT);
887 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN,
888 minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT);
889
890 if (nphy->hang_avoid)
891 b43_nphy_stay_in_carrier_search(dev, 0);
892}
893
782/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 894/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
783static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 895static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
784{ 896{
@@ -863,7 +975,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
863 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 975 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
864 (code << 8 | 0x7C)); 976 (code << 8 | 0x7C));
865 977
866 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ 978 b43_nphy_adjust_lna_gain_table(dev);
867 979
868 if (nphy->elna_gain_config) { 980 if (nphy->elna_gain_config) {
869 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); 981 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
@@ -1970,12 +2082,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
1970 u16 *rssical_phy_regs = NULL; 2082 u16 *rssical_phy_regs = NULL;
1971 2083
1972 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2084 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1973 if (!nphy->rssical_chanspec_2G) 2085 if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
1974 return; 2086 return;
1975 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; 2087 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1976 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; 2088 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1977 } else { 2089 } else {
1978 if (!nphy->rssical_chanspec_5G) 2090 if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
1979 return; 2091 return;
1980 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; 2092 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1981 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; 2093 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2395,7 +2507,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
2395 2507
2396 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2508 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2397 u16 *txcal_radio_regs = NULL; 2509 u16 *txcal_radio_regs = NULL;
2398 u8 *iqcal_chanspec; 2510 struct b43_chanspec *iqcal_chanspec;
2399 u16 *table = NULL; 2511 u16 *table = NULL;
2400 2512
2401 if (nphy->hang_avoid) 2513 if (nphy->hang_avoid)
@@ -2451,12 +2563,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
2451 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 2563 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2452 2564
2453 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2565 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2454 if (nphy->iqcal_chanspec_2G == 0) 2566 if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
2455 return; 2567 return;
2456 table = nphy->cal_cache.txcal_coeffs_2G; 2568 table = nphy->cal_cache.txcal_coeffs_2G;
2457 loft = &nphy->cal_cache.txcal_coeffs_2G[5]; 2569 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2458 } else { 2570 } else {
2459 if (nphy->iqcal_chanspec_5G == 0) 2571 if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
2460 return; 2572 return;
2461 table = nphy->cal_cache.txcal_coeffs_5G; 2573 table = nphy->cal_cache.txcal_coeffs_5G;
2462 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2574 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2689,7 +2801,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2689 } 2801 }
2690 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, 2802 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
2691 buffer); 2803 buffer);
2692 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, 2804 b43_ntab_read_bulk(dev, B43_NTAB16(15, 101), 2,
2693 buffer); 2805 buffer);
2694 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, 2806 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
2695 buffer); 2807 buffer);
@@ -2701,8 +2813,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2701 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, 2813 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2702 nphy->txiqlocal_bestc); 2814 nphy->txiqlocal_bestc);
2703 nphy->txiqlocal_coeffsvalid = true; 2815 nphy->txiqlocal_coeffsvalid = true;
2704 /* TODO: Set nphy->txiqlocal_chanspec to 2816 nphy->txiqlocal_chanspec = nphy->radio_chanspec;
2705 the current channel */
2706 } else { 2817 } else {
2707 length = 11; 2818 length = 11;
2708 if (dev->phy.rev < 3) 2819 if (dev->phy.rev < 3)
@@ -2737,7 +2848,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2737 u16 buffer[7]; 2848 u16 buffer[7];
2738 bool equal = true; 2849 bool equal = true;
2739 2850
2740 if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */) 2851 if (!nphy->txiqlocal_coeffsvalid ||
2852 b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
2741 return; 2853 return;
2742 2854
2743 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 2855 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -3092,9 +3204,11 @@ int b43_phy_initn(struct b43_wldev *dev)
3092 do_rssi_cal = false; 3204 do_rssi_cal = false;
3093 if (phy->rev >= 3) { 3205 if (phy->rev >= 3) {
3094 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3206 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3095 do_rssi_cal = (nphy->rssical_chanspec_2G == 0); 3207 do_rssi_cal =
3208 b43_empty_chanspec(&nphy->rssical_chanspec_2G);
3096 else 3209 else
3097 do_rssi_cal = (nphy->rssical_chanspec_5G == 0); 3210 do_rssi_cal =
3211 b43_empty_chanspec(&nphy->rssical_chanspec_5G);
3098 3212
3099 if (do_rssi_cal) 3213 if (do_rssi_cal)
3100 b43_nphy_rssi_cal(dev); 3214 b43_nphy_rssi_cal(dev);
@@ -3106,9 +3220,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3106 3220
3107 if (!((nphy->measure_hold & 0x6) != 0)) { 3221 if (!((nphy->measure_hold & 0x6) != 0)) {
3108 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3222 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3109 do_cal = (nphy->iqcal_chanspec_2G == 0); 3223 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
3110 else 3224 else
3111 do_cal = (nphy->iqcal_chanspec_5G == 0); 3225 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
3112 3226
3113 if (nphy->mute) 3227 if (nphy->mute)
3114 do_cal = false; 3228 do_cal = false;
@@ -3117,7 +3231,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3117 target = b43_nphy_get_tx_gains(dev); 3231 target = b43_nphy_get_tx_gains(dev);
3118 3232
3119 if (nphy->antsel_type == 2) 3233 if (nphy->antsel_type == 2)
3120 ;/*TODO NPHY Superswitch Init with argument 1*/ 3234 b43_nphy_superswitch_init(dev, true);
3121 if (nphy->perical != 2) { 3235 if (nphy->perical != 2) {
3122 b43_nphy_rssi_cal(dev); 3236 b43_nphy_rssi_cal(dev);
3123 if (phy->rev >= 3) { 3237 if (phy->rev >= 3) {
@@ -3155,6 +3269,133 @@ int b43_phy_initn(struct b43_wldev *dev)
3155 return 0; 3269 return 0;
3156} 3270}
3157 3271
3272/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
3273static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3274 const struct b43_phy_n_sfo_cfg *e,
3275 struct b43_chanspec chanspec)
3276{
3277 struct b43_phy *phy = &dev->phy;
3278 struct b43_phy_n *nphy = dev->phy.n;
3279
3280 u16 tmp;
3281 u32 tmp32;
3282
3283 tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3284 if (chanspec.b_freq == 1 && tmp == 0) {
3285 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3286 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3287 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3288 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3289 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3290 } else if (chanspec.b_freq == 1) {
3291 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3292 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3293 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3294 b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000);
3295 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3296 }
3297
3298 b43_chantab_phy_upload(dev, e);
3299
3300 tmp = chanspec.channel;
3301 if (chanspec.b_freq == 1)
3302 tmp |= 0x0100;
3303 if (chanspec.b_width == 3)
3304 tmp |= 0x0200;
3305 b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
3306
3307 if (nphy->radio_chanspec.channel == 14) {
3308 b43_nphy_classifier(dev, 2, 0);
3309 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
3310 } else {
3311 b43_nphy_classifier(dev, 2, 2);
3312 if (chanspec.b_freq == 2)
3313 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
3314 }
3315
3316 if (nphy->txpwrctrl)
3317 b43_nphy_tx_power_fix(dev);
3318
3319 if (dev->phy.rev < 3)
3320 b43_nphy_adjust_lna_gain_table(dev);
3321
3322 b43_nphy_tx_lp_fbw(dev);
3323
3324 if (dev->phy.rev >= 3 && 0) {
3325 /* TODO */
3326 }
3327
3328 b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);
3329
3330 if (phy->rev >= 3)
3331 b43_nphy_spur_workaround(dev);
3332}
3333
3334/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
3335static int b43_nphy_set_chanspec(struct b43_wldev *dev,
3336 struct b43_chanspec chanspec)
3337{
3338 struct b43_phy_n *nphy = dev->phy.n;
3339
3340 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
3341 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
3342
3343 u8 tmp;
3344 u8 channel = chanspec.channel;
3345
3346 if (dev->phy.rev >= 3) {
3347 /* TODO */
3348 tabent_r3 = NULL;
3349 if (!tabent_r3)
3350 return -ESRCH;
3351 } else {
3352 tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
3353 if (!tabent_r2)
3354 return -ESRCH;
3355 }
3356
3357 nphy->radio_chanspec = chanspec;
3358
3359 if (chanspec.b_width != nphy->b_width)
3360 ; /* TODO: BMAC BW Set (chanspec.b_width) */
3361
3362 /* TODO: use defines */
3363 if (chanspec.b_width == 3) {
3364 if (chanspec.sideband == 2)
3365 b43_phy_set(dev, B43_NPHY_RXCTL,
3366 B43_NPHY_RXCTL_BSELU20);
3367 else
3368 b43_phy_mask(dev, B43_NPHY_RXCTL,
3369 ~B43_NPHY_RXCTL_BSELU20);
3370 }
3371
3372 if (dev->phy.rev >= 3) {
3373 tmp = (chanspec.b_freq == 1) ? 4 : 0;
3374 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3375 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
3376 b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
3377 } else {
3378 tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
3379 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
3380 b43_radio_2055_setup(dev, tabent_r2);
3381 b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
3382 }
3383
3384 return 0;
3385}
3386
3387/* Tune the hardware to a new channel */
3388static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
3389{
3390 struct b43_phy_n *nphy = dev->phy.n;
3391
3392 struct b43_chanspec chanspec;
3393 chanspec = nphy->radio_chanspec;
3394 chanspec.channel = channel;
3395
3396 return b43_nphy_set_chanspec(dev, chanspec);
3397}
3398
3158static int b43_nphy_op_allocate(struct b43_wldev *dev) 3399static int b43_nphy_op_allocate(struct b43_wldev *dev)
3159{ 3400{
3160 struct b43_phy_n *nphy; 3401 struct b43_phy_n *nphy;
@@ -3243,9 +3484,43 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3243 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); 3484 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
3244} 3485}
3245 3486
3487/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
3246static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 3488static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3247 bool blocked) 3489 bool blocked)
3248{//TODO 3490{
3491 struct b43_phy_n *nphy = dev->phy.n;
3492
3493 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3494 b43err(dev->wl, "MAC not suspended\n");
3495
3496 if (blocked) {
3497 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3498 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3499 if (dev->phy.rev >= 3) {
3500 b43_radio_mask(dev, 0x09, ~0x2);
3501
3502 b43_radio_write(dev, 0x204D, 0);
3503 b43_radio_write(dev, 0x2053, 0);
3504 b43_radio_write(dev, 0x2058, 0);
3505 b43_radio_write(dev, 0x205E, 0);
3506 b43_radio_mask(dev, 0x2062, ~0xF0);
3507 b43_radio_write(dev, 0x2064, 0);
3508
3509 b43_radio_write(dev, 0x304D, 0);
3510 b43_radio_write(dev, 0x3053, 0);
3511 b43_radio_write(dev, 0x3058, 0);
3512 b43_radio_write(dev, 0x305E, 0);
3513 b43_radio_mask(dev, 0x3062, ~0xF0);
3514 b43_radio_write(dev, 0x3064, 0);
3515 }
3516 } else {
3517 if (dev->phy.rev >= 3) {
3518 b43_radio_init2056(dev);
3519 b43_nphy_set_chanspec(dev, nphy->radio_chanspec);
3520 } else {
3521 b43_radio_init2055(dev);
3522 }
3523 }
3249} 3524}
3250 3525
3251static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) 3526static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 403aad3f894f..8b6d570dd0aa 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -711,6 +711,8 @@
711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ 711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ 712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
713 713
714#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
715#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
714 716
715 717
716/* Broadcom 2055 radio registers */ 718/* Broadcom 2055 radio registers */
@@ -924,6 +926,13 @@
924 926
925struct b43_wldev; 927struct b43_wldev;
926 928
929struct b43_chanspec {
930 u8 channel;
931 u8 sideband;
932 u8 b_width;
933 u8 b_freq;
934};
935
927struct b43_phy_n_iq_comp { 936struct b43_phy_n_iq_comp {
928 s16 a0; 937 s16 a0;
929 s16 b0; 938 s16 b0;
@@ -975,7 +984,8 @@ struct b43_phy_n {
975 u16 papd_epsilon_offset[2]; 984 u16 papd_epsilon_offset[2];
976 s32 preamble_override; 985 s32 preamble_override;
977 u32 bb_mult_save; 986 u32 bb_mult_save;
978 u16 radio_chanspec; 987 u8 b_width;
988 struct b43_chanspec radio_chanspec;
979 989
980 bool gain_boost; 990 bool gain_boost;
981 bool elna_gain_config; 991 bool elna_gain_config;
@@ -991,6 +1001,7 @@ struct b43_phy_n {
991 u16 txiqlocal_bestc[11]; 1001 u16 txiqlocal_bestc[11];
992 bool txiqlocal_coeffsvalid; 1002 bool txiqlocal_coeffsvalid;
993 struct b43_phy_n_txpwrindex txpwrindex[2]; 1003 struct b43_phy_n_txpwrindex txpwrindex[2];
1004 struct b43_chanspec txiqlocal_chanspec;
994 1005
995 u8 txrx_chain; 1006 u8 txrx_chain;
996 u16 tx_rx_cal_phy_saveregs[11]; 1007 u16 tx_rx_cal_phy_saveregs[11];
@@ -1006,12 +1017,12 @@ struct b43_phy_n {
1006 bool gband_spurwar_en; 1017 bool gband_spurwar_en;
1007 1018
1008 bool ipa2g_on; 1019 bool ipa2g_on;
1009 u8 iqcal_chanspec_2G; 1020 struct b43_chanspec iqcal_chanspec_2G;
1010 u8 rssical_chanspec_2G; 1021 struct b43_chanspec rssical_chanspec_2G;
1011 1022
1012 bool ipa5g_on; 1023 bool ipa5g_on;
1013 u8 iqcal_chanspec_5G; 1024 struct b43_chanspec iqcal_chanspec_5G;
1014 u8 rssical_chanspec_5G; 1025 struct b43_chanspec rssical_chanspec_5G;
1015 1026
1016 struct b43_phy_n_rssical_cache rssical_cache; 1027 struct b43_phy_n_rssical_cache rssical_cache;
1017 struct b43_phy_n_cal_cache cal_cache; 1028 struct b43_phy_n_cal_cache cal_cache;
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index a00d509150f7..d96e870ab8fe 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -318,14 +318,14 @@ void b2055_upload_inittab(struct b43_wldev *dev,
318 .radio_c2_tx_mxbgtrim = r21 318 .radio_c2_tx_mxbgtrim = r21
319 319
320#define PHYREGS(r0, r1, r2, r3, r4, r5) \ 320#define PHYREGS(r0, r1, r2, r3, r4, r5) \
321 .phy_bw1a = r0, \ 321 .phy_regs.phy_bw1a = r0, \
322 .phy_bw2 = r1, \ 322 .phy_regs.phy_bw2 = r1, \
323 .phy_bw3 = r2, \ 323 .phy_regs.phy_bw3 = r2, \
324 .phy_bw4 = r3, \ 324 .phy_regs.phy_bw4 = r3, \
325 .phy_bw5 = r4, \ 325 .phy_regs.phy_bw5 = r4, \
326 .phy_bw6 = r5 326 .phy_regs.phy_bw6 = r5
327 327
328static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = { 328static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = {
329 { .channel = 184, 329 { .channel = 184,
330 .freq = 4920, /* MHz */ 330 .freq = 4920, /* MHz */
331 .unk2 = 3280, 331 .unk2 = 3280,
@@ -1320,10 +1320,10 @@ static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = {
1320 }, 1320 },
1321}; 1321};
1322 1322
1323const struct b43_nphy_channeltab_entry * 1323const struct b43_nphy_channeltab_entry_rev2 *
1324b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel) 1324b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel)
1325{ 1325{
1326 const struct b43_nphy_channeltab_entry *e; 1326 const struct b43_nphy_channeltab_entry_rev2 *e;
1327 unsigned int i; 1327 unsigned int i;
1328 1328
1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) { 1329 for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 9c1c6ecd3672..8fc1da9f8fe5 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -4,9 +4,22 @@
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6 6
7struct b43_nphy_channeltab_entry { 7struct b43_phy_n_sfo_cfg {
8 u16 phy_bw1a;
9 u16 phy_bw2;
10 u16 phy_bw3;
11 u16 phy_bw4;
12 u16 phy_bw5;
13 u16 phy_bw6;
14};
15
16struct b43_nphy_channeltab_entry_rev2 {
8 /* The channel number */ 17 /* The channel number */
9 u8 channel; 18 u8 channel;
19 /* The channel frequency in MHz */
20 u16 freq;
21 /* An unknown value */
22 u16 unk2;
10 /* Radio register values on channelswitch */ 23 /* Radio register values on channelswitch */
11 u8 radio_pll_ref; 24 u8 radio_pll_ref;
12 u8 radio_rf_pllmod0; 25 u8 radio_rf_pllmod0;
@@ -31,16 +44,18 @@ struct b43_nphy_channeltab_entry {
31 u8 radio_c2_tx_pgapadtn; 44 u8 radio_c2_tx_pgapadtn;
32 u8 radio_c2_tx_mxbgtrim; 45 u8 radio_c2_tx_mxbgtrim;
33 /* PHY register values on channelswitch */ 46 /* PHY register values on channelswitch */
34 u16 phy_bw1a; 47 struct b43_phy_n_sfo_cfg phy_regs;
35 u16 phy_bw2; 48};
36 u16 phy_bw3; 49
37 u16 phy_bw4; 50struct b43_nphy_channeltab_entry_rev3 {
38 u16 phy_bw5; 51 /* The channel number */
39 u16 phy_bw6; 52 u8 channel;
40 /* The channel frequency in MHz */ 53 /* The channel frequency in MHz */
41 u16 freq; 54 u16 freq;
42 /* An unknown value */ 55 /* Radio register values on channelswitch */
43 u16 unk2; 56 /* TODO */
57 /* PHY register values on channelswitch */
58 struct b43_phy_n_sfo_cfg phy_regs;
44}; 59};
45 60
46 61
@@ -77,8 +92,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
77 92
78/* Get the NPHY Channel Switch Table entry for a channel number. 93/* Get the NPHY Channel Switch Table entry for a channel number.
79 * Returns NULL on failure to find an entry. */ 94 * Returns NULL on failure to find an entry. */
80const struct b43_nphy_channeltab_entry * 95const struct b43_nphy_channeltab_entry_rev2 *
81b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); 96b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel);
82 97
83 98
84/* The N-PHY tables. */ 99/* The N-PHY tables. */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index eda06529ef5f..e6b0528f3b52 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -610,7 +610,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
610 } 610 }
611 611
612 /* Link quality statistics */ 612 /* Link quality statistics */
613 status.noise = dev->stats.link_noise;
614 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { 613 if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
615// s8 rssi = max(rxhdr->power0, rxhdr->power1); 614// s8 rssi = max(rxhdr->power0, rxhdr->power1);
616 //TODO: Find out what the rssi value is (dBm or percentage?) 615 //TODO: Find out what the rssi value is (dBm or percentage?)
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index bb2dd9329aa0..1713f5f7a58b 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3482,6 +3482,23 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
3482 return 0; 3482 return 0;
3483} 3483}
3484 3484
3485static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
3486 struct survey_info *survey)
3487{
3488 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3489 struct b43legacy_wldev *dev = wl->current_dev;
3490 struct ieee80211_conf *conf = &hw->conf;
3491
3492 if (idx != 0)
3493 return -ENOENT;
3494
3495 survey->channel = conf->channel;
3496 survey->filled = SURVEY_INFO_NOISE_DBM;
3497 survey->noise = dev->stats.link_noise;
3498
3499 return 0;
3500}
3501
3485static const struct ieee80211_ops b43legacy_hw_ops = { 3502static const struct ieee80211_ops b43legacy_hw_ops = {
3486 .tx = b43legacy_op_tx, 3503 .tx = b43legacy_op_tx,
3487 .conf_tx = b43legacy_op_conf_tx, 3504 .conf_tx = b43legacy_op_conf_tx,
@@ -3494,6 +3511,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3494 .start = b43legacy_op_start, 3511 .start = b43legacy_op_start,
3495 .stop = b43legacy_op_stop, 3512 .stop = b43legacy_op_stop,
3496 .set_tim = b43legacy_op_beacon_set_tim, 3513 .set_tim = b43legacy_op_beacon_set_tim,
3514 .get_survey = b43legacy_op_get_survey,
3497 .rfkill_poll = b43legacy_rfkill_poll, 3515 .rfkill_poll = b43legacy_rfkill_poll,
3498}; 3516};
3499 3517
@@ -3769,8 +3787,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3769 3787
3770 /* fill hw info */ 3788 /* fill hw info */
3771 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 3789 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
3772 IEEE80211_HW_SIGNAL_DBM | 3790 IEEE80211_HW_SIGNAL_DBM;
3773 IEEE80211_HW_NOISE_DBM;
3774 hw->wiphy->interface_modes = 3791 hw->wiphy->interface_modes =
3775 BIT(NL80211_IFTYPE_AP) | 3792 BIT(NL80211_IFTYPE_AP) |
3776 BIT(NL80211_IFTYPE_STATION) | 3793 BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 9c8882d9275e..7d177d97f1f7 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -548,7 +548,6 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
548 (phystat0 & B43legacy_RX_PHYST0_OFDM), 548 (phystat0 & B43legacy_RX_PHYST0_OFDM),
549 (phystat0 & B43legacy_RX_PHYST0_GAINCTL), 549 (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
550 (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); 550 (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
551 status.noise = dev->stats.link_noise;
552 /* change to support A PHY */ 551 /* change to support A PHY */
553 if (phystat0 & B43legacy_RX_PHYST0_OFDM) 552 if (phystat0 & B43legacy_RX_PHYST0_OFDM)
554 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); 553 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index f4c56121d387..e0b3e8d406b3 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -355,8 +355,7 @@ static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
355 list_del(&bss->list); 355 list_del(&bss->list);
356 local->num_bss_info--; 356 local->num_bss_info--;
357 } else { 357 } else {
358 bss = (struct hostap_bss_info *) 358 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
359 kmalloc(sizeof(*bss), GFP_ATOMIC);
360 if (bss == NULL) 359 if (bss == NULL)
361 return NULL; 360 return NULL;
362 } 361 }
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 7e72ac1de49b..231dbd77f5f5 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -349,7 +349,7 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
349 default: 349 default:
350 policy_txt = "unknown"; 350 policy_txt = "unknown";
351 break; 351 break;
352 }; 352 }
353 p += sprintf(p, "MAC policy: %s\n", policy_txt); 353 p += sprintf(p, "MAC policy: %s\n", policy_txt);
354 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries); 354 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
355 p += sprintf(p, "MAC list:\n"); 355 p += sprintf(p, "MAC list:\n");
diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c
index 89d3849abfe0..e73bf739fd9b 100644
--- a/drivers/net/wireless/hostap/hostap_download.c
+++ b/drivers/net/wireless/hostap/hostap_download.c
@@ -744,7 +744,7 @@ static int prism2_download(local_info_t *local,
744 local->dev->name, param->dl_cmd); 744 local->dev->name, param->dl_cmd);
745 ret = -EINVAL; 745 ret = -EINVAL;
746 break; 746 break;
747 }; 747 }
748 748
749 out: 749 out:
750 if (ret == 0 && dl && 750 if (ret == 0 && dl &&
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 9a082308a9d4..a85e43a8d758 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3039,8 +3039,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
3039 p->length > 1024 || !p->pointer) 3039 p->length > 1024 || !p->pointer)
3040 return -EINVAL; 3040 return -EINVAL;
3041 3041
3042 param = (struct prism2_download_param *) 3042 param = kmalloc(p->length, GFP_KERNEL);
3043 kmalloc(p->length, GFP_KERNEL);
3044 if (param == NULL) 3043 if (param == NULL)
3045 return -ENOMEM; 3044 return -ENOMEM;
3046 3045
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 2b05fe5e994c..0bd4dfa59a8a 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2141,7 +2141,7 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2141 DECLARE_SSID_BUF(ssid); 2141 DECLARE_SSID_BUF(ssid);
2142 2142
2143 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, 2143 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
2144 "disassociated: '%s' %pM \n", 2144 "disassociated: '%s' %pM\n",
2145 print_ssid(ssid, priv->essid, priv->essid_len), 2145 print_ssid(ssid, priv->essid, priv->essid_len),
2146 priv->bssid); 2146 priv->bssid);
2147 2147
@@ -3240,7 +3240,6 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3240 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX, 3240 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3241 txq->next); 3241 txq->next);
3242 } 3242 }
3243 return;
3244} 3243}
3245 3244
3246static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) 3245static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3286,7 +3285,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3286 3285
3287 if (inta & IPW2100_INTA_PARITY_ERROR) { 3286 if (inta & IPW2100_INTA_PARITY_ERROR) {
3288 printk(KERN_ERR DRV_NAME 3287 printk(KERN_ERR DRV_NAME
3289 ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3288 ": ***** PARITY ERROR INTERRUPT !!!!\n");
3290 priv->inta_other++; 3289 priv->inta_other++;
3291 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR); 3290 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3292 } 3291 }
@@ -6103,7 +6102,7 @@ static const struct net_device_ops ipw2100_netdev_ops = {
6103 .ndo_validate_addr = eth_validate_addr, 6102 .ndo_validate_addr = eth_validate_addr,
6104}; 6103};
6105 6104
6106/* Look into using netdev destructor to shutdown ieee80211? */ 6105/* Look into using netdev destructor to shutdown libipw? */
6107 6106
6108static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, 6107static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6109 void __iomem * base_addr, 6108 void __iomem * base_addr,
@@ -6113,7 +6112,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6113 struct ipw2100_priv *priv; 6112 struct ipw2100_priv *priv;
6114 struct net_device *dev; 6113 struct net_device *dev;
6115 6114
6116 dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); 6115 dev = alloc_libipw(sizeof(struct ipw2100_priv), 0);
6117 if (!dev) 6116 if (!dev)
6118 return NULL; 6117 return NULL;
6119 priv = libipw_priv(dev); 6118 priv = libipw_priv(dev);
@@ -6426,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6426 sysfs_remove_group(&pci_dev->dev.kobj, 6425 sysfs_remove_group(&pci_dev->dev.kobj,
6427 &ipw2100_attribute_group); 6426 &ipw2100_attribute_group);
6428 6427
6429 free_ieee80211(dev, 0); 6428 free_libipw(dev, 0);
6430 pci_set_drvdata(pci_dev, NULL); 6429 pci_set_drvdata(pci_dev, NULL);
6431 } 6430 }
6432 6431
@@ -6484,10 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6484 if (dev->base_addr) 6483 if (dev->base_addr)
6485 iounmap((void __iomem *)dev->base_addr); 6484 iounmap((void __iomem *)dev->base_addr);
6486 6485
6487 /* wiphy_unregister needs to be here, before free_ieee80211 */ 6486 /* wiphy_unregister needs to be here, before free_libipw */
6488 wiphy_unregister(priv->ieee->wdev.wiphy); 6487 wiphy_unregister(priv->ieee->wdev.wiphy);
6489 kfree(priv->ieee->bg_band.channels); 6488 kfree(priv->ieee->bg_band.channels);
6490 free_ieee80211(dev, 0); 6489 free_libipw(dev, 0);
6491 } 6490 }
6492 6491
6493 pci_release_regions(pci_dev); 6492 pci_release_regions(pci_dev);
@@ -6754,7 +6753,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6754 err = -EOPNOTSUPP; 6753 err = -EOPNOTSUPP;
6755 goto done; 6754 goto done;
6756 } else { /* Set the channel */ 6755 } else { /* Set the channel */
6757 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6756 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
6758 err = ipw2100_set_channel(priv, fwrq->m, 0); 6757 err = ipw2100_set_channel(priv, fwrq->m, 0);
6759 } 6758 }
6760 6759
@@ -6783,7 +6782,7 @@ static int ipw2100_wx_get_freq(struct net_device *dev,
6783 else 6782 else
6784 wrqu->freq.m = 0; 6783 wrqu->freq.m = 0;
6785 6784
6786 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 6785 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
6787 return 0; 6786 return 0;
6788 6787
6789} 6788}
@@ -6795,7 +6794,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
6795 struct ipw2100_priv *priv = libipw_priv(dev); 6794 struct ipw2100_priv *priv = libipw_priv(dev);
6796 int err = 0; 6795 int err = 0;
6797 6796
6798 IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode); 6797 IPW_DEBUG_WX("SET Mode -> %d\n", wrqu->mode);
6799 6798
6800 if (wrqu->mode == priv->ieee->iw_mode) 6799 if (wrqu->mode == priv->ieee->iw_mode)
6801 return 0; 6800 return 0;
@@ -7150,7 +7149,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7150 memset(priv->nick, 0, sizeof(priv->nick)); 7149 memset(priv->nick, 0, sizeof(priv->nick));
7151 memcpy(priv->nick, extra, wrqu->data.length); 7150 memcpy(priv->nick, extra, wrqu->data.length);
7152 7151
7153 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7152 IPW_DEBUG_WX("SET Nickname -> %s\n", priv->nick);
7154 7153
7155 return 0; 7154 return 0;
7156} 7155}
@@ -7169,7 +7168,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7169 memcpy(extra, priv->nick, wrqu->data.length); 7168 memcpy(extra, priv->nick, wrqu->data.length);
7170 wrqu->data.flags = 1; /* active */ 7169 wrqu->data.flags = 1; /* active */
7171 7170
7172 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7171 IPW_DEBUG_WX("GET Nickname -> %s\n", extra);
7173 7172
7174 return 0; 7173 return 0;
7175} 7174}
@@ -7208,7 +7207,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7208 7207
7209 err = ipw2100_set_tx_rates(priv, rate, 0); 7208 err = ipw2100_set_tx_rates(priv, rate, 0);
7210 7209
7211 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7210 IPW_DEBUG_WX("SET Rate -> %04X\n", rate);
7212 done: 7211 done:
7213 mutex_unlock(&priv->action_mutex); 7212 mutex_unlock(&priv->action_mutex);
7214 return err; 7213 return err;
@@ -7259,7 +7258,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7259 wrqu->bitrate.value = 0; 7258 wrqu->bitrate.value = 0;
7260 } 7259 }
7261 7260
7262 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7261 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
7263 7262
7264 done: 7263 done:
7265 mutex_unlock(&priv->action_mutex); 7264 mutex_unlock(&priv->action_mutex);
@@ -7295,7 +7294,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7295 7294
7296 err = ipw2100_set_rts_threshold(priv, value); 7295 err = ipw2100_set_rts_threshold(priv, value);
7297 7296
7298 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7297 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X\n", value);
7299 done: 7298 done:
7300 mutex_unlock(&priv->action_mutex); 7299 mutex_unlock(&priv->action_mutex);
7301 return err; 7300 return err;
@@ -7317,7 +7316,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7317 /* If RTS is set to the default value, then it is disabled */ 7316 /* If RTS is set to the default value, then it is disabled */
7318 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7317 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
7319 7318
7320 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value); 7319 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X\n", wrqu->rts.value);
7321 7320
7322 return 0; 7321 return 0;
7323} 7322}
@@ -7356,7 +7355,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7356 7355
7357 err = ipw2100_set_tx_power(priv, value); 7356 err = ipw2100_set_tx_power(priv, value);
7358 7357
7359 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7358 IPW_DEBUG_WX("SET TX Power -> %d\n", value);
7360 7359
7361 done: 7360 done:
7362 mutex_unlock(&priv->action_mutex); 7361 mutex_unlock(&priv->action_mutex);
@@ -7385,7 +7384,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7385 7384
7386 wrqu->txpower.flags = IW_TXPOW_DBM; 7385 wrqu->txpower.flags = IW_TXPOW_DBM;
7387 7386
7388 IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value); 7387 IPW_DEBUG_WX("GET TX Power -> %d\n", wrqu->txpower.value);
7389 7388
7390 return 0; 7389 return 0;
7391} 7390}
@@ -7415,7 +7414,7 @@ static int ipw2100_wx_set_frag(struct net_device *dev,
7415 priv->frag_threshold = priv->ieee->fts; 7414 priv->frag_threshold = priv->ieee->fts;
7416 } 7415 }
7417 7416
7418 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts); 7417 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", priv->ieee->fts);
7419 7418
7420 return 0; 7419 return 0;
7421} 7420}
@@ -7433,7 +7432,7 @@ static int ipw2100_wx_get_frag(struct net_device *dev,
7433 wrqu->frag.fixed = 0; /* no auto select */ 7432 wrqu->frag.fixed = 0; /* no auto select */
7434 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0; 7433 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
7435 7434
7436 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 7435 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
7437 7436
7438 return 0; 7437 return 0;
7439} 7438}
@@ -7459,14 +7458,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7459 7458
7460 if (wrqu->retry.flags & IW_RETRY_SHORT) { 7459 if (wrqu->retry.flags & IW_RETRY_SHORT) {
7461 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7460 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7462 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7461 IPW_DEBUG_WX("SET Short Retry Limit -> %d\n",
7463 wrqu->retry.value); 7462 wrqu->retry.value);
7464 goto done; 7463 goto done;
7465 } 7464 }
7466 7465
7467 if (wrqu->retry.flags & IW_RETRY_LONG) { 7466 if (wrqu->retry.flags & IW_RETRY_LONG) {
7468 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7467 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7469 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7468 IPW_DEBUG_WX("SET Long Retry Limit -> %d\n",
7470 wrqu->retry.value); 7469 wrqu->retry.value);
7471 goto done; 7470 goto done;
7472 } 7471 }
@@ -7475,7 +7474,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7475 if (!err) 7474 if (!err)
7476 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7475 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7477 7476
7478 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7477 IPW_DEBUG_WX("SET Both Retry Limits -> %d\n", wrqu->retry.value);
7479 7478
7480 done: 7479 done:
7481 mutex_unlock(&priv->action_mutex); 7480 mutex_unlock(&priv->action_mutex);
@@ -7509,7 +7508,7 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7509 wrqu->retry.value = priv->short_retry_limit; 7508 wrqu->retry.value = priv->short_retry_limit;
7510 } 7509 }
7511 7510
7512 IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value); 7511 IPW_DEBUG_WX("GET Retry -> %d\n", wrqu->retry.value);
7513 7512
7514 return 0; 7513 return 0;
7515} 7514}
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 8d72e3d19586..3aa3bb18f615 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -459,7 +459,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
459{ 459{
460 u32 word; 460 u32 word;
461 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK); 461 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
462 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 462 IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);
463 word = _ipw_read32(priv, IPW_INDIRECT_DATA); 463 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
464 return (word >> ((reg & 0x3) * 8)) & 0xff; 464 return (word >> ((reg & 0x3) * 8)) & 0xff;
465} 465}
@@ -473,7 +473,7 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
473 473
474 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg); 474 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
475 value = _ipw_read32(priv, IPW_INDIRECT_DATA); 475 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
476 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 476 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);
477 return value; 477 return value;
478} 478}
479 479
@@ -2349,16 +2349,25 @@ static void ipw_bg_adapter_restart(struct work_struct *work)
2349 mutex_unlock(&priv->mutex); 2349 mutex_unlock(&priv->mutex);
2350} 2350}
2351 2351
2352#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2352static void ipw_abort_scan(struct ipw_priv *priv);
2353
2354#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
2353 2355
2354static void ipw_scan_check(void *data) 2356static void ipw_scan_check(void *data)
2355{ 2357{
2356 struct ipw_priv *priv = data; 2358 struct ipw_priv *priv = data;
2357 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { 2359
2360 if (priv->status & STATUS_SCAN_ABORTING) {
2358 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2361 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
2359 "adapter after (%dms).\n", 2362 "adapter after (%dms).\n",
2360 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); 2363 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2361 queue_work(priv->workqueue, &priv->adapter_restart); 2364 queue_work(priv->workqueue, &priv->adapter_restart);
2365 } else if (priv->status & STATUS_SCANNING) {
2366 IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
2367 "after (%dms).\n",
2368 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2369 ipw_abort_scan(priv);
2370 queue_delayed_work(priv->workqueue, &priv->scan_check, HZ);
2362 } 2371 }
2363} 2372}
2364 2373
@@ -2598,8 +2607,6 @@ static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2598 2607
2599 /* the eeprom requires some time to complete the operation */ 2608 /* the eeprom requires some time to complete the operation */
2600 udelay(p->eeprom_delay); 2609 udelay(p->eeprom_delay);
2601
2602 return;
2603} 2610}
2604 2611
2605/* perform a chip select operation */ 2612/* perform a chip select operation */
@@ -2739,7 +2746,7 @@ static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2739static int ipw_fw_dma_enable(struct ipw_priv *priv) 2746static int ipw_fw_dma_enable(struct ipw_priv *priv)
2740{ /* start dma engine but no transfers yet */ 2747{ /* start dma engine but no transfers yet */
2741 2748
2742 IPW_DEBUG_FW(">> : \n"); 2749 IPW_DEBUG_FW(">> :\n");
2743 2750
2744 /* Start the dma */ 2751 /* Start the dma */
2745 ipw_fw_dma_reset_command_blocks(priv); 2752 ipw_fw_dma_reset_command_blocks(priv);
@@ -2747,7 +2754,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
2747 /* Write CB base address */ 2754 /* Write CB base address */
2748 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL); 2755 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
2749 2756
2750 IPW_DEBUG_FW("<< : \n"); 2757 IPW_DEBUG_FW("<< :\n");
2751 return 0; 2758 return 0;
2752} 2759}
2753 2760
@@ -2762,7 +2769,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
2762 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); 2769 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
2763 priv->sram_desc.last_cb_index = 0; 2770 priv->sram_desc.last_cb_index = 0;
2764 2771
2765 IPW_DEBUG_FW("<< \n"); 2772 IPW_DEBUG_FW("<<\n");
2766} 2773}
2767 2774
2768static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, 2775static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
@@ -2813,29 +2820,29 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2813 2820
2814 IPW_DEBUG_FW(">> :\n"); 2821 IPW_DEBUG_FW(">> :\n");
2815 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB); 2822 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
2816 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2823 IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);
2817 2824
2818 /* Read the DMA Controlor register */ 2825 /* Read the DMA Controlor register */
2819 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL); 2826 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
2820 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2827 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);
2821 2828
2822 /* Print the CB values */ 2829 /* Print the CB values */
2823 cb_fields_address = address; 2830 cb_fields_address = address;
2824 register_value = ipw_read_reg32(priv, cb_fields_address); 2831 register_value = ipw_read_reg32(priv, cb_fields_address);
2825 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value); 2832 IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);
2826 2833
2827 cb_fields_address += sizeof(u32); 2834 cb_fields_address += sizeof(u32);
2828 register_value = ipw_read_reg32(priv, cb_fields_address); 2835 register_value = ipw_read_reg32(priv, cb_fields_address);
2829 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value); 2836 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);
2830 2837
2831 cb_fields_address += sizeof(u32); 2838 cb_fields_address += sizeof(u32);
2832 register_value = ipw_read_reg32(priv, cb_fields_address); 2839 register_value = ipw_read_reg32(priv, cb_fields_address);
2833 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n", 2840 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",
2834 register_value); 2841 register_value);
2835 2842
2836 cb_fields_address += sizeof(u32); 2843 cb_fields_address += sizeof(u32);
2837 register_value = ipw_read_reg32(priv, cb_fields_address); 2844 register_value = ipw_read_reg32(priv, cb_fields_address);
2838 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value); 2845 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);
2839 2846
2840 IPW_DEBUG_FW(">> :\n"); 2847 IPW_DEBUG_FW(">> :\n");
2841} 2848}
@@ -2851,7 +2858,7 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2851 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) / 2858 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
2852 sizeof(struct command_block); 2859 sizeof(struct command_block);
2853 2860
2854 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2861 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",
2855 current_cb_index, current_cb_address); 2862 current_cb_index, current_cb_address);
2856 2863
2857 IPW_DEBUG_FW(">> :\n"); 2864 IPW_DEBUG_FW(">> :\n");
@@ -2910,7 +2917,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2910 int ret, i; 2917 int ret, i;
2911 u32 size; 2918 u32 size;
2912 2919
2913 IPW_DEBUG_FW(">> \n"); 2920 IPW_DEBUG_FW(">>\n");
2914 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n", 2921 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
2915 nr, dest_address, len); 2922 nr, dest_address, len);
2916 2923
@@ -2927,7 +2934,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2927 IPW_DEBUG_FW_INFO(": Added new cb\n"); 2934 IPW_DEBUG_FW_INFO(": Added new cb\n");
2928 } 2935 }
2929 2936
2930 IPW_DEBUG_FW("<< \n"); 2937 IPW_DEBUG_FW("<<\n");
2931 return 0; 2938 return 0;
2932} 2939}
2933 2940
@@ -2936,7 +2943,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
2936 u32 current_index = 0, previous_index; 2943 u32 current_index = 0, previous_index;
2937 u32 watchdog = 0; 2944 u32 watchdog = 0;
2938 2945
2939 IPW_DEBUG_FW(">> : \n"); 2946 IPW_DEBUG_FW(">> :\n");
2940 2947
2941 current_index = ipw_fw_dma_command_block_index(priv); 2948 current_index = ipw_fw_dma_command_block_index(priv);
2942 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n", 2949 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
@@ -2965,7 +2972,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
2965 ipw_set_bit(priv, IPW_RESET_REG, 2972 ipw_set_bit(priv, IPW_RESET_REG,
2966 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER); 2973 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
2967 2974
2968 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2975 IPW_DEBUG_FW("<< dmaWaitSync\n");
2969 return 0; 2976 return 0;
2970} 2977}
2971 2978
@@ -3026,7 +3033,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
3026{ 3033{
3027 int rc; 3034 int rc;
3028 3035
3029 IPW_DEBUG_TRACE(">> \n"); 3036 IPW_DEBUG_TRACE(">>\n");
3030 /* stop master. typical delay - 0 */ 3037 /* stop master. typical delay - 0 */
3031 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER); 3038 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
3032 3039
@@ -3045,7 +3052,7 @@ static int ipw_stop_master(struct ipw_priv *priv)
3045 3052
3046static void ipw_arc_release(struct ipw_priv *priv) 3053static void ipw_arc_release(struct ipw_priv *priv)
3047{ 3054{
3048 IPW_DEBUG_TRACE(">> \n"); 3055 IPW_DEBUG_TRACE(">>\n");
3049 mdelay(5); 3056 mdelay(5);
3050 3057
3051 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3058 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
@@ -3067,7 +3074,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3067 3074
3068 image = (__le16 *) data; 3075 image = (__le16 *) data;
3069 3076
3070 IPW_DEBUG_TRACE(">> \n"); 3077 IPW_DEBUG_TRACE(">>\n");
3071 3078
3072 rc = ipw_stop_master(priv); 3079 rc = ipw_stop_master(priv);
3073 3080
@@ -3181,7 +3188,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3181 void **virts; 3188 void **virts;
3182 dma_addr_t *phys; 3189 dma_addr_t *phys;
3183 3190
3184 IPW_DEBUG_TRACE("<< : \n"); 3191 IPW_DEBUG_TRACE("<< :\n");
3185 3192
3186 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, 3193 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
3187 GFP_KERNEL); 3194 GFP_KERNEL);
@@ -4482,7 +4489,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4482 case CMAS_ASSOCIATED:{ 4489 case CMAS_ASSOCIATED:{
4483 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4490 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4484 IPW_DL_ASSOC, 4491 IPW_DL_ASSOC,
4485 "associated: '%s' %pM \n", 4492 "associated: '%s' %pM\n",
4486 print_ssid(ssid, priv->essid, 4493 print_ssid(ssid, priv->essid,
4487 priv->essid_len), 4494 priv->essid_len),
4488 priv->bssid); 4495 priv->bssid);
@@ -4563,7 +4570,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4563 IPW_DL_ASSOC, 4570 IPW_DL_ASSOC,
4564 "deauthenticated: '%s' " 4571 "deauthenticated: '%s' "
4565 "%pM" 4572 "%pM"
4566 ": (0x%04X) - %s \n", 4573 ": (0x%04X) - %s\n",
4567 print_ssid(ssid, 4574 print_ssid(ssid,
4568 priv-> 4575 priv->
4569 essid, 4576 essid,
@@ -4614,7 +4621,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4614 4621
4615 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4622 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4616 IPW_DL_ASSOC, 4623 IPW_DL_ASSOC,
4617 "disassociated: '%s' %pM \n", 4624 "disassociated: '%s' %pM\n",
4618 print_ssid(ssid, priv->essid, 4625 print_ssid(ssid, priv->essid,
4619 priv->essid_len), 4626 priv->essid_len),
4620 priv->bssid); 4627 priv->bssid);
@@ -4652,7 +4659,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4652 switch (auth->state) { 4659 switch (auth->state) {
4653 case CMAS_AUTHENTICATED: 4660 case CMAS_AUTHENTICATED:
4654 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4661 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4655 "authenticated: '%s' %pM \n", 4662 "authenticated: '%s' %pM\n",
4656 print_ssid(ssid, priv->essid, 4663 print_ssid(ssid, priv->essid,
4657 priv->essid_len), 4664 priv->essid_len),
4658 priv->bssid); 4665 priv->bssid);
@@ -6925,7 +6932,7 @@ static u8 ipw_qos_current_mode(struct ipw_priv * priv)
6925 } else { 6932 } else {
6926 mode = priv->ieee->mode; 6933 mode = priv->ieee->mode;
6927 } 6934 }
6928 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode); 6935 IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);
6929 return mode; 6936 return mode;
6930} 6937}
6931 6938
@@ -6965,7 +6972,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6965 &def_parameters_OFDM, size); 6972 &def_parameters_OFDM, size);
6966 6973
6967 if ((network->qos_data.active == 1) && (active_network == 1)) { 6974 if ((network->qos_data.active == 1) && (active_network == 1)) {
6968 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n"); 6975 IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");
6969 schedule_work(&priv->qos_activate); 6976 schedule_work(&priv->qos_activate);
6970 } 6977 }
6971 6978
@@ -7542,7 +7549,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
7542 return err; 7549 return err;
7543 } 7550 }
7544 7551
7545 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM \n", 7552 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n",
7546 print_ssid(ssid, priv->essid, priv->essid_len), 7553 print_ssid(ssid, priv->essid, priv->essid_len),
7547 priv->bssid); 7554 priv->bssid);
7548 7555
@@ -8793,7 +8800,7 @@ static int ipw_wx_set_freq(struct net_device *dev,
8793 } 8800 }
8794 } 8801 }
8795 8802
8796 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8803 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
8797 mutex_lock(&priv->mutex); 8804 mutex_lock(&priv->mutex);
8798 ret = ipw_set_channel(priv, channel); 8805 ret = ipw_set_channel(priv, channel);
8799 mutex_unlock(&priv->mutex); 8806 mutex_unlock(&priv->mutex);
@@ -8835,7 +8842,7 @@ static int ipw_wx_get_freq(struct net_device *dev,
8835 wrqu->freq.m = 0; 8842 wrqu->freq.m = 0;
8836 8843
8837 mutex_unlock(&priv->mutex); 8844 mutex_unlock(&priv->mutex);
8838 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8845 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
8839 return 0; 8846 return 0;
8840} 8847}
8841 8848
@@ -9230,7 +9237,7 @@ static int ipw_wx_get_sens(struct net_device *dev,
9230 wrqu->sens.value = priv->roaming_threshold; 9237 wrqu->sens.value = priv->roaming_threshold;
9231 mutex_unlock(&priv->mutex); 9238 mutex_unlock(&priv->mutex);
9232 9239
9233 IPW_DEBUG_WX("GET roaming threshold -> %s %d \n", 9240 IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",
9234 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); 9241 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9235 9242
9236 return 0; 9243 return 0;
@@ -9358,7 +9365,7 @@ static int ipw_wx_get_rate(struct net_device *dev,
9358 wrqu->bitrate.value = priv->last_rate; 9365 wrqu->bitrate.value = priv->last_rate;
9359 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0; 9366 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
9360 mutex_unlock(&priv->mutex); 9367 mutex_unlock(&priv->mutex);
9361 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 9368 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
9362 return 0; 9369 return 0;
9363} 9370}
9364 9371
@@ -9381,7 +9388,7 @@ static int ipw_wx_set_rts(struct net_device *dev,
9381 9388
9382 ipw_send_rts_threshold(priv, priv->rts_threshold); 9389 ipw_send_rts_threshold(priv, priv->rts_threshold);
9383 mutex_unlock(&priv->mutex); 9390 mutex_unlock(&priv->mutex);
9384 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 9391 IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);
9385 return 0; 9392 return 0;
9386} 9393}
9387 9394
@@ -9395,7 +9402,7 @@ static int ipw_wx_get_rts(struct net_device *dev,
9395 wrqu->rts.fixed = 0; /* no auto select */ 9402 wrqu->rts.fixed = 0; /* no auto select */
9396 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 9403 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
9397 mutex_unlock(&priv->mutex); 9404 mutex_unlock(&priv->mutex);
9398 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 9405 IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);
9399 return 0; 9406 return 0;
9400} 9407}
9401 9408
@@ -9445,7 +9452,7 @@ static int ipw_wx_get_txpow(struct net_device *dev,
9445 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 9452 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
9446 mutex_unlock(&priv->mutex); 9453 mutex_unlock(&priv->mutex);
9447 9454
9448 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 9455 IPW_DEBUG_WX("GET TX Power -> %s %d\n",
9449 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); 9456 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9450 9457
9451 return 0; 9458 return 0;
@@ -9471,7 +9478,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
9471 9478
9472 ipw_send_frag_threshold(priv, wrqu->frag.value); 9479 ipw_send_frag_threshold(priv, wrqu->frag.value);
9473 mutex_unlock(&priv->mutex); 9480 mutex_unlock(&priv->mutex);
9474 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 9481 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);
9475 return 0; 9482 return 0;
9476} 9483}
9477 9484
@@ -9485,7 +9492,7 @@ static int ipw_wx_get_frag(struct net_device *dev,
9485 wrqu->frag.fixed = 0; /* no auto select */ 9492 wrqu->frag.fixed = 0; /* no auto select */
9486 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 9493 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
9487 mutex_unlock(&priv->mutex); 9494 mutex_unlock(&priv->mutex);
9488 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 9495 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
9489 9496
9490 return 0; 9497 return 0;
9491} 9498}
@@ -9549,7 +9556,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
9549 } 9556 }
9550 mutex_unlock(&priv->mutex); 9557 mutex_unlock(&priv->mutex);
9551 9558
9552 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value); 9559 IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);
9553 9560
9554 return 0; 9561 return 0;
9555} 9562}
@@ -9996,49 +10003,48 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9996} 10003}
9997 10004
9998/* Rebase the WE IOCTLs to zero for the handler array */ 10005/* Rebase the WE IOCTLs to zero for the handler array */
9999#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
10000static iw_handler ipw_wx_handlers[] = { 10006static iw_handler ipw_wx_handlers[] = {
10001 IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, 10007 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
10002 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 10008 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
10003 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 10009 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
10004 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 10010 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
10005 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 10011 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
10006 IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens, 10012 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
10007 IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens, 10013 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
10008 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 10014 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
10009 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 10015 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
10010 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 10016 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
10011 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 10017 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
10012 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 10018 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
10013 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 10019 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
10014 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 10020 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
10015 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 10021 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
10016 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 10022 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
10017 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 10023 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
10018 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 10024 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
10019 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 10025 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
10020 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 10026 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
10021 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 10027 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
10022 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 10028 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
10023 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 10029 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
10024 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 10030 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
10025 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 10031 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
10026 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 10032 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
10027 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 10033 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
10028 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 10034 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
10029 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 10035 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
10030 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 10036 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
10031 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy, 10037 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
10032 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, 10038 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
10033 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, 10039 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
10034 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, 10040 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
10035 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, 10041 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
10036 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, 10042 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
10037 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, 10043 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
10038 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth, 10044 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
10039 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, 10045 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
10040 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, 10046 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
10041 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, 10047 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
10042}; 10048};
10043 10049
10044enum { 10050enum {
@@ -11667,7 +11673,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11667 if (priv->prom_net_dev) 11673 if (priv->prom_net_dev)
11668 return -EPERM; 11674 return -EPERM;
11669 11675
11670 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); 11676 priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);
11671 if (priv->prom_net_dev == NULL) 11677 if (priv->prom_net_dev == NULL)
11672 return -ENOMEM; 11678 return -ENOMEM;
11673 11679
@@ -11686,7 +11692,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11686 11692
11687 rc = register_netdev(priv->prom_net_dev); 11693 rc = register_netdev(priv->prom_net_dev);
11688 if (rc) { 11694 if (rc) {
11689 free_ieee80211(priv->prom_net_dev, 1); 11695 free_libipw(priv->prom_net_dev, 1);
11690 priv->prom_net_dev = NULL; 11696 priv->prom_net_dev = NULL;
11691 return rc; 11697 return rc;
11692 } 11698 }
@@ -11700,7 +11706,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
11700 return; 11706 return;
11701 11707
11702 unregister_netdev(priv->prom_net_dev); 11708 unregister_netdev(priv->prom_net_dev);
11703 free_ieee80211(priv->prom_net_dev, 1); 11709 free_libipw(priv->prom_net_dev, 1);
11704 11710
11705 priv->prom_net_dev = NULL; 11711 priv->prom_net_dev = NULL;
11706} 11712}
@@ -11728,7 +11734,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11728 struct ipw_priv *priv; 11734 struct ipw_priv *priv;
11729 int i; 11735 int i;
11730 11736
11731 net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); 11737 net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);
11732 if (net_dev == NULL) { 11738 if (net_dev == NULL) {
11733 err = -ENOMEM; 11739 err = -ENOMEM;
11734 goto out; 11740 goto out;
@@ -11748,7 +11754,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11748 mutex_init(&priv->mutex); 11754 mutex_init(&priv->mutex);
11749 if (pci_enable_device(pdev)) { 11755 if (pci_enable_device(pdev)) {
11750 err = -ENODEV; 11756 err = -ENODEV;
11751 goto out_free_ieee80211; 11757 goto out_free_libipw;
11752 } 11758 }
11753 11759
11754 pci_set_master(pdev); 11760 pci_set_master(pdev);
@@ -11875,8 +11881,8 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11875 out_pci_disable_device: 11881 out_pci_disable_device:
11876 pci_disable_device(pdev); 11882 pci_disable_device(pdev);
11877 pci_set_drvdata(pdev, NULL); 11883 pci_set_drvdata(pdev, NULL);
11878 out_free_ieee80211: 11884 out_free_libipw:
11879 free_ieee80211(priv->net_dev, 0); 11885 free_libipw(priv->net_dev, 0);
11880 out: 11886 out:
11881 return err; 11887 return err;
11882} 11888}
@@ -11943,11 +11949,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
11943 pci_release_regions(pdev); 11949 pci_release_regions(pdev);
11944 pci_disable_device(pdev); 11950 pci_disable_device(pdev);
11945 pci_set_drvdata(pdev, NULL); 11951 pci_set_drvdata(pdev, NULL);
11946 /* wiphy_unregister needs to be here, before free_ieee80211 */ 11952 /* wiphy_unregister needs to be here, before free_libipw */
11947 wiphy_unregister(priv->ieee->wdev.wiphy); 11953 wiphy_unregister(priv->ieee->wdev.wiphy);
11948 kfree(priv->ieee->a_band.channels); 11954 kfree(priv->ieee->a_band.channels);
11949 kfree(priv->ieee->bg_band.channels); 11955 kfree(priv->ieee->bg_band.channels);
11950 free_ieee80211(priv->net_dev, 0); 11956 free_libipw(priv->net_dev, 0);
11951 free_firmware(); 11957 free_firmware();
11952} 11958}
11953 11959
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index a6d5e42647e4..284b0e4cb815 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -64,7 +64,7 @@
64extern u32 libipw_debug_level; 64extern u32 libipw_debug_level;
65#define LIBIPW_DEBUG(level, fmt, args...) \ 65#define LIBIPW_DEBUG(level, fmt, args...) \
66do { if (libipw_debug_level & (level)) \ 66do { if (libipw_debug_level & (level)) \
67 printk(KERN_DEBUG "ieee80211: %c %s " fmt, \ 67 printk(KERN_DEBUG "libipw: %c %s " fmt, \
68 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) 68 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
69static inline bool libipw_ratelimit_debug(u32 level) 69static inline bool libipw_ratelimit_debug(u32 level)
70{ 70{
@@ -116,8 +116,8 @@ static inline bool libipw_ratelimit_debug(u32 level)
116#define LIBIPW_DL_RX (1<<9) 116#define LIBIPW_DL_RX (1<<9)
117#define LIBIPW_DL_QOS (1<<31) 117#define LIBIPW_DL_QOS (1<<31)
118 118
119#define LIBIPW_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) 119#define LIBIPW_ERROR(f, a...) printk(KERN_ERR "libipw: " f, ## a)
120#define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) 120#define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "libipw: " f, ## a)
121#define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a) 121#define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a)
122 122
123#define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a) 123#define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a)
@@ -905,7 +905,7 @@ struct libipw_device {
905 struct libipw_reassoc_request * req); 905 struct libipw_reassoc_request * req);
906 906
907 /* This must be the last item so that it points to the data 907 /* This must be the last item so that it points to the data
908 * allocated beyond this structure by alloc_ieee80211 */ 908 * allocated beyond this structure by alloc_libipw */
909 u8 priv[0]; 909 u8 priv[0];
910}; 910};
911 911
@@ -1017,9 +1017,9 @@ static inline int libipw_is_cck_rate(u8 rate)
1017 return 0; 1017 return 0;
1018} 1018}
1019 1019
1020/* ieee80211.c */ 1020/* libipw.c */
1021extern void free_ieee80211(struct net_device *dev, int monitor); 1021extern void free_libipw(struct net_device *dev, int monitor);
1022extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); 1022extern struct net_device *alloc_libipw(int sizeof_priv, int monitor);
1023extern int libipw_change_mtu(struct net_device *dev, int new_mtu); 1023extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
1024 1024
1025extern void libipw_networks_age(struct libipw_device *ieee, 1025extern void libipw_networks_age(struct libipw_device *ieee,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 2fa55867bd8b..55965408ff3f 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -53,7 +53,7 @@
53#include "libipw.h" 53#include "libipw.h"
54 54
55#define DRV_DESCRIPTION "802.11 data/management/control stack" 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
56#define DRV_NAME "ieee80211" 56#define DRV_NAME "libipw"
57#define DRV_VERSION LIBIPW_VERSION 57#define DRV_VERSION LIBIPW_VERSION
58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" 58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
59 59
@@ -140,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
140} 140}
141EXPORT_SYMBOL(libipw_change_mtu); 141EXPORT_SYMBOL(libipw_change_mtu);
142 142
143struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) 143struct net_device *alloc_libipw(int sizeof_priv, int monitor)
144{ 144{
145 struct libipw_device *ieee; 145 struct libipw_device *ieee;
146 struct net_device *dev; 146 struct net_device *dev;
@@ -222,8 +222,9 @@ failed_free_netdev:
222failed: 222failed:
223 return NULL; 223 return NULL;
224} 224}
225EXPORT_SYMBOL(alloc_libipw);
225 226
226void free_ieee80211(struct net_device *dev, int monitor) 227void free_libipw(struct net_device *dev, int monitor)
227{ 228{
228 struct libipw_device *ieee = netdev_priv(dev); 229 struct libipw_device *ieee = netdev_priv(dev);
229 230
@@ -237,6 +238,7 @@ void free_ieee80211(struct net_device *dev, int monitor)
237 238
238 free_netdev(dev); 239 free_netdev(dev);
239} 240}
241EXPORT_SYMBOL(free_libipw);
240 242
241#ifdef CONFIG_LIBIPW_DEBUG 243#ifdef CONFIG_LIBIPW_DEBUG
242 244
@@ -291,7 +293,7 @@ static int __init libipw_init(void)
291 struct proc_dir_entry *e; 293 struct proc_dir_entry *e;
292 294
293 libipw_debug_level = debug; 295 libipw_debug_level = debug;
294 libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 296 libipw_proc = proc_mkdir("ieee80211", init_net.proc_net);
295 if (libipw_proc == NULL) { 297 if (libipw_proc == NULL) {
296 LIBIPW_ERROR("Unable to create " DRV_NAME 298 LIBIPW_ERROR("Unable to create " DRV_NAME
297 " proc directory\n"); 299 " proc directory\n");
@@ -331,6 +333,3 @@ MODULE_PARM_DESC(debug, "debug output mask");
331 333
332module_exit(libipw_exit); 334module_exit(libipw_exit);
333module_init(libipw_init); 335module_init(libipw_init);
334
335EXPORT_SYMBOL(alloc_ieee80211);
336EXPORT_SYMBOL(free_ieee80211);
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 39a34da52d52..0de1b1893220 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -918,7 +918,6 @@ void libipw_rx_any(struct libipw_device *ieee,
918drop_free: 918drop_free:
919 dev_kfree_skb_irq(skb); 919 dev_kfree_skb_irq(skb);
920 ieee->dev->stats.rx_dropped++; 920 ieee->dev->stats.rx_dropped++;
921 return;
922} 921}
923 922
924#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 923#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 4e378faee650..7c7235385513 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -9,7 +9,10 @@ CFLAGS_iwl-devtrace.o := -I$(src)
9 9
10# AGN 10# AGN
11obj-$(CONFIG_IWLAGN) += iwlagn.o 11obj-$(CONFIG_IWLAGN) += iwlagn.o
12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o 12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
14iwlagn-objs += iwl-agn-lib.o
15iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
13 16
14iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 17iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
15iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 18iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
@@ -19,5 +22,6 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
19# 3945 22# 3945
20obj-$(CONFIG_IWL3945) += iwl3945.o 23obj-$(CONFIG_IWL3945) += iwl3945.o
21iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o 24iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
25iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o
22 26
23ccflags-y += -D__CHECK_ENDIAN__ 27ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 3bf2e6e9b2d9..6be2992f8f21 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -42,9 +42,11 @@
42#include "iwl-core.h" 42#include "iwl-core.h"
43#include "iwl-io.h" 43#include "iwl-io.h"
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-agn.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 47#include "iwl-agn-hw.h"
47#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn-debugfs.h"
48 50
49/* Highest firmware API version supported */ 51/* Highest firmware API version supported */
50#define IWL1000_UCODE_API_MAX 3 52#define IWL1000_UCODE_API_MAX 3
@@ -117,7 +119,7 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
117static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) 119static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
118{ 120{
119 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 121 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
120 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 122 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
121 priv->cfg->num_of_queues = 123 priv->cfg->num_of_queues =
122 priv->cfg->mod_params->num_of_queues; 124 priv->cfg->mod_params->num_of_queues;
123 125
@@ -125,13 +127,13 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
125 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 127 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
126 priv->hw_params.scd_bc_tbls_size = 128 priv->hw_params.scd_bc_tbls_size =
127 priv->cfg->num_of_queues * 129 priv->cfg->num_of_queues *
128 sizeof(struct iwl5000_scd_bc_tbl); 130 sizeof(struct iwlagn_scd_bc_tbl);
129 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
130 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 132 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
131 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 133 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
132 134
133 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
134 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; 136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
135 137
136 priv->hw_params.max_bsm_size = 0; 138 priv->hw_params.max_bsm_size = 0;
137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 139 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
@@ -161,25 +163,25 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
161 163
162static struct iwl_lib_ops iwl1000_lib = { 164static struct iwl_lib_ops iwl1000_lib = {
163 .set_hw_params = iwl1000_hw_set_hw_params, 165 .set_hw_params = iwl1000_hw_set_hw_params,
164 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 166 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
165 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 167 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
166 .txq_set_sched = iwl5000_txq_set_sched, 168 .txq_set_sched = iwlagn_txq_set_sched,
167 .txq_agg_enable = iwl5000_txq_agg_enable, 169 .txq_agg_enable = iwlagn_txq_agg_enable,
168 .txq_agg_disable = iwl5000_txq_agg_disable, 170 .txq_agg_disable = iwlagn_txq_agg_disable,
169 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 171 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
170 .txq_free_tfd = iwl_hw_txq_free_tfd, 172 .txq_free_tfd = iwl_hw_txq_free_tfd,
171 .txq_init = iwl_hw_tx_queue_init, 173 .txq_init = iwl_hw_tx_queue_init,
172 .rx_handler_setup = iwl5000_rx_handler_setup, 174 .rx_handler_setup = iwlagn_rx_handler_setup,
173 .setup_deferred_work = iwl5000_setup_deferred_work, 175 .setup_deferred_work = iwlagn_setup_deferred_work,
174 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 176 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
175 .load_ucode = iwl5000_load_ucode, 177 .load_ucode = iwlagn_load_ucode,
176 .dump_nic_event_log = iwl_dump_nic_event_log, 178 .dump_nic_event_log = iwl_dump_nic_event_log,
177 .dump_nic_error_log = iwl_dump_nic_error_log, 179 .dump_nic_error_log = iwl_dump_nic_error_log,
178 .dump_csr = iwl_dump_csr, 180 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh, 181 .dump_fh = iwl_dump_fh,
180 .init_alive_start = iwl5000_init_alive_start, 182 .init_alive_start = iwlagn_init_alive_start,
181 .alive_notify = iwl5000_alive_notify, 183 .alive_notify = iwlagn_alive_notify,
182 .send_tx_power = iwl5000_send_tx_power, 184 .send_tx_power = iwlagn_send_tx_power,
183 .update_chain_flags = iwl_update_chain_flags, 185 .update_chain_flags = iwl_update_chain_flags,
184 .apm_ops = { 186 .apm_ops = {
185 .init = iwl_apm_init, 187 .init = iwl_apm_init,
@@ -189,40 +191,47 @@ static struct iwl_lib_ops iwl1000_lib = {
189 }, 191 },
190 .eeprom_ops = { 192 .eeprom_ops = {
191 .regulatory_bands = { 193 .regulatory_bands = {
192 EEPROM_5000_REG_BAND_1_CHANNELS, 194 EEPROM_REG_BAND_1_CHANNELS,
193 EEPROM_5000_REG_BAND_2_CHANNELS, 195 EEPROM_REG_BAND_2_CHANNELS,
194 EEPROM_5000_REG_BAND_3_CHANNELS, 196 EEPROM_REG_BAND_3_CHANNELS,
195 EEPROM_5000_REG_BAND_4_CHANNELS, 197 EEPROM_REG_BAND_4_CHANNELS,
196 EEPROM_5000_REG_BAND_5_CHANNELS, 198 EEPROM_REG_BAND_5_CHANNELS,
197 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 199 EEPROM_REG_BAND_24_HT40_CHANNELS,
198 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 200 EEPROM_REG_BAND_52_HT40_CHANNELS
199 }, 201 },
200 .verify_signature = iwlcore_eeprom_verify_signature, 202 .verify_signature = iwlcore_eeprom_verify_signature,
201 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 203 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
202 .release_semaphore = iwlcore_eeprom_release_semaphore, 204 .release_semaphore = iwlcore_eeprom_release_semaphore,
203 .calib_version = iwl5000_eeprom_calib_version, 205 .calib_version = iwlagn_eeprom_calib_version,
204 .query_addr = iwl5000_eeprom_query_addr, 206 .query_addr = iwlagn_eeprom_query_addr,
205 }, 207 },
206 .post_associate = iwl_post_associate, 208 .post_associate = iwl_post_associate,
207 .isr = iwl_isr_ict, 209 .isr = iwl_isr_ict,
208 .config_ap = iwl_config_ap, 210 .config_ap = iwl_config_ap,
209 .temp_ops = { 211 .temp_ops = {
210 .temperature = iwl5000_temperature, 212 .temperature = iwlagn_temperature,
211 .set_ct_kill = iwl1000_set_ct_threshold, 213 .set_ct_kill = iwl1000_set_ct_threshold,
212 }, 214 },
213 .add_bcast_station = iwl_add_bcast_station, 215 .manage_ibss_station = iwlagn_manage_ibss_station,
216 .debugfs_ops = {
217 .rx_stats_read = iwl_ucode_rx_stats_read,
218 .tx_stats_read = iwl_ucode_tx_stats_read,
219 .general_stats_read = iwl_ucode_general_stats_read,
220 },
221 .recover_from_tx_stall = iwl_bg_monitor_recover,
222 .check_plcp_health = iwl_good_plcp_health,
223 .check_ack_health = iwl_good_ack_health,
214}; 224};
215 225
216static const struct iwl_ops iwl1000_ops = { 226static const struct iwl_ops iwl1000_ops = {
217 .ucode = &iwl5000_ucode,
218 .lib = &iwl1000_lib, 227 .lib = &iwl1000_lib,
219 .hcmd = &iwl5000_hcmd, 228 .hcmd = &iwlagn_hcmd,
220 .utils = &iwl5000_hcmd_utils, 229 .utils = &iwlagn_hcmd_utils,
221 .led = &iwlagn_led_ops, 230 .led = &iwlagn_led_ops,
222}; 231};
223 232
224struct iwl_cfg iwl1000_bgn_cfg = { 233struct iwl_cfg iwl1000_bgn_cfg = {
225 .name = "1000 Series BGN", 234 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
226 .fw_name_pre = IWL1000_FW_PRE, 235 .fw_name_pre = IWL1000_FW_PRE,
227 .ucode_api_max = IWL1000_UCODE_API_MAX, 236 .ucode_api_max = IWL1000_UCODE_API_MAX,
228 .ucode_api_min = IWL1000_UCODE_API_MIN, 237 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -230,10 +239,10 @@ struct iwl_cfg iwl1000_bgn_cfg = {
230 .ops = &iwl1000_ops, 239 .ops = &iwl1000_ops,
231 .eeprom_size = OTP_LOW_IMAGE_SIZE, 240 .eeprom_size = OTP_LOW_IMAGE_SIZE,
232 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 241 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
233 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 242 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
234 .num_of_queues = IWL50_NUM_QUEUES, 243 .num_of_queues = IWLAGN_NUM_QUEUES,
235 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 244 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
236 .mod_params = &iwl50_mod_params, 245 .mod_params = &iwlagn_mod_params,
237 .valid_tx_ant = ANT_A, 246 .valid_tx_ant = ANT_A,
238 .valid_rx_ant = ANT_AB, 247 .valid_rx_ant = ANT_AB,
239 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 248 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -248,10 +257,15 @@ struct iwl_cfg iwl1000_bgn_cfg = {
248 .support_ct_kill_exit = true, 257 .support_ct_kill_exit = true,
249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 258 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
250 .chain_noise_scale = 1000, 259 .chain_noise_scale = 1000,
260 .monitor_recover_period = IWL_MONITORING_PERIOD,
261 .max_event_log_size = 128,
262 .ucode_tracing = true,
263 .sensitivity_calib_by_driver = true,
264 .chain_noise_calib_by_driver = true,
251}; 265};
252 266
253struct iwl_cfg iwl1000_bg_cfg = { 267struct iwl_cfg iwl1000_bg_cfg = {
254 .name = "1000 Series BG", 268 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
255 .fw_name_pre = IWL1000_FW_PRE, 269 .fw_name_pre = IWL1000_FW_PRE,
256 .ucode_api_max = IWL1000_UCODE_API_MAX, 270 .ucode_api_max = IWL1000_UCODE_API_MAX,
257 .ucode_api_min = IWL1000_UCODE_API_MIN, 271 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -259,10 +273,10 @@ struct iwl_cfg iwl1000_bg_cfg = {
259 .ops = &iwl1000_ops, 273 .ops = &iwl1000_ops,
260 .eeprom_size = OTP_LOW_IMAGE_SIZE, 274 .eeprom_size = OTP_LOW_IMAGE_SIZE,
261 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, 275 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
262 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 276 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
263 .num_of_queues = IWL50_NUM_QUEUES, 277 .num_of_queues = IWLAGN_NUM_QUEUES,
264 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 278 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
265 .mod_params = &iwl50_mod_params, 279 .mod_params = &iwlagn_mod_params,
266 .valid_tx_ant = ANT_A, 280 .valid_tx_ant = ANT_A,
267 .valid_rx_ant = ANT_AB, 281 .valid_rx_ant = ANT_AB,
268 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 282 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -270,12 +284,16 @@ struct iwl_cfg iwl1000_bg_cfg = {
270 .use_bsm = false, 284 .use_bsm = false,
271 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 285 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
272 .shadow_ram_support = false, 286 .shadow_ram_support = false,
273 .ht_greenfield_support = true,
274 .led_compensation = 51, 287 .led_compensation = 51,
275 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 288 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
276 .support_ct_kill_exit = true, 289 .support_ct_kill_exit = true,
277 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 290 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
278 .chain_noise_scale = 1000, 291 .chain_noise_scale = 1000,
292 .monitor_recover_period = IWL_MONITORING_PERIOD,
293 .max_event_log_size = 128,
294 .ucode_tracing = true,
295 .sensitivity_calib_by_driver = true,
296 .chain_noise_calib_by_driver = true,
279}; 297};
280 298
281MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 299MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
new file mode 100644
index 000000000000..6a9c64a50e36
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
@@ -0,0 +1,500 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include "iwl-3945-debugfs.h"
30
31ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
32 char __user *user_buf,
33 size_t count, loff_t *ppos)
34{
35 struct iwl_priv *priv = file->private_data;
36 int pos = 0;
37 char *buf;
38 int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 +
39 sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400;
40 ssize_t ret;
41 struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
42 struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
43 struct iwl39_statistics_rx_non_phy *general, *accum_general;
44 struct iwl39_statistics_rx_non_phy *delta_general, *max_general;
45
46 if (!iwl_is_alive(priv))
47 return -EAGAIN;
48
49 buf = kzalloc(bufsz, GFP_KERNEL);
50 if (!buf) {
51 IWL_ERR(priv, "Can not allocate Buffer\n");
52 return -ENOMEM;
53 }
54
55 /*
56 * The statistic information display here is based on
57 * the last statistics notification from uCode
58 * might not reflect the current uCode activity
59 */
60 ofdm = &priv->_3945.statistics.rx.ofdm;
61 cck = &priv->_3945.statistics.rx.cck;
62 general = &priv->_3945.statistics.rx.general;
63 accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm;
64 accum_cck = &priv->_3945.accum_statistics.rx.cck;
65 accum_general = &priv->_3945.accum_statistics.rx.general;
66 delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm;
67 delta_cck = &priv->_3945.delta_statistics.rx.cck;
68 delta_general = &priv->_3945.delta_statistics.rx.general;
69 max_ofdm = &priv->_3945.max_delta.rx.ofdm;
70 max_cck = &priv->_3945.max_delta.rx.cck;
71 max_general = &priv->_3945.max_delta.rx.general;
72
73 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
74 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
75 "acumulative delta max\n",
76 "Statistics_Rx - OFDM:");
77 pos += scnprintf(buf + pos, bufsz - pos,
78 " %-30s %10u %10u %10u %10u\n",
79 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
80 accum_ofdm->ina_cnt,
81 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
82 pos += scnprintf(buf + pos, bufsz - pos,
83 " %-30s %10u %10u %10u %10u\n",
84 "fina_cnt:",
85 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
86 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
87 pos += scnprintf(buf + pos, bufsz - pos,
88 " %-30s %10u %10u %10u %10u\n", "plcp_err:",
89 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
90 delta_ofdm->plcp_err, max_ofdm->plcp_err);
91 pos += scnprintf(buf + pos, bufsz - pos,
92 " %-30s %10u %10u %10u %10u\n", "crc32_err:",
93 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
94 delta_ofdm->crc32_err, max_ofdm->crc32_err);
95 pos += scnprintf(buf + pos, bufsz - pos,
96 " %-30s %10u %10u %10u %10u\n", "overrun_err:",
97 le32_to_cpu(ofdm->overrun_err),
98 accum_ofdm->overrun_err, delta_ofdm->overrun_err,
99 max_ofdm->overrun_err);
100 pos += scnprintf(buf + pos, bufsz - pos,
101 " %-30s %10u %10u %10u %10u\n",
102 "early_overrun_err:",
103 le32_to_cpu(ofdm->early_overrun_err),
104 accum_ofdm->early_overrun_err,
105 delta_ofdm->early_overrun_err,
106 max_ofdm->early_overrun_err);
107 pos += scnprintf(buf + pos, bufsz - pos,
108 " %-30s %10u %10u %10u %10u\n",
109 "crc32_good:", le32_to_cpu(ofdm->crc32_good),
110 accum_ofdm->crc32_good, delta_ofdm->crc32_good,
111 max_ofdm->crc32_good);
112 pos += scnprintf(buf + pos, bufsz - pos,
113 " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:",
114 le32_to_cpu(ofdm->false_alarm_cnt),
115 accum_ofdm->false_alarm_cnt,
116 delta_ofdm->false_alarm_cnt,
117 max_ofdm->false_alarm_cnt);
118 pos += scnprintf(buf + pos, bufsz - pos,
119 " %-30s %10u %10u %10u %10u\n",
120 "fina_sync_err_cnt:",
121 le32_to_cpu(ofdm->fina_sync_err_cnt),
122 accum_ofdm->fina_sync_err_cnt,
123 delta_ofdm->fina_sync_err_cnt,
124 max_ofdm->fina_sync_err_cnt);
125 pos += scnprintf(buf + pos, bufsz - pos,
126 " %-30s %10u %10u %10u %10u\n",
127 "sfd_timeout:",
128 le32_to_cpu(ofdm->sfd_timeout),
129 accum_ofdm->sfd_timeout,
130 delta_ofdm->sfd_timeout,
131 max_ofdm->sfd_timeout);
132 pos += scnprintf(buf + pos, bufsz - pos,
133 " %-30s %10u %10u %10u %10u\n",
134 "fina_timeout:",
135 le32_to_cpu(ofdm->fina_timeout),
136 accum_ofdm->fina_timeout,
137 delta_ofdm->fina_timeout,
138 max_ofdm->fina_timeout);
139 pos += scnprintf(buf + pos, bufsz - pos,
140 " %-30s %10u %10u %10u %10u\n",
141 "unresponded_rts:",
142 le32_to_cpu(ofdm->unresponded_rts),
143 accum_ofdm->unresponded_rts,
144 delta_ofdm->unresponded_rts,
145 max_ofdm->unresponded_rts);
146 pos += scnprintf(buf + pos, bufsz - pos,
147 " %-30s %10u %10u %10u %10u\n",
148 "rxe_frame_lmt_ovrun:",
149 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
150 accum_ofdm->rxe_frame_limit_overrun,
151 delta_ofdm->rxe_frame_limit_overrun,
152 max_ofdm->rxe_frame_limit_overrun);
153 pos += scnprintf(buf + pos, bufsz - pos,
154 " %-30s %10u %10u %10u %10u\n",
155 "sent_ack_cnt:",
156 le32_to_cpu(ofdm->sent_ack_cnt),
157 accum_ofdm->sent_ack_cnt,
158 delta_ofdm->sent_ack_cnt,
159 max_ofdm->sent_ack_cnt);
160 pos += scnprintf(buf + pos, bufsz - pos,
161 " %-30s %10u %10u %10u %10u\n",
162 "sent_cts_cnt:",
163 le32_to_cpu(ofdm->sent_cts_cnt),
164 accum_ofdm->sent_cts_cnt,
165 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
166
167 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
168 "acumulative delta max\n",
169 "Statistics_Rx - CCK:");
170 pos += scnprintf(buf + pos, bufsz - pos,
171 " %-30s %10u %10u %10u %10u\n",
172 "ina_cnt:",
173 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
174 delta_cck->ina_cnt, max_cck->ina_cnt);
175 pos += scnprintf(buf + pos, bufsz - pos,
176 " %-30s %10u %10u %10u %10u\n",
177 "fina_cnt:",
178 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
179 delta_cck->fina_cnt, max_cck->fina_cnt);
180 pos += scnprintf(buf + pos, bufsz - pos,
181 " %-30s %10u %10u %10u %10u\n",
182 "plcp_err:",
183 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
184 delta_cck->plcp_err, max_cck->plcp_err);
185 pos += scnprintf(buf + pos, bufsz - pos,
186 " %-30s %10u %10u %10u %10u\n",
187 "crc32_err:",
188 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
189 delta_cck->crc32_err, max_cck->crc32_err);
190 pos += scnprintf(buf + pos, bufsz - pos,
191 " %-30s %10u %10u %10u %10u\n",
192 "overrun_err:",
193 le32_to_cpu(cck->overrun_err),
194 accum_cck->overrun_err,
195 delta_cck->overrun_err, max_cck->overrun_err);
196 pos += scnprintf(buf + pos, bufsz - pos,
197 " %-30s %10u %10u %10u %10u\n",
198 "early_overrun_err:",
199 le32_to_cpu(cck->early_overrun_err),
200 accum_cck->early_overrun_err,
201 delta_cck->early_overrun_err,
202 max_cck->early_overrun_err);
203 pos += scnprintf(buf + pos, bufsz - pos,
204 " %-30s %10u %10u %10u %10u\n",
205 "crc32_good:",
206 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
207 delta_cck->crc32_good,
208 max_cck->crc32_good);
209 pos += scnprintf(buf + pos, bufsz - pos,
210 " %-30s %10u %10u %10u %10u\n",
211 "false_alarm_cnt:",
212 le32_to_cpu(cck->false_alarm_cnt),
213 accum_cck->false_alarm_cnt,
214 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
215 pos += scnprintf(buf + pos, bufsz - pos,
216 " %-30s %10u %10u %10u %10u\n",
217 "fina_sync_err_cnt:",
218 le32_to_cpu(cck->fina_sync_err_cnt),
219 accum_cck->fina_sync_err_cnt,
220 delta_cck->fina_sync_err_cnt,
221 max_cck->fina_sync_err_cnt);
222 pos += scnprintf(buf + pos, bufsz - pos,
223 " %-30s %10u %10u %10u %10u\n",
224 "sfd_timeout:",
225 le32_to_cpu(cck->sfd_timeout),
226 accum_cck->sfd_timeout,
227 delta_cck->sfd_timeout, max_cck->sfd_timeout);
228 pos += scnprintf(buf + pos, bufsz - pos,
229 " %-30s %10u %10u %10u %10u\n",
230 "fina_timeout:",
231 le32_to_cpu(cck->fina_timeout),
232 accum_cck->fina_timeout,
233 delta_cck->fina_timeout, max_cck->fina_timeout);
234 pos += scnprintf(buf + pos, bufsz - pos,
235 " %-30s %10u %10u %10u %10u\n",
236 "unresponded_rts:",
237 le32_to_cpu(cck->unresponded_rts),
238 accum_cck->unresponded_rts,
239 delta_cck->unresponded_rts,
240 max_cck->unresponded_rts);
241 pos += scnprintf(buf + pos, bufsz - pos,
242 " %-30s %10u %10u %10u %10u\n",
243 "rxe_frame_lmt_ovrun:",
244 le32_to_cpu(cck->rxe_frame_limit_overrun),
245 accum_cck->rxe_frame_limit_overrun,
246 delta_cck->rxe_frame_limit_overrun,
247 max_cck->rxe_frame_limit_overrun);
248 pos += scnprintf(buf + pos, bufsz - pos,
249 " %-30s %10u %10u %10u %10u\n",
250 "sent_ack_cnt:",
251 le32_to_cpu(cck->sent_ack_cnt),
252 accum_cck->sent_ack_cnt,
253 delta_cck->sent_ack_cnt,
254 max_cck->sent_ack_cnt);
255 pos += scnprintf(buf + pos, bufsz - pos,
256 " %-30s %10u %10u %10u %10u\n",
257 "sent_cts_cnt:",
258 le32_to_cpu(cck->sent_cts_cnt),
259 accum_cck->sent_cts_cnt,
260 delta_cck->sent_cts_cnt,
261 max_cck->sent_cts_cnt);
262
263 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
264 "acumulative delta max\n",
265 "Statistics_Rx - GENERAL:");
266 pos += scnprintf(buf + pos, bufsz - pos,
267 " %-30s %10u %10u %10u %10u\n",
268 "bogus_cts:",
269 le32_to_cpu(general->bogus_cts),
270 accum_general->bogus_cts,
271 delta_general->bogus_cts, max_general->bogus_cts);
272 pos += scnprintf(buf + pos, bufsz - pos,
273 " %-30s %10u %10u %10u %10u\n",
274 "bogus_ack:",
275 le32_to_cpu(general->bogus_ack),
276 accum_general->bogus_ack,
277 delta_general->bogus_ack, max_general->bogus_ack);
278 pos += scnprintf(buf + pos, bufsz - pos,
279 " %-30s %10u %10u %10u %10u\n",
280 "non_bssid_frames:",
281 le32_to_cpu(general->non_bssid_frames),
282 accum_general->non_bssid_frames,
283 delta_general->non_bssid_frames,
284 max_general->non_bssid_frames);
285 pos += scnprintf(buf + pos, bufsz - pos,
286 " %-30s %10u %10u %10u %10u\n",
287 "filtered_frames:",
288 le32_to_cpu(general->filtered_frames),
289 accum_general->filtered_frames,
290 delta_general->filtered_frames,
291 max_general->filtered_frames);
292 pos += scnprintf(buf + pos, bufsz - pos,
293 " %-30s %10u %10u %10u %10u\n",
294 "non_channel_beacons:",
295 le32_to_cpu(general->non_channel_beacons),
296 accum_general->non_channel_beacons,
297 delta_general->non_channel_beacons,
298 max_general->non_channel_beacons);
299
300 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
301 kfree(buf);
302 return ret;
303}
304
305ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
306 char __user *user_buf,
307 size_t count, loff_t *ppos)
308{
309 struct iwl_priv *priv = file->private_data;
310 int pos = 0;
311 char *buf;
312 int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250;
313 ssize_t ret;
314 struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
315
316 if (!iwl_is_alive(priv))
317 return -EAGAIN;
318
319 buf = kzalloc(bufsz, GFP_KERNEL);
320 if (!buf) {
321 IWL_ERR(priv, "Can not allocate Buffer\n");
322 return -ENOMEM;
323 }
324
325 /*
326 * The statistic information display here is based on
327 * the last statistics notification from uCode
328 * might not reflect the current uCode activity
329 */
330 tx = &priv->_3945.statistics.tx;
331 accum_tx = &priv->_3945.accum_statistics.tx;
332 delta_tx = &priv->_3945.delta_statistics.tx;
333 max_tx = &priv->_3945.max_delta.tx;
334 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
335 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
336 "acumulative delta max\n",
337 "Statistics_Tx:");
338 pos += scnprintf(buf + pos, bufsz - pos,
339 " %-30s %10u %10u %10u %10u\n",
340 "preamble:",
341 le32_to_cpu(tx->preamble_cnt),
342 accum_tx->preamble_cnt,
343 delta_tx->preamble_cnt, max_tx->preamble_cnt);
344 pos += scnprintf(buf + pos, bufsz - pos,
345 " %-30s %10u %10u %10u %10u\n",
346 "rx_detected_cnt:",
347 le32_to_cpu(tx->rx_detected_cnt),
348 accum_tx->rx_detected_cnt,
349 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
350 pos += scnprintf(buf + pos, bufsz - pos,
351 " %-30s %10u %10u %10u %10u\n",
352 "bt_prio_defer_cnt:",
353 le32_to_cpu(tx->bt_prio_defer_cnt),
354 accum_tx->bt_prio_defer_cnt,
355 delta_tx->bt_prio_defer_cnt,
356 max_tx->bt_prio_defer_cnt);
357 pos += scnprintf(buf + pos, bufsz - pos,
358 " %-30s %10u %10u %10u %10u\n",
359 "bt_prio_kill_cnt:",
360 le32_to_cpu(tx->bt_prio_kill_cnt),
361 accum_tx->bt_prio_kill_cnt,
362 delta_tx->bt_prio_kill_cnt,
363 max_tx->bt_prio_kill_cnt);
364 pos += scnprintf(buf + pos, bufsz - pos,
365 " %-30s %10u %10u %10u %10u\n",
366 "few_bytes_cnt:",
367 le32_to_cpu(tx->few_bytes_cnt),
368 accum_tx->few_bytes_cnt,
369 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
370 pos += scnprintf(buf + pos, bufsz - pos,
371 " %-30s %10u %10u %10u %10u\n",
372 "cts_timeout:",
373 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
374 delta_tx->cts_timeout, max_tx->cts_timeout);
375 pos += scnprintf(buf + pos, bufsz - pos,
376 " %-30s %10u %10u %10u %10u\n",
377 "ack_timeout:",
378 le32_to_cpu(tx->ack_timeout),
379 accum_tx->ack_timeout,
380 delta_tx->ack_timeout, max_tx->ack_timeout);
381 pos += scnprintf(buf + pos, bufsz - pos,
382 " %-30s %10u %10u %10u %10u\n",
383 "expected_ack_cnt:",
384 le32_to_cpu(tx->expected_ack_cnt),
385 accum_tx->expected_ack_cnt,
386 delta_tx->expected_ack_cnt,
387 max_tx->expected_ack_cnt);
388 pos += scnprintf(buf + pos, bufsz - pos,
389 " %-30s %10u %10u %10u %10u\n",
390 "actual_ack_cnt:",
391 le32_to_cpu(tx->actual_ack_cnt),
392 accum_tx->actual_ack_cnt,
393 delta_tx->actual_ack_cnt,
394 max_tx->actual_ack_cnt);
395
396 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
397 kfree(buf);
398 return ret;
399}
400
401ssize_t iwl3945_ucode_general_stats_read(struct file *file,
402 char __user *user_buf,
403 size_t count, loff_t *ppos)
404{
405 struct iwl_priv *priv = file->private_data;
406 int pos = 0;
407 char *buf;
408 int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300;
409 ssize_t ret;
410 struct iwl39_statistics_general *general, *accum_general;
411 struct iwl39_statistics_general *delta_general, *max_general;
412 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
413 struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div;
414
415 if (!iwl_is_alive(priv))
416 return -EAGAIN;
417
418 buf = kzalloc(bufsz, GFP_KERNEL);
419 if (!buf) {
420 IWL_ERR(priv, "Can not allocate Buffer\n");
421 return -ENOMEM;
422 }
423
424 /*
425 * The statistic information display here is based on
426 * the last statistics notification from uCode
427 * might not reflect the current uCode activity
428 */
429 general = &priv->_3945.statistics.general;
430 dbg = &priv->_3945.statistics.general.dbg;
431 div = &priv->_3945.statistics.general.div;
432 accum_general = &priv->_3945.accum_statistics.general;
433 delta_general = &priv->_3945.delta_statistics.general;
434 max_general = &priv->_3945.max_delta.general;
435 accum_dbg = &priv->_3945.accum_statistics.general.dbg;
436 delta_dbg = &priv->_3945.delta_statistics.general.dbg;
437 max_dbg = &priv->_3945.max_delta.general.dbg;
438 accum_div = &priv->_3945.accum_statistics.general.div;
439 delta_div = &priv->_3945.delta_statistics.general.div;
440 max_div = &priv->_3945.max_delta.general.div;
441 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
442 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
443 "acumulative delta max\n",
444 "Statistics_General:");
445 pos += scnprintf(buf + pos, bufsz - pos,
446 " %-30s %10u %10u %10u %10u\n",
447 "burst_check:",
448 le32_to_cpu(dbg->burst_check),
449 accum_dbg->burst_check,
450 delta_dbg->burst_check, max_dbg->burst_check);
451 pos += scnprintf(buf + pos, bufsz - pos,
452 " %-30s %10u %10u %10u %10u\n",
453 "burst_count:",
454 le32_to_cpu(dbg->burst_count),
455 accum_dbg->burst_count,
456 delta_dbg->burst_count, max_dbg->burst_count);
457 pos += scnprintf(buf + pos, bufsz - pos,
458 " %-30s %10u %10u %10u %10u\n",
459 "sleep_time:",
460 le32_to_cpu(general->sleep_time),
461 accum_general->sleep_time,
462 delta_general->sleep_time, max_general->sleep_time);
463 pos += scnprintf(buf + pos, bufsz - pos,
464 " %-30s %10u %10u %10u %10u\n",
465 "slots_out:",
466 le32_to_cpu(general->slots_out),
467 accum_general->slots_out,
468 delta_general->slots_out, max_general->slots_out);
469 pos += scnprintf(buf + pos, bufsz - pos,
470 " %-30s %10u %10u %10u %10u\n",
471 "slots_idle:",
472 le32_to_cpu(general->slots_idle),
473 accum_general->slots_idle,
474 delta_general->slots_idle, max_general->slots_idle);
475 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
476 le32_to_cpu(general->ttl_timestamp));
477 pos += scnprintf(buf + pos, bufsz - pos,
478 " %-30s %10u %10u %10u %10u\n",
479 "tx_on_a:",
480 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
481 delta_div->tx_on_a, max_div->tx_on_a);
482 pos += scnprintf(buf + pos, bufsz - pos,
483 " %-30s %10u %10u %10u %10u\n",
484 "tx_on_b:",
485 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
486 delta_div->tx_on_b, max_div->tx_on_b);
487 pos += scnprintf(buf + pos, bufsz - pos,
488 " %-30s %10u %10u %10u %10u\n",
489 "exec_time:",
490 le32_to_cpu(div->exec_time), accum_div->exec_time,
491 delta_div->exec_time, max_div->exec_time);
492 pos += scnprintf(buf + pos, bufsz - pos,
493 " %-30s %10u %10u %10u %10u\n",
494 "probe_time:",
495 le32_to_cpu(div->probe_time), accum_div->probe_time,
496 delta_div->probe_time, max_div->probe_time);
497 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
498 kfree(buf);
499 return ret;
500}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h
new file mode 100644
index 000000000000..70809c53c215
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h
@@ -0,0 +1,60 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include "iwl-dev.h"
30#include "iwl-core.h"
31#include "iwl-debug.h"
32
33#ifdef CONFIG_IWLWIFI_DEBUGFS
34ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
35 size_t count, loff_t *ppos);
36ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
37 size_t count, loff_t *ppos);
38ssize_t iwl3945_ucode_general_stats_read(struct file *file,
39 char __user *user_buf, size_t count,
40 loff_t *ppos);
41#else
42static ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
43 char __user *user_buf, size_t count,
44 loff_t *ppos)
45{
46 return 0;
47}
48static ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
49 char __user *user_buf, size_t count,
50 loff_t *ppos)
51{
52 return 0;
53}
54static ssize_t iwl3945_ucode_general_stats_read(struct file *file,
55 char __user *user_buf,
56 size_t count, loff_t *ppos)
57{
58 return 0;
59}
60#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 3a876a8ece38..91bcb4e3cdfb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -71,13 +71,11 @@
71 71
72#include "iwl-eeprom.h" 72#include "iwl-eeprom.h"
73 73
74/* Time constants */
75#define SHORT_SLOT_TIME 9
76#define LONG_SLOT_TIME 20
77
78/* RSSI to dBm */ 74/* RSSI to dBm */
79#define IWL39_RSSI_OFFSET 95 75#define IWL39_RSSI_OFFSET 95
80 76
77#define IWL_DEFAULT_TX_POWER 0x0F
78
81/* 79/*
82 * EEPROM related constants, enums, and structures. 80 * EEPROM related constants, enums, and structures.
83 */ 81 */
@@ -228,7 +226,6 @@ struct iwl3945_eeprom {
228 226
229/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ 227/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
230#define IWL39_NUM_QUEUES 5 228#define IWL39_NUM_QUEUES 5
231#define IWL_NUM_SCAN_RATES (2)
232 229
233#define IWL_DEFAULT_TX_RETRY 15 230#define IWL_DEFAULT_TX_RETRY 15
234 231
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 902c4d4293e9..8e84a08ff951 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -330,16 +330,25 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
330 330
331} 331}
332 332
333static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 333/*
334 struct ieee80211_sta *sta, void *priv_sta) 334 * Called after adding a new station to initialize rate scaling
335 */
336void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
335{ 337{
336 struct iwl3945_rs_sta *rs_sta = priv_sta; 338 struct ieee80211_hw *hw = priv->hw;
337 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 339 struct ieee80211_conf *conf = &priv->hw->conf;
340 struct iwl3945_sta_priv *psta;
341 struct iwl3945_rs_sta *rs_sta;
342 struct ieee80211_supported_band *sband;
338 int i; 343 int i;
339 344
340 IWL_DEBUG_RATE(priv, "enter\n"); 345 IWL_DEBUG_INFO(priv, "enter\n");
346 if (sta_id == priv->hw_params.bcast_sta_id)
347 goto out;
341 348
342 spin_lock_init(&rs_sta->lock); 349 psta = (struct iwl3945_sta_priv *) sta->drv_priv;
350 rs_sta = &psta->rs_sta;
351 sband = hw->wiphy->bands[conf->channel->band];
343 352
344 rs_sta->priv = priv; 353 rs_sta->priv = priv;
345 354
@@ -352,9 +361,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
352 rs_sta->last_flush = jiffies; 361 rs_sta->last_flush = jiffies;
353 rs_sta->flush_time = IWL_RATE_FLUSH; 362 rs_sta->flush_time = IWL_RATE_FLUSH;
354 rs_sta->last_tx_packets = 0; 363 rs_sta->last_tx_packets = 0;
355 rs_sta->ibss_sta_added = 0;
356 364
357 init_timer(&rs_sta->rate_scale_flush);
358 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; 365 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
359 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; 366 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush;
360 367
@@ -373,16 +380,18 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
373 } 380 }
374 } 381 }
375 382
376 priv->sta_supp_rates = sta->supp_rates[sband->band]; 383 priv->_3945.sta_supp_rates = sta->supp_rates[sband->band];
377 /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ 384 /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
378 if (sband->band == IEEE80211_BAND_5GHZ) { 385 if (sband->band == IEEE80211_BAND_5GHZ) {
379 rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 386 rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
380 priv->sta_supp_rates = priv->sta_supp_rates << 387 priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates <<
381 IWL_FIRST_OFDM_RATE; 388 IWL_FIRST_OFDM_RATE;
382 } 389 }
383 390
391out:
392 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
384 393
385 IWL_DEBUG_RATE(priv, "leave\n"); 394 IWL_DEBUG_INFO(priv, "leave\n");
386} 395}
387 396
388static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 397static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -406,6 +415,9 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
406 415
407 rs_sta = &psta->rs_sta; 416 rs_sta = &psta->rs_sta;
408 417
418 spin_lock_init(&rs_sta->lock);
419 init_timer(&rs_sta->rate_scale_flush);
420
409 IWL_DEBUG_RATE(priv, "leave\n"); 421 IWL_DEBUG_RATE(priv, "leave\n");
410 422
411 return rs_sta; 423 return rs_sta;
@@ -414,13 +426,14 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
414static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, 426static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
415 void *priv_sta) 427 void *priv_sta)
416{ 428{
417 struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; 429 struct iwl3945_rs_sta *rs_sta = priv_sta;
418 struct iwl3945_rs_sta *rs_sta = &psta->rs_sta;
419 struct iwl_priv *priv __maybe_unused = rs_sta->priv;
420 430
421 IWL_DEBUG_RATE(priv, "enter\n"); 431 /*
432 * Be careful not to use any members of iwl3945_rs_sta (like trying
433 * to use iwl_priv to print out debugging) since it may not be fully
434 * initialized at this point.
435 */
422 del_timer_sync(&rs_sta->rate_scale_flush); 436 del_timer_sync(&rs_sta->rate_scale_flush);
423 IWL_DEBUG_RATE(priv, "leave\n");
424} 437}
425 438
426 439
@@ -459,6 +472,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
459 return; 472 return;
460 } 473 }
461 474
475 /* Treat uninitialized rate scaling data same as non-existing. */
476 if (!rs_sta->priv) {
477 IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n");
478 return;
479 }
480
481
462 rs_sta->tx_packets++; 482 rs_sta->tx_packets++;
463 483
464 scale_rate_index = first_index; 484 scale_rate_index = first_index;
@@ -525,8 +545,6 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
525 spin_unlock_irqrestore(&rs_sta->lock, flags); 545 spin_unlock_irqrestore(&rs_sta->lock, flags);
526 546
527 IWL_DEBUG_RATE(priv, "leave\n"); 547 IWL_DEBUG_RATE(priv, "leave\n");
528
529 return;
530} 548}
531 549
532static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, 550static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
@@ -626,14 +644,19 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
626 u32 fail_count; 644 u32 fail_count;
627 s8 scale_action = 0; 645 s8 scale_action = 0;
628 unsigned long flags; 646 unsigned long flags;
629 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
630 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; 647 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
631 s8 max_rate_idx = -1; 648 s8 max_rate_idx = -1;
632 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 649 struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r;
633 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 650 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
634 651
635 IWL_DEBUG_RATE(priv, "enter\n"); 652 IWL_DEBUG_RATE(priv, "enter\n");
636 653
654 /* Treat uninitialized rate scaling data same as non-existing. */
655 if (rs_sta && !rs_sta->priv) {
656 IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n");
657 priv_sta = NULL;
658 }
659
637 if (rate_control_send_low(sta, priv_sta, txrc)) 660 if (rate_control_send_low(sta, priv_sta, txrc))
638 return; 661 return;
639 662
@@ -651,20 +674,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
651 if (sband->band == IEEE80211_BAND_5GHZ) 674 if (sband->band == IEEE80211_BAND_5GHZ)
652 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; 675 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
653 676
654 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
655 !rs_sta->ibss_sta_added) {
656 u8 sta_id = iwl_find_station(priv, hdr->addr1);
657
658 if (sta_id == IWL_INVALID_STATION) {
659 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
660 hdr->addr1);
661 sta_id = iwl_add_station(priv, hdr->addr1, false,
662 CMD_ASYNC, NULL);
663 }
664 if (sta_id != IWL_INVALID_STATION)
665 rs_sta->ibss_sta_added = 1;
666 }
667
668 spin_lock_irqsave(&rs_sta->lock, flags); 677 spin_lock_irqsave(&rs_sta->lock, flags);
669 678
670 /* for recent assoc, choose best rate regarding 679 /* for recent assoc, choose best rate regarding
@@ -884,12 +893,22 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
884} 893}
885#endif 894#endif
886 895
896/*
897 * Initialization of rate scaling information is done by driver after
898 * the station is added. Since mac80211 calls this function before a
899 * station is added we ignore it.
900 */
901static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
902 struct ieee80211_sta *sta, void *priv_sta)
903{
904}
905
887static struct rate_control_ops rs_ops = { 906static struct rate_control_ops rs_ops = {
888 .module = NULL, 907 .module = NULL,
889 .name = RS_NAME, 908 .name = RS_NAME,
890 .tx_status = rs_tx_status, 909 .tx_status = rs_tx_status,
891 .get_rate = rs_get_rate, 910 .get_rate = rs_get_rate,
892 .rate_init = rs_rate_init, 911 .rate_init = rs_rate_init_stub,
893 .alloc = rs_alloc, 912 .alloc = rs_alloc,
894 .free = rs_free, 913 .free = rs_free,
895 .alloc_sta = rs_alloc_sta, 914 .alloc_sta = rs_alloc_sta,
@@ -900,7 +919,6 @@ static struct rate_control_ops rs_ops = {
900#endif 919#endif
901 920
902}; 921};
903
904void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) 922void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
905{ 923{
906 struct iwl_priv *priv = hw->priv; 924 struct iwl_priv *priv = hw->priv;
@@ -917,6 +935,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
917 sta = ieee80211_find_sta(priv->vif, 935 sta = ieee80211_find_sta(priv->vif,
918 priv->stations[sta_id].sta.sta.addr); 936 priv->stations[sta_id].sta.sta.addr);
919 if (!sta) { 937 if (!sta) {
938 IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
920 rcu_read_unlock(); 939 rcu_read_unlock();
921 return; 940 return;
922 } 941 }
@@ -947,7 +966,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
947 966
948 spin_unlock_irqrestore(&rs_sta->lock, flags); 967 spin_unlock_irqrestore(&rs_sta->lock, flags);
949 968
950 rssi = priv->last_rx_rssi; 969 rssi = priv->_3945.last_rx_rssi;
951 if (rssi == 0) 970 if (rssi == 0)
952 rssi = IWL_MIN_RSSI_VAL; 971 rssi = IWL_MIN_RSSI_VAL;
953 972
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 0728054a22d4..068f7f8435c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -50,6 +50,7 @@
50#include "iwl-helpers.h" 50#include "iwl-helpers.h"
51#include "iwl-led.h" 51#include "iwl-led.h"
52#include "iwl-3945-led.h" 52#include "iwl-3945-led.h"
53#include "iwl-3945-debugfs.h"
53 54
54#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ 55#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
55 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 56 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -192,12 +193,12 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
192} 193}
193 194
194#ifdef CONFIG_IWLWIFI_DEBUG 195#ifdef CONFIG_IWLWIFI_DEBUG
195#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x 196#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x
196 197
197static const char *iwl3945_get_tx_fail_reason(u32 status) 198static const char *iwl3945_get_tx_fail_reason(u32 status)
198{ 199{
199 switch (status & TX_STATUS_MSK) { 200 switch (status & TX_STATUS_MSK) {
200 case TX_STATUS_SUCCESS: 201 case TX_3945_STATUS_SUCCESS:
201 return "SUCCESS"; 202 return "SUCCESS";
202 TX_STATUS_ENTRY(SHORT_LIMIT); 203 TX_STATUS_ENTRY(SHORT_LIMIT);
203 TX_STATUS_ENTRY(LONG_LIMIT); 204 TX_STATUS_ENTRY(LONG_LIMIT);
@@ -243,7 +244,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
243 next_rate = IWL_RATE_6M_INDEX; 244 next_rate = IWL_RATE_6M_INDEX;
244 break; 245 break;
245 case IEEE80211_BAND_2GHZ: 246 case IEEE80211_BAND_2GHZ:
246 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && 247 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
247 iwl_is_associated(priv)) { 248 iwl_is_associated(priv)) {
248 if (rate == IWL_RATE_11M_INDEX) 249 if (rate == IWL_RATE_11M_INDEX)
249 next_rate = IWL_RATE_5M_INDEX; 250 next_rate = IWL_RATE_5M_INDEX;
@@ -293,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
293 * iwl3945_rx_reply_tx - Handle Tx response 294 * iwl3945_rx_reply_tx - Handle Tx response
294 */ 295 */
295static void iwl3945_rx_reply_tx(struct iwl_priv *priv, 296static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
296 struct iwl_rx_mem_buffer *rxb) 297 struct iwl_rx_mem_buffer *rxb)
297{ 298{
298 struct iwl_rx_packet *pkt = rxb_addr(rxb); 299 struct iwl_rx_packet *pkt = rxb_addr(rxb);
299 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 300 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -351,18 +352,143 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
351 * RX handler implementations 352 * RX handler implementations
352 * 353 *
353 *****************************************************************************/ 354 *****************************************************************************/
355#ifdef CONFIG_IWLWIFI_DEBUG
356/*
357 * based on the assumption of all statistics counter are in DWORD
358 * FIXME: This function is for debugging, do not deal with
359 * the case of counters roll-over.
360 */
361static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
362 __le32 *stats)
363{
364 int i;
365 __le32 *prev_stats;
366 u32 *accum_stats;
367 u32 *delta, *max_delta;
368
369 prev_stats = (__le32 *)&priv->_3945.statistics;
370 accum_stats = (u32 *)&priv->_3945.accum_statistics;
371 delta = (u32 *)&priv->_3945.delta_statistics;
372 max_delta = (u32 *)&priv->_3945.max_delta;
373
374 for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics);
375 i += sizeof(__le32), stats++, prev_stats++, delta++,
376 max_delta++, accum_stats++) {
377 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
378 *delta = (le32_to_cpu(*stats) -
379 le32_to_cpu(*prev_stats));
380 *accum_stats += *delta;
381 if (*delta > *max_delta)
382 *max_delta = *delta;
383 }
384 }
385
386 /* reset accumulative statistics for "no-counter" type statistics */
387 priv->_3945.accum_statistics.general.temperature =
388 priv->_3945.statistics.general.temperature;
389 priv->_3945.accum_statistics.general.ttl_timestamp =
390 priv->_3945.statistics.general.ttl_timestamp;
391}
392#endif
393
394/**
395 * iwl3945_good_plcp_health - checks for plcp error.
396 *
397 * When the plcp error is exceeding the thresholds, reset the radio
398 * to improve the throughput.
399 */
400static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
401 struct iwl_rx_packet *pkt)
402{
403 bool rc = true;
404 struct iwl3945_notif_statistics current_stat;
405 int combined_plcp_delta;
406 unsigned int plcp_msec;
407 unsigned long plcp_received_jiffies;
408
409 memcpy(&current_stat, pkt->u.raw, sizeof(struct
410 iwl3945_notif_statistics));
411 /*
412 * check for plcp_err and trigger radio reset if it exceeds
413 * the plcp error threshold plcp_delta.
414 */
415 plcp_received_jiffies = jiffies;
416 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
417 (long) priv->plcp_jiffies);
418 priv->plcp_jiffies = plcp_received_jiffies;
419 /*
420 * check to make sure plcp_msec is not 0 to prevent division
421 * by zero.
422 */
423 if (plcp_msec) {
424 combined_plcp_delta =
425 (le32_to_cpu(current_stat.rx.ofdm.plcp_err) -
426 le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err));
427
428 if ((combined_plcp_delta > 0) &&
429 ((combined_plcp_delta * 100) / plcp_msec) >
430 priv->cfg->plcp_delta_threshold) {
431 /*
432 * if plcp_err exceed the threshold, the following
433 * data is printed in csv format:
434 * Text: plcp_err exceeded %d,
435 * Received ofdm.plcp_err,
436 * Current ofdm.plcp_err,
437 * combined_plcp_delta,
438 * plcp_msec
439 */
440 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
441 "%u, %d, %u mSecs\n",
442 priv->cfg->plcp_delta_threshold,
443 le32_to_cpu(current_stat.rx.ofdm.plcp_err),
444 combined_plcp_delta, plcp_msec);
445 /*
446 * Reset the RF radio due to the high plcp
447 * error rate
448 */
449 rc = false;
450 }
451 }
452 return rc;
453}
354 454
355void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 455void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
356 struct iwl_rx_mem_buffer *rxb) 456 struct iwl_rx_mem_buffer *rxb)
357{ 457{
358 struct iwl_rx_packet *pkt = rxb_addr(rxb); 458 struct iwl_rx_packet *pkt = rxb_addr(rxb);
459
359 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 460 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
360 (int)sizeof(struct iwl3945_notif_statistics), 461 (int)sizeof(struct iwl3945_notif_statistics),
361 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 462 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
463#ifdef CONFIG_IWLWIFI_DEBUG
464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
465#endif
466 iwl_recover_from_statistics(priv, pkt);
467
468 memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
469}
470
471void iwl3945_reply_statistics(struct iwl_priv *priv,
472 struct iwl_rx_mem_buffer *rxb)
473{
474 struct iwl_rx_packet *pkt = rxb_addr(rxb);
475 __le32 *flag = (__le32 *)&pkt->u.raw;
362 476
363 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); 477 if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
478#ifdef CONFIG_IWLWIFI_DEBUG
479 memset(&priv->_3945.accum_statistics, 0,
480 sizeof(struct iwl3945_notif_statistics));
481 memset(&priv->_3945.delta_statistics, 0,
482 sizeof(struct iwl3945_notif_statistics));
483 memset(&priv->_3945.max_delta, 0,
484 sizeof(struct iwl3945_notif_statistics));
485#endif
486 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
487 }
488 iwl3945_hw_rx_statistics(priv, rxb);
364} 489}
365 490
491
366/****************************************************************************** 492/******************************************************************************
367 * 493 *
368 * Misc. internal state and helper functions 494 * Misc. internal state and helper functions
@@ -487,7 +613,7 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
487 * but you can hack it to show more, if you'd like to. */ 613 * but you can hack it to show more, if you'd like to. */
488 if (dataframe) 614 if (dataframe)
489 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " 615 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
490 "len=%u, rssi=%d, chnl=%d, rate=%d, \n", 616 "len=%u, rssi=%d, chnl=%d, rate=%d,\n",
491 title, le16_to_cpu(fc), header->addr1[5], 617 title, le16_to_cpu(fc), header->addr1[5],
492 length, rssi, channel, rate); 618 length, rssi, channel, rate);
493 else { 619 else {
@@ -549,7 +675,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
549 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 675 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
550 u16 len = le16_to_cpu(rx_hdr->len); 676 u16 len = le16_to_cpu(rx_hdr->len);
551 struct sk_buff *skb; 677 struct sk_buff *skb;
552 int ret;
553 __le16 fc = hdr->frame_control; 678 __le16 fc = hdr->frame_control;
554 679
555 /* We received data from the HW, so stop the watchdog */ 680 /* We received data from the HW, so stop the watchdog */
@@ -566,9 +691,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
566 return; 691 return;
567 } 692 }
568 693
569 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); 694 skb = dev_alloc_skb(128);
570 if (!skb) { 695 if (!skb) {
571 IWL_ERR(priv, "alloc_skb failed\n"); 696 IWL_ERR(priv, "dev_alloc_skb failed\n");
572 return; 697 return;
573 } 698 }
574 699
@@ -577,37 +702,13 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
577 (struct ieee80211_hdr *)rxb_addr(rxb), 702 (struct ieee80211_hdr *)rxb_addr(rxb),
578 le32_to_cpu(rx_end->status), stats); 703 le32_to_cpu(rx_end->status), stats);
579 704
580 skb_reserve(skb, IWL_LINK_HDR_MAX);
581 skb_add_rx_frag(skb, 0, rxb->page, 705 skb_add_rx_frag(skb, 0, rxb->page,
582 (void *)rx_hdr->payload - (void *)pkt, len); 706 (void *)rx_hdr->payload - (void *)pkt, len);
583 707
584 /* mac80211 currently doesn't support paged SKB. Convert it to
585 * linear SKB for management frame and data frame requires
586 * software decryption or software defragementation. */
587 if (ieee80211_is_mgmt(fc) ||
588 ieee80211_has_protected(fc) ||
589 ieee80211_has_morefrags(fc) ||
590 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
591 ret = skb_linearize(skb);
592 else
593 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
594 0 : -ENOMEM;
595
596 if (ret) {
597 kfree_skb(skb);
598 goto out;
599 }
600
601 /*
602 * XXX: We cannot touch the page and its virtual memory (pkt) after
603 * here. It might have already been freed by the above skb change.
604 */
605
606 iwl_update_stats(priv, false, fc, len); 708 iwl_update_stats(priv, false, fc, len);
607 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); 709 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
608 710
609 ieee80211_rx(priv->hw, skb); 711 ieee80211_rx(priv->hw, skb);
610 out:
611 priv->alloc_rxb_page--; 712 priv->alloc_rxb_page--;
612 rxb->page = NULL; 713 rxb->page = NULL;
613} 714}
@@ -623,9 +724,8 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
623 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); 724 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
624 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); 725 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
625 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 726 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
626 int snr; 727 u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg);
627 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); 728 u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff);
628 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
629 u8 network_packet; 729 u8 network_packet;
630 730
631 rx_status.flag = 0; 731 rx_status.flag = 0;
@@ -663,53 +763,29 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
663 /* Convert 3945's rssi indicator to dBm */ 763 /* Convert 3945's rssi indicator to dBm */
664 rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; 764 rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
665 765
666 /* Set default noise value to -127 */ 766 IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n",
667 if (priv->last_rx_noise == 0) 767 rx_status.signal, rx_stats_sig_avg,
668 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 768 rx_stats_noise_diff);
669
670 /* 3945 provides noise info for OFDM frames only.
671 * sig_avg and noise_diff are measured by the 3945's digital signal
672 * processor (DSP), and indicate linear levels of signal level and
673 * distortion/noise within the packet preamble after
674 * automatic gain control (AGC). sig_avg should stay fairly
675 * constant if the radio's AGC is working well.
676 * Since these values are linear (not dB or dBm), linear
677 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff).
678 * Convert linear SNR to dB SNR, then subtract that from rssi dBm
679 * to obtain noise level in dBm.
680 * Calculate rx_status.signal (quality indicator in %) based on SNR. */
681 if (rx_stats_noise_diff) {
682 snr = rx_stats_sig_avg / rx_stats_noise_diff;
683 rx_status.noise = rx_status.signal -
684 iwl3945_calc_db_from_ratio(snr);
685 } else {
686 rx_status.noise = priv->last_rx_noise;
687 }
688
689
690 IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n",
691 rx_status.signal, rx_status.noise,
692 rx_stats_sig_avg, rx_stats_noise_diff);
693 769
694 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 770 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
695 771
696 network_packet = iwl3945_is_network_packet(priv, header); 772 network_packet = iwl3945_is_network_packet(priv, header);
697 773
698 IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", 774 IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n",
699 network_packet ? '*' : ' ', 775 network_packet ? '*' : ' ',
700 le16_to_cpu(rx_hdr->channel), 776 le16_to_cpu(rx_hdr->channel),
701 rx_status.signal, rx_status.signal, 777 rx_status.signal, rx_status.signal,
702 rx_status.noise, rx_status.rate_idx); 778 rx_status.rate_idx);
703 779
704 /* Set "1" to report good data frames in groups of 100 */ 780 /* Set "1" to report good data frames in groups of 100 */
705 iwl3945_dbg_report_frame(priv, pkt, header, 1); 781 iwl3945_dbg_report_frame(priv, pkt, header, 1);
706 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); 782 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
707 783
708 if (network_packet) { 784 if (network_packet) {
709 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); 785 priv->_3945.last_beacon_time =
710 priv->last_tsf = le64_to_cpu(rx_end->timestamp); 786 le32_to_cpu(rx_end->beacon_timestamp);
711 priv->last_rx_rssi = rx_status.signal; 787 priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp);
712 priv->last_rx_noise = rx_status.noise; 788 priv->_3945.last_rx_rssi = rx_status.signal;
713 } 789 }
714 790
715 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); 791 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
@@ -871,7 +947,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
871 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); 947 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
872} 948}
873 949
874u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) 950static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
951 u16 tx_rate, u8 flags)
875{ 952{
876 unsigned long flags_spin; 953 unsigned long flags_spin;
877 struct iwl_station_entry *station; 954 struct iwl_station_entry *station;
@@ -957,7 +1034,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
957 iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); 1034 iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
958 1035
959 iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, 1036 iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
960 priv->shared_phys); 1037 priv->_3945.shared_phys);
961 1038
962 iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, 1039 iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
963 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | 1040 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
@@ -1049,7 +1126,7 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1049 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); 1126 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1050 1127
1051 if (rev_id & PCI_CFG_REV_ID_BIT_RTP) 1128 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
1052 IWL_DEBUG_INFO(priv, "RTP type \n"); 1129 IWL_DEBUG_INFO(priv, "RTP type\n");
1053 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { 1130 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
1054 IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); 1131 IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
1055 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1132 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
@@ -1607,7 +1684,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
1607 int power; 1684 int power;
1608 1685
1609 /* Get this chnlgrp's rate-to-max/clip-powers table */ 1686 /* Get this chnlgrp's rate-to-max/clip-powers table */
1610 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 1687 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
1611 1688
1612 /* Get this channel's rate-to-current-power settings table */ 1689 /* Get this channel's rate-to-current-power settings table */
1613 power_info = ch_info->power_info; 1690 power_info = ch_info->power_info;
@@ -1701,6 +1778,11 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1701 int ref_temp; 1778 int ref_temp;
1702 int temperature = priv->temperature; 1779 int temperature = priv->temperature;
1703 1780
1781 if (priv->disable_tx_power_cal ||
1782 test_bit(STATUS_SCANNING, &priv->status)) {
1783 /* do not perform tx power calibration */
1784 return 0;
1785 }
1704 /* set up new Tx power info for each and every channel, 2.4 and 5.x */ 1786 /* set up new Tx power info for each and every channel, 2.4 and 5.x */
1705 for (i = 0; i < priv->channel_count; i++) { 1787 for (i = 0; i < priv->channel_count; i++) {
1706 ch_info = &priv->channel_info[i]; 1788 ch_info = &priv->channel_info[i];
@@ -1733,7 +1815,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1733 } 1815 }
1734 1816
1735 /* Get this chnlgrp's rate-to-max/clip-powers table */ 1817 /* Get this chnlgrp's rate-to-max/clip-powers table */
1736 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 1818 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
1737 1819
1738 /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ 1820 /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
1739 for (scan_tbl_index = 0; 1821 for (scan_tbl_index = 0;
@@ -1911,6 +1993,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1911 "configuration (%d).\n", rc); 1993 "configuration (%d).\n", rc);
1912 return rc; 1994 return rc;
1913 } 1995 }
1996 iwl_clear_ucode_stations(priv);
1997 iwl_restore_stations(priv);
1914 } 1998 }
1915 1999
1916 IWL_DEBUG_INFO(priv, "Sending RXON\n" 2000 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1941,7 +2025,10 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1941 2025
1942 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 2026 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1943 2027
1944 iwl_clear_stations_table(priv); 2028 if (!new_assoc) {
2029 iwl_clear_ucode_stations(priv);
2030 iwl_restore_stations(priv);
2031 }
1945 2032
1946 /* If we issue a new RXON command which required a tune then we must 2033 /* If we issue a new RXON command which required a tune then we must
1947 * send a new TXPOWER command or we won't be able to Tx any frames */ 2034 * send a new TXPOWER command or we won't be able to Tx any frames */
@@ -1951,19 +2038,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1951 return rc; 2038 return rc;
1952 } 2039 }
1953 2040
1954 /* Add the broadcast address so we can send broadcast frames */
1955 priv->cfg->ops->lib->add_bcast_station(priv);
1956
1957 /* If we have set the ASSOC_MSK and we are in BSS mode then
1958 * add the IWL_AP_ID to the station rate table */
1959 if (iwl_is_associated(priv) &&
1960 (priv->iw_mode == NL80211_IFTYPE_STATION))
1961 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
1962 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
1963 IWL_ERR(priv, "Error adding AP address for transmit\n");
1964 return -EIO;
1965 }
1966
1967 /* Init the hardware's rate fallback order based on the band */ 2041 /* Init the hardware's rate fallback order based on the band */
1968 rc = iwl3945_init_hw_rate_table(priv); 2042 rc = iwl3945_init_hw_rate_table(priv);
1969 if (rc) { 2043 if (rc) {
@@ -1998,13 +2072,13 @@ void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
1998 2072
1999 reschedule: 2073 reschedule:
2000 queue_delayed_work(priv->workqueue, 2074 queue_delayed_work(priv->workqueue,
2001 &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ); 2075 &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ);
2002} 2076}
2003 2077
2004static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) 2078static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
2005{ 2079{
2006 struct iwl_priv *priv = container_of(work, struct iwl_priv, 2080 struct iwl_priv *priv = container_of(work, struct iwl_priv,
2007 thermal_periodic.work); 2081 _3945.thermal_periodic.work);
2008 2082
2009 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2083 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2010 return; 2084 return;
@@ -2140,7 +2214,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
2140 * power peaks, without too much distortion (clipping). 2214 * power peaks, without too much distortion (clipping).
2141 */ 2215 */
2142 /* we'll fill in this array with h/w max power levels */ 2216 /* we'll fill in this array with h/w max power levels */
2143 clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers; 2217 clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers;
2144 2218
2145 /* divide factory saturation power by 2 to find -3dB level */ 2219 /* divide factory saturation power by 2 to find -3dB level */
2146 satur_pwr = (s8) (group->saturation_power >> 1); 2220 satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2224,7 +2298,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2224 iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); 2298 iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
2225 2299
2226 /* Get this chnlgrp's rate->max/clip-powers table */ 2300 /* Get this chnlgrp's rate->max/clip-powers table */
2227 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; 2301 clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers;
2228 2302
2229 /* calculate power index *adjustment* value according to 2303 /* calculate power index *adjustment* value according to
2230 * diff between current temperature and factory temperature */ 2304 * diff between current temperature and factory temperature */
@@ -2332,7 +2406,7 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2332{ 2406{
2333 int txq_id = txq->q.id; 2407 int txq_id = txq->q.id;
2334 2408
2335 struct iwl3945_shared *shared_data = priv->shared_virt; 2409 struct iwl3945_shared *shared_data = priv->_3945.shared_virt;
2336 2410
2337 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); 2411 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
2338 2412
@@ -2385,6 +2459,30 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2385 return (u16)sizeof(struct iwl3945_addsta_cmd); 2459 return (u16)sizeof(struct iwl3945_addsta_cmd);
2386} 2460}
2387 2461
2462static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2463 struct ieee80211_vif *vif, bool add)
2464{
2465 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
2466 int ret;
2467
2468 if (add) {
2469 ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
2470 &vif_priv->ibss_bssid_sta_id);
2471 if (ret)
2472 return ret;
2473
2474 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
2475 (priv->band == IEEE80211_BAND_5GHZ) ?
2476 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
2477 CMD_ASYNC);
2478 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
2479
2480 return 0;
2481 }
2482
2483 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
2484 vif->bss_conf.bssid);
2485}
2388 2486
2389/** 2487/**
2390 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table 2488 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
@@ -2432,7 +2530,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2432 /* If an OFDM rate is used, have it fall back to the 2530 /* If an OFDM rate is used, have it fall back to the
2433 * 1M CCK rates */ 2531 * 1M CCK rates */
2434 2532
2435 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && 2533 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
2436 iwl_is_associated(priv)) { 2534 iwl_is_associated(priv)) {
2437 2535
2438 index = IWL_FIRST_CCK_RATE; 2536 index = IWL_FIRST_CCK_RATE;
@@ -2471,12 +2569,12 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2471 memset((void *)&priv->hw_params, 0, 2569 memset((void *)&priv->hw_params, 0,
2472 sizeof(struct iwl_hw_params)); 2570 sizeof(struct iwl_hw_params));
2473 2571
2474 priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, 2572 priv->_3945.shared_virt =
2475 sizeof(struct iwl3945_shared), 2573 dma_alloc_coherent(&priv->pci_dev->dev,
2476 &priv->shared_phys, GFP_KERNEL); 2574 sizeof(struct iwl3945_shared),
2477 if (!priv->shared_virt) { 2575 &priv->_3945.shared_phys, GFP_KERNEL);
2576 if (!priv->_3945.shared_virt) {
2478 IWL_ERR(priv, "failed to allocate pci memory\n"); 2577 IWL_ERR(priv, "failed to allocate pci memory\n");
2479 mutex_unlock(&priv->mutex);
2480 return -ENOMEM; 2578 return -ENOMEM;
2481 } 2579 }
2482 2580
@@ -2537,13 +2635,13 @@ void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
2537 2635
2538void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) 2636void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
2539{ 2637{
2540 INIT_DELAYED_WORK(&priv->thermal_periodic, 2638 INIT_DELAYED_WORK(&priv->_3945.thermal_periodic,
2541 iwl3945_bg_reg_txpower_periodic); 2639 iwl3945_bg_reg_txpower_periodic);
2542} 2640}
2543 2641
2544void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) 2642void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
2545{ 2643{
2546 cancel_delayed_work(&priv->thermal_periodic); 2644 cancel_delayed_work(&priv->_3945.thermal_periodic);
2547} 2645}
2548 2646
2549/* check contents of special bootstrap uCode SRAM */ 2647/* check contents of special bootstrap uCode SRAM */
@@ -2714,48 +2812,10 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2714 return 0; 2812 return 0;
2715} 2813}
2716 2814
2717#define IWL3945_UCODE_GET(item) \
2718static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2719 u32 api_ver) \
2720{ \
2721 return le32_to_cpu(ucode->u.v1.item); \
2722}
2723
2724static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2725{
2726 return UCODE_HEADER_SIZE(1);
2727}
2728static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
2729 u32 api_ver)
2730{
2731 return 0;
2732}
2733static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
2734 u32 api_ver)
2735{
2736 return (u8 *) ucode->u.v1.data;
2737}
2738
2739IWL3945_UCODE_GET(inst_size);
2740IWL3945_UCODE_GET(data_size);
2741IWL3945_UCODE_GET(init_size);
2742IWL3945_UCODE_GET(init_data_size);
2743IWL3945_UCODE_GET(boot_size);
2744
2745static struct iwl_hcmd_ops iwl3945_hcmd = { 2815static struct iwl_hcmd_ops iwl3945_hcmd = {
2746 .rxon_assoc = iwl3945_send_rxon_assoc, 2816 .rxon_assoc = iwl3945_send_rxon_assoc,
2747 .commit_rxon = iwl3945_commit_rxon, 2817 .commit_rxon = iwl3945_commit_rxon,
2748}; 2818 .send_bt_config = iwl_send_bt_config,
2749
2750static struct iwl_ucode_ops iwl3945_ucode = {
2751 .get_header_size = iwl3945_ucode_get_header_size,
2752 .get_build = iwl3945_ucode_get_build,
2753 .get_inst_size = iwl3945_ucode_get_inst_size,
2754 .get_data_size = iwl3945_ucode_get_data_size,
2755 .get_init_size = iwl3945_ucode_get_init_size,
2756 .get_init_data_size = iwl3945_ucode_get_init_data_size,
2757 .get_boot_size = iwl3945_ucode_get_boot_size,
2758 .get_data = iwl3945_ucode_get_data,
2759}; 2819};
2760 2820
2761static struct iwl_lib_ops iwl3945_lib = { 2821static struct iwl_lib_ops iwl3945_lib = {
@@ -2791,17 +2851,24 @@ static struct iwl_lib_ops iwl3945_lib = {
2791 .post_associate = iwl3945_post_associate, 2851 .post_associate = iwl3945_post_associate,
2792 .isr = iwl_isr_legacy, 2852 .isr = iwl_isr_legacy,
2793 .config_ap = iwl3945_config_ap, 2853 .config_ap = iwl3945_config_ap,
2794 .add_bcast_station = iwl3945_add_bcast_station, 2854 .manage_ibss_station = iwl3945_manage_ibss_station,
2855 .check_plcp_health = iwl3945_good_plcp_health,
2856
2857 .debugfs_ops = {
2858 .rx_stats_read = iwl3945_ucode_rx_stats_read,
2859 .tx_stats_read = iwl3945_ucode_tx_stats_read,
2860 .general_stats_read = iwl3945_ucode_general_stats_read,
2861 },
2795}; 2862};
2796 2863
2797static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2864static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2798 .get_hcmd_size = iwl3945_get_hcmd_size, 2865 .get_hcmd_size = iwl3945_get_hcmd_size,
2799 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2866 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
2800 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2867 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2868 .request_scan = iwl3945_request_scan,
2801}; 2869};
2802 2870
2803static const struct iwl_ops iwl3945_ops = { 2871static const struct iwl_ops iwl3945_ops = {
2804 .ucode = &iwl3945_ucode,
2805 .lib = &iwl3945_lib, 2872 .lib = &iwl3945_lib,
2806 .hcmd = &iwl3945_hcmd, 2873 .hcmd = &iwl3945_hcmd,
2807 .utils = &iwl3945_hcmd_utils, 2874 .utils = &iwl3945_hcmd_utils,
@@ -2826,7 +2893,10 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2826 .ht_greenfield_support = false, 2893 .ht_greenfield_support = false,
2827 .led_compensation = 64, 2894 .led_compensation = 64,
2828 .broken_powersave = true, 2895 .broken_powersave = true,
2829 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2896 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2897 .monitor_recover_period = IWL_MONITORING_PERIOD,
2898 .max_event_log_size = 512,
2899 .tx_power_by_driver = true,
2830}; 2900};
2831 2901
2832static struct iwl_cfg iwl3945_abg_cfg = { 2902static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2844,7 +2914,10 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2844 .ht_greenfield_support = false, 2914 .ht_greenfield_support = false,
2845 .led_compensation = 64, 2915 .led_compensation = 64,
2846 .broken_powersave = true, 2916 .broken_powersave = true,
2847 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2917 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
2918 .monitor_recover_period = IWL_MONITORING_PERIOD,
2919 .max_event_log_size = 512,
2920 .tx_power_by_driver = true,
2848}; 2921};
2849 2922
2850DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2923DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 452dfd5456c6..bb2aeebf3652 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -95,7 +95,6 @@ struct iwl3945_rs_sta {
95 u8 tgg; 95 u8 tgg;
96 u8 flush_pending; 96 u8 flush_pending;
97 u8 start_rate; 97 u8 start_rate;
98 u8 ibss_sta_added;
99 struct timer_list rate_scale_flush; 98 struct timer_list rate_scale_flush;
100 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; 99 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
101#ifdef CONFIG_MAC80211_DEBUGFS 100#ifdef CONFIG_MAC80211_DEBUGFS
@@ -107,7 +106,12 @@ struct iwl3945_rs_sta {
107}; 106};
108 107
109 108
109/*
110 * The common struct MUST be first because it is shared between
111 * 3945 and agn!
112 */
110struct iwl3945_sta_priv { 113struct iwl3945_sta_priv {
114 struct iwl_station_priv_common common;
111 struct iwl3945_rs_sta rs_sta; 115 struct iwl3945_rs_sta rs_sta;
112}; 116};
113 117
@@ -212,13 +216,6 @@ extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
212 char **buf, bool display); 216 char **buf, bool display);
213extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 217extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
214 218
215/*
216 * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
217 * call this... todo... fix that.
218*/
219extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
220 u16 tx_rate, u8 flags);
221
222/****************************************************************************** 219/******************************************************************************
223 * 220 *
224 * Functions implemented in iwl-[34]*.c which are forward declared here 221 * Functions implemented in iwl-[34]*.c which are forward declared here
@@ -265,10 +262,14 @@ extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
265extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); 262extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
266extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 263extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
267 struct iwl_rx_mem_buffer *rxb); 264 struct iwl_rx_mem_buffer *rxb);
265void iwl3945_reply_statistics(struct iwl_priv *priv,
266 struct iwl_rx_mem_buffer *rxb);
268extern void iwl3945_disable_events(struct iwl_priv *priv); 267extern void iwl3945_disable_events(struct iwl_priv *priv);
269extern int iwl4965_get_temperature(const struct iwl_priv *priv); 268extern int iwl4965_get_temperature(const struct iwl_priv *priv);
270extern void iwl3945_post_associate(struct iwl_priv *priv); 269extern void iwl3945_post_associate(struct iwl_priv *priv,
271extern void iwl3945_config_ap(struct iwl_priv *priv); 270 struct ieee80211_vif *vif);
271extern void iwl3945_config_ap(struct iwl_priv *priv,
272 struct ieee80211_vif *vif);
272 273
273/** 274/**
274 * iwl3945_hw_find_station - Find station id for a given BSSID 275 * iwl3945_hw_find_station - Find station id for a given BSSID
@@ -287,14 +288,15 @@ extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
287extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); 288extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
288extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); 289extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
289extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); 290extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
290extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
291 u16 tx_rate, u8 flags);
292 291
293extern const struct iwl_channel_info *iwl3945_get_channel_info( 292extern const struct iwl_channel_info *iwl3945_get_channel_info(
294 const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); 293 const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
295 294
296extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); 295extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
297 296
297/* scanning */
298void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
299
298/* Requires full declaration of iwl_priv before including */ 300/* Requires full declaration of iwl_priv before including */
299#include "iwl-io.h" 301#include "iwl-io.h"
300 302
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 67ef562e8db1..cd4b61ae25b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -81,26 +81,6 @@
81 */ 81 */
82#define IWL49_FIRST_AMPDU_QUEUE 7 82#define IWL49_FIRST_AMPDU_QUEUE 7
83 83
84/* Time constants */
85#define SHORT_SLOT_TIME 9
86#define LONG_SLOT_TIME 20
87
88/* RSSI to dBm */
89#define IWL49_RSSI_OFFSET 44
90
91
92/* PCI registers */
93#define PCI_CFG_RETRY_TIMEOUT 0x041
94
95/* PCI register values */
96#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
97#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
98
99#define IWL_NUM_SCAN_RATES (2)
100
101#define IWL_DEFAULT_TX_RETRY 15
102
103
104/* Sizes and addresses for instruction and data memory (SRAM) in 84/* Sizes and addresses for instruction and data memory (SRAM) in
105 * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ 85 * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
106#define IWL49_RTC_INST_LOWER_BOUND (0x000000) 86#define IWL49_RTC_INST_LOWER_BOUND (0x000000)
@@ -393,10 +373,6 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
393 * location(s) in command (struct iwl4965_txpowertable_cmd). 373 * location(s) in command (struct iwl4965_txpowertable_cmd).
394 */ 374 */
395 375
396/* Limit range of txpower output target to be between these values */
397#define IWL_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm = 1 milliwatt */
398#define IWL_TX_POWER_TARGET_POWER_MAX (16) /* 16 dBm */
399
400/** 376/**
401 * When MIMO is used (2 transmitters operating simultaneously), driver should 377 * When MIMO is used (2 transmitters operating simultaneously), driver should
402 * limit each transmitter to deliver a max of 3 dB below the regulatory limit 378 * limit each transmitter to deliver a max of 3 dB below the regulatory limit
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 8972166386cb..d3afddae8d9f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -46,6 +46,8 @@
46#include "iwl-calib.h" 46#include "iwl-calib.h"
47#include "iwl-sta.h" 47#include "iwl-sta.h"
48#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn.h"
50#include "iwl-agn-debugfs.h"
49 51
50static int iwl4965_send_tx_power(struct iwl_priv *priv); 52static int iwl4965_send_tx_power(struct iwl_priv *priv);
51static int iwl4965_hw_get_temperature(struct iwl_priv *priv); 53static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -60,14 +62,6 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
60#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" 62#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
61#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) 63#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
62 64
63
64/* module parameters */
65static struct iwl_mod_params iwl4965_mod_params = {
66 .amsdu_size_8K = 1,
67 .restart_fw = 1,
68 /* the rest are 0 by default */
69};
70
71/* check contents of special bootstrap uCode SRAM */ 65/* check contents of special bootstrap uCode SRAM */
72static int iwl4965_verify_bsm(struct iwl_priv *priv) 66static int iwl4965_verify_bsm(struct iwl_priv *priv)
73{ 67{
@@ -417,7 +411,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
417 sizeof(cmd), &cmd); 411 sizeof(cmd), &cmd);
418 if (ret) 412 if (ret)
419 IWL_DEBUG_CALIB(priv, "fail sending cmd " 413 IWL_DEBUG_CALIB(priv, "fail sending cmd "
420 "REPLY_PHY_CALIBRATION_CMD \n"); 414 "REPLY_PHY_CALIBRATION_CMD\n");
421 415
422 /* TODO we might want recalculate 416 /* TODO we might want recalculate
423 * rx_chain in rxon cmd */ 417 * rx_chain in rxon cmd */
@@ -502,14 +496,14 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
502 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); 496 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
503} 497}
504 498
505static const u16 default_queue_to_tx_fifo[] = { 499static const s8 default_queue_to_tx_fifo[] = {
506 IWL_TX_FIFO_AC3, 500 IWL_TX_FIFO_VO,
507 IWL_TX_FIFO_AC2, 501 IWL_TX_FIFO_VI,
508 IWL_TX_FIFO_AC1, 502 IWL_TX_FIFO_BE,
509 IWL_TX_FIFO_AC0, 503 IWL_TX_FIFO_BK,
510 IWL49_CMD_FIFO_NUM, 504 IWL49_CMD_FIFO_NUM,
511 IWL_TX_FIFO_HCCA_1, 505 IWL_TX_FIFO_UNUSED,
512 IWL_TX_FIFO_HCCA_2 506 IWL_TX_FIFO_UNUSED,
513}; 507};
514 508
515static int iwl4965_alive_notify(struct iwl_priv *priv) 509static int iwl4965_alive_notify(struct iwl_priv *priv)
@@ -589,9 +583,15 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
589 /* reset to 0 to enable all the queue first */ 583 /* reset to 0 to enable all the queue first */
590 priv->txq_ctx_active_msk = 0; 584 priv->txq_ctx_active_msk = 0;
591 /* Map each Tx/cmd queue to its corresponding fifo */ 585 /* Map each Tx/cmd queue to its corresponding fifo */
586 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
592 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { 587 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
593 int ac = default_queue_to_tx_fifo[i]; 588 int ac = default_queue_to_tx_fifo[i];
589
594 iwl_txq_ctx_activate(priv, i); 590 iwl_txq_ctx_activate(priv, i);
591
592 if (ac == IWL_TX_FIFO_UNUSED)
593 continue;
594
595 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); 595 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
596 } 596 }
597 597
@@ -1613,19 +1613,19 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
1613 1613
1614 /* get absolute value */ 1614 /* get absolute value */
1615 if (temp_diff < 0) { 1615 if (temp_diff < 0) {
1616 IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff); 1616 IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff);
1617 temp_diff = -temp_diff; 1617 temp_diff = -temp_diff;
1618 } else if (temp_diff == 0) 1618 } else if (temp_diff == 0)
1619 IWL_DEBUG_POWER(priv, "Same temp, \n"); 1619 IWL_DEBUG_POWER(priv, "Temperature unchanged\n");
1620 else 1620 else
1621 IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff); 1621 IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff);
1622 1622
1623 if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { 1623 if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
1624 IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n"); 1624 IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n");
1625 return 0; 1625 return 0;
1626 } 1626 }
1627 1627
1628 IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n"); 1628 IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n");
1629 1629
1630 return 1; 1630 return 1;
1631} 1631}
@@ -1874,7 +1874,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1874 info->status.rates[0].count = tx_resp->failure_frame + 1; 1874 info->status.rates[0].count = tx_resp->failure_frame + 1;
1875 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 1875 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1876 info->flags |= iwl_tx_status_to_mac80211(status); 1876 info->flags |= iwl_tx_status_to_mac80211(status);
1877 iwl_hwrate_to_tx_control(priv, rate_n_flags, info); 1877 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
1878 /* FIXME: code repetition end */ 1878 /* FIXME: code repetition end */
1879 1879
1880 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", 1880 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
@@ -1953,6 +1953,60 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1953 return 0; 1953 return 0;
1954} 1954}
1955 1955
1956static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
1957{
1958 int i;
1959 int start = 0;
1960 int ret = IWL_INVALID_STATION;
1961 unsigned long flags;
1962
1963 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
1964 (priv->iw_mode == NL80211_IFTYPE_AP))
1965 start = IWL_STA_ID;
1966
1967 if (is_broadcast_ether_addr(addr))
1968 return priv->hw_params.bcast_sta_id;
1969
1970 spin_lock_irqsave(&priv->sta_lock, flags);
1971 for (i = start; i < priv->hw_params.max_stations; i++)
1972 if (priv->stations[i].used &&
1973 (!compare_ether_addr(priv->stations[i].sta.sta.addr,
1974 addr))) {
1975 ret = i;
1976 goto out;
1977 }
1978
1979 IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
1980 addr, priv->num_stations);
1981
1982 out:
1983 /*
1984 * It may be possible that more commands interacting with stations
1985 * arrive before we completed processing the adding of
1986 * station
1987 */
1988 if (ret != IWL_INVALID_STATION &&
1989 (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
1990 ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
1991 (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
1992 IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
1993 ret);
1994 ret = IWL_INVALID_STATION;
1995 }
1996 spin_unlock_irqrestore(&priv->sta_lock, flags);
1997 return ret;
1998}
1999
2000static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
2001{
2002 if (priv->iw_mode == NL80211_IFTYPE_STATION) {
2003 return IWL_AP_ID;
2004 } else {
2005 u8 *da = ieee80211_get_DA(hdr);
2006 return iwl_find_station(priv, da);
2007 }
2008}
2009
1956/** 2010/**
1957 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response 2011 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
1958 */ 2012 */
@@ -2014,7 +2068,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2014 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 2068 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2015 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " 2069 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2016 "%d index %d\n", scd_ssn , index); 2070 "%d index %d\n", scd_ssn , index);
2017 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2071 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2018 if (qc) 2072 if (qc)
2019 iwl_free_tfds_in_queue(priv, sta_id, 2073 iwl_free_tfds_in_queue(priv, sta_id,
2020 tid, freed); 2074 tid, freed);
@@ -2031,7 +2085,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2031 } else { 2085 } else {
2032 info->status.rates[0].count = tx_resp->failure_frame + 1; 2086 info->status.rates[0].count = tx_resp->failure_frame + 1;
2033 info->flags |= iwl_tx_status_to_mac80211(status); 2087 info->flags |= iwl_tx_status_to_mac80211(status);
2034 iwl_hwrate_to_tx_control(priv, 2088 iwlagn_hwrate_to_tx_control(priv,
2035 le32_to_cpu(tx_resp->rate_n_flags), 2089 le32_to_cpu(tx_resp->rate_n_flags),
2036 info); 2090 info);
2037 2091
@@ -2042,7 +2096,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2042 le32_to_cpu(tx_resp->rate_n_flags), 2096 le32_to_cpu(tx_resp->rate_n_flags),
2043 tx_resp->failure_frame); 2097 tx_resp->failure_frame);
2044 2098
2045 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2099 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2046 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2100 if (qc && likely(sta_id != IWL_INVALID_STATION))
2047 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 2101 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2048 else if (sta_id == IWL_INVALID_STATION) 2102 else if (sta_id == IWL_INVALID_STATION)
@@ -2053,10 +2107,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2053 iwl_wake_queue(priv, txq_id); 2107 iwl_wake_queue(priv, txq_id);
2054 } 2108 }
2055 if (qc && likely(sta_id != IWL_INVALID_STATION)) 2109 if (qc && likely(sta_id != IWL_INVALID_STATION))
2056 iwl_txq_check_empty(priv, sta_id, tid, txq_id); 2110 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2057 2111
2058 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 2112 iwl_check_abort_status(priv, tx_resp->frame_count, status);
2059 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
2060} 2113}
2061 2114
2062static int iwl4965_calc_rssi(struct iwl_priv *priv, 2115static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2090,7 +2143,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
2090 2143
2091 /* dBm = max_rssi dB - agc dB - constant. 2144 /* dBm = max_rssi dB - agc dB - constant.
2092 * Higher AGC (higher radio gain) means lower signal. */ 2145 * Higher AGC (higher radio gain) means lower signal. */
2093 return max_rssi - agc - IWL49_RSSI_OFFSET; 2146 return max_rssi - agc - IWLAGN_RSSI_OFFSET;
2094} 2147}
2095 2148
2096 2149
@@ -2098,7 +2151,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
2098static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 2151static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2099{ 2152{
2100 /* Legacy Rx frames */ 2153 /* Legacy Rx frames */
2101 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx; 2154 priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx;
2102 /* Tx response */ 2155 /* Tx response */
2103 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; 2156 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2104} 2157}
@@ -2113,50 +2166,13 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2113 cancel_work_sync(&priv->txpower_work); 2166 cancel_work_sync(&priv->txpower_work);
2114} 2167}
2115 2168
2116#define IWL4965_UCODE_GET(item) \
2117static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2118 u32 api_ver) \
2119{ \
2120 return le32_to_cpu(ucode->u.v1.item); \
2121}
2122
2123static u32 iwl4965_ucode_get_header_size(u32 api_ver)
2124{
2125 return UCODE_HEADER_SIZE(1);
2126}
2127static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
2128 u32 api_ver)
2129{
2130 return 0;
2131}
2132static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
2133 u32 api_ver)
2134{
2135 return (u8 *) ucode->u.v1.data;
2136}
2137
2138IWL4965_UCODE_GET(inst_size);
2139IWL4965_UCODE_GET(data_size);
2140IWL4965_UCODE_GET(init_size);
2141IWL4965_UCODE_GET(init_data_size);
2142IWL4965_UCODE_GET(boot_size);
2143
2144static struct iwl_hcmd_ops iwl4965_hcmd = { 2169static struct iwl_hcmd_ops iwl4965_hcmd = {
2145 .rxon_assoc = iwl4965_send_rxon_assoc, 2170 .rxon_assoc = iwl4965_send_rxon_assoc,
2146 .commit_rxon = iwl_commit_rxon, 2171 .commit_rxon = iwl_commit_rxon,
2147 .set_rxon_chain = iwl_set_rxon_chain, 2172 .set_rxon_chain = iwl_set_rxon_chain,
2173 .send_bt_config = iwl_send_bt_config,
2148}; 2174};
2149 2175
2150static struct iwl_ucode_ops iwl4965_ucode = {
2151 .get_header_size = iwl4965_ucode_get_header_size,
2152 .get_build = iwl4965_ucode_get_build,
2153 .get_inst_size = iwl4965_ucode_get_inst_size,
2154 .get_data_size = iwl4965_ucode_get_data_size,
2155 .get_init_size = iwl4965_ucode_get_init_size,
2156 .get_init_data_size = iwl4965_ucode_get_init_data_size,
2157 .get_boot_size = iwl4965_ucode_get_boot_size,
2158 .get_data = iwl4965_ucode_get_data,
2159};
2160static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2176static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2161 .get_hcmd_size = iwl4965_get_hcmd_size, 2177 .get_hcmd_size = iwl4965_get_hcmd_size,
2162 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2178 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2164,6 +2180,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2164 .gain_computation = iwl4965_gain_computation, 2180 .gain_computation = iwl4965_gain_computation,
2165 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2181 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2166 .calc_rssi = iwl4965_calc_rssi, 2182 .calc_rssi = iwl4965_calc_rssi,
2183 .request_scan = iwlagn_request_scan,
2167}; 2184};
2168 2185
2169static struct iwl_lib_ops iwl4965_lib = { 2186static struct iwl_lib_ops iwl4965_lib = {
@@ -2184,6 +2201,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2184 .load_ucode = iwl4965_load_bsm, 2201 .load_ucode = iwl4965_load_bsm,
2185 .dump_nic_event_log = iwl_dump_nic_event_log, 2202 .dump_nic_event_log = iwl_dump_nic_event_log,
2186 .dump_nic_error_log = iwl_dump_nic_error_log, 2203 .dump_nic_error_log = iwl_dump_nic_error_log,
2204 .dump_fh = iwl_dump_fh,
2187 .set_channel_switch = iwl4965_hw_channel_switch, 2205 .set_channel_switch = iwl4965_hw_channel_switch,
2188 .apm_ops = { 2206 .apm_ops = {
2189 .init = iwl_apm_init, 2207 .init = iwl_apm_init,
@@ -2216,11 +2234,16 @@ static struct iwl_lib_ops iwl4965_lib = {
2216 .temperature = iwl4965_temperature_calib, 2234 .temperature = iwl4965_temperature_calib,
2217 .set_ct_kill = iwl4965_set_ct_threshold, 2235 .set_ct_kill = iwl4965_set_ct_threshold,
2218 }, 2236 },
2219 .add_bcast_station = iwl_add_bcast_station, 2237 .manage_ibss_station = iwlagn_manage_ibss_station,
2238 .debugfs_ops = {
2239 .rx_stats_read = iwl_ucode_rx_stats_read,
2240 .tx_stats_read = iwl_ucode_tx_stats_read,
2241 .general_stats_read = iwl_ucode_general_stats_read,
2242 },
2243 .check_plcp_health = iwl_good_plcp_health,
2220}; 2244};
2221 2245
2222static const struct iwl_ops iwl4965_ops = { 2246static const struct iwl_ops iwl4965_ops = {
2223 .ucode = &iwl4965_ucode,
2224 .lib = &iwl4965_lib, 2247 .lib = &iwl4965_lib,
2225 .hcmd = &iwl4965_hcmd, 2248 .hcmd = &iwl4965_hcmd,
2226 .utils = &iwl4965_hcmd_utils, 2249 .utils = &iwl4965_hcmd_utils,
@@ -2228,7 +2251,7 @@ static const struct iwl_ops iwl4965_ops = {
2228}; 2251};
2229 2252
2230struct iwl_cfg iwl4965_agn_cfg = { 2253struct iwl_cfg iwl4965_agn_cfg = {
2231 .name = "4965AGN", 2254 .name = "Intel(R) Wireless WiFi Link 4965AGN",
2232 .fw_name_pre = IWL4965_FW_PRE, 2255 .fw_name_pre = IWL4965_FW_PRE,
2233 .ucode_api_max = IWL4965_UCODE_API_MAX, 2256 .ucode_api_max = IWL4965_UCODE_API_MAX,
2234 .ucode_api_min = IWL4965_UCODE_API_MIN, 2257 .ucode_api_min = IWL4965_UCODE_API_MIN,
@@ -2239,7 +2262,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .ops = &iwl4965_ops, 2262 .ops = &iwl4965_ops,
2240 .num_of_queues = IWL49_NUM_QUEUES, 2263 .num_of_queues = IWL49_NUM_QUEUES,
2241 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, 2264 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2242 .mod_params = &iwl4965_mod_params, 2265 .mod_params = &iwlagn_mod_params,
2243 .valid_tx_ant = ANT_AB, 2266 .valid_tx_ant = ANT_AB,
2244 .valid_rx_ant = ANT_ABC, 2267 .valid_rx_ant = ANT_ABC,
2245 .pll_cfg_val = 0, 2268 .pll_cfg_val = 0,
@@ -2251,27 +2274,20 @@ struct iwl_cfg iwl4965_agn_cfg = {
2251 .led_compensation = 61, 2274 .led_compensation = 61,
2252 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2275 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2253 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2276 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2277 .monitor_recover_period = IWL_MONITORING_PERIOD,
2278 .temperature_kelvin = true,
2279 .max_event_log_size = 512,
2280 .tx_power_by_driver = true,
2281 .ucode_tracing = true,
2282 .sensitivity_calib_by_driver = true,
2283 .chain_noise_calib_by_driver = true,
2284 /*
2285 * Force use of chains B and C for scan RX on 5 GHz band
2286 * because the device has off-channel reception on chain A.
2287 */
2288 .scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
2254}; 2289};
2255 2290
2256/* Module firmware */ 2291/* Module firmware */
2257MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); 2292MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
2258 2293
2259module_param_named(antenna, iwl4965_mod_params.antenna, int, S_IRUGO);
2260MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
2261module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO);
2262MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
2263module_param_named(
2264 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, S_IRUGO);
2265MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
2266
2267module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO);
2268MODULE_PARM_DESC(queues_num, "number of hw queues.");
2269/* 11n */
2270module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO);
2271MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
2272module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K,
2273 int, S_IRUGO);
2274MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
2275
2276module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, S_IRUGO);
2277MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 714e032f6217..146e6431ae95 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -68,25 +68,6 @@
68#ifndef __iwl_5000_hw_h__ 68#ifndef __iwl_5000_hw_h__
69#define __iwl_5000_hw_h__ 69#define __iwl_5000_hw_h__
70 70
71#define IWL50_RTC_INST_LOWER_BOUND (0x000000)
72#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
73
74#define IWL50_RTC_DATA_LOWER_BOUND (0x800000)
75#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
76
77#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
78 IWL50_RTC_INST_LOWER_BOUND)
79#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
80 IWL50_RTC_DATA_LOWER_BOUND)
81
82/* EEPROM */
83#define IWL_5000_EEPROM_IMG_SIZE 2048
84
85#define IWL50_CMD_FIFO_NUM 7
86#define IWL50_NUM_QUEUES 20
87#define IWL50_NUM_AMPDU_QUEUES 10
88#define IWL50_FIRST_AMPDU_QUEUE 10
89
90/* 5150 only */ 71/* 5150 only */
91#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5) 72#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
92 73
@@ -103,19 +84,5 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
103 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); 84 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
104} 85}
105 86
106/* Fixed (non-configurable) rx data from phy */
107
108/**
109 * struct iwl5000_schedq_bc_tbl scheduler byte count table
110 * base physical address of iwl5000_shared
111 * is provided to SCD_DRAM_BASE_ADDR
112 * @tfd_offset 0-12 - tx command byte count
113 * 12-16 - station index
114 */
115struct iwl5000_scd_bc_tbl {
116 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
117} __attribute__ ((packed));
118
119
120#endif /* __iwl_5000_hw_h__ */ 87#endif /* __iwl_5000_hw_h__ */
121 88
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e476acb53aa7..a28af7eb67eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -19,6 +19,7 @@
19 * file called LICENSE. 19 * file called LICENSE.
20 * 20 *
21 * Contact Information: 21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
22 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
23 * 24 *
24 *****************************************************************************/ 25 *****************************************************************************/
@@ -43,9 +44,11 @@
43#include "iwl-io.h" 44#include "iwl-io.h"
44#include "iwl-sta.h" 45#include "iwl-sta.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
47#include "iwl-agn.h"
46#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn-hw.h"
47#include "iwl-5000-hw.h" 50#include "iwl-5000-hw.h"
48#include "iwl-6000-hw.h" 51#include "iwl-agn-debugfs.h"
49 52
50/* Highest firmware API version supported */ 53/* Highest firmware API version supported */
51#define IWL5000_UCODE_API_MAX 2 54#define IWL5000_UCODE_API_MAX 2
@@ -63,18 +66,8 @@
63#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" 66#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
64#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) 67#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
65 68
66static const u16 iwl5000_default_queue_to_tx_fifo[] = {
67 IWL_TX_FIFO_AC3,
68 IWL_TX_FIFO_AC2,
69 IWL_TX_FIFO_AC1,
70 IWL_TX_FIFO_AC0,
71 IWL50_CMD_FIFO_NUM,
72 IWL_TX_FIFO_HCCA_1,
73 IWL_TX_FIFO_HCCA_2
74};
75
76/* NIC configuration for 5000 series */ 69/* NIC configuration for 5000 series */
77void iwl5000_nic_config(struct iwl_priv *priv) 70static void iwl5000_nic_config(struct iwl_priv *priv)
78{ 71{
79 unsigned long flags; 72 unsigned long flags;
80 u16 radio_cfg; 73 u16 radio_cfg;
@@ -107,162 +100,6 @@ void iwl5000_nic_config(struct iwl_priv *priv)
107 spin_unlock_irqrestore(&priv->lock, flags); 100 spin_unlock_irqrestore(&priv->lock, flags);
108} 101}
109 102
110
111/*
112 * EEPROM
113 */
114static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
115{
116 u16 offset = 0;
117
118 if ((address & INDIRECT_ADDRESS) == 0)
119 return address;
120
121 switch (address & INDIRECT_TYPE_MSK) {
122 case INDIRECT_HOST:
123 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
124 break;
125 case INDIRECT_GENERAL:
126 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
127 break;
128 case INDIRECT_REGULATORY:
129 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
130 break;
131 case INDIRECT_CALIBRATION:
132 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
133 break;
134 case INDIRECT_PROCESS_ADJST:
135 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
136 break;
137 case INDIRECT_OTHERS:
138 offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
139 break;
140 default:
141 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
142 address & INDIRECT_TYPE_MSK);
143 break;
144 }
145
146 /* translate the offset from words to byte */
147 return (address & ADDRESS_MSK) + (offset << 1);
148}
149
150u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
151{
152 struct iwl_eeprom_calib_hdr {
153 u8 version;
154 u8 pa_type;
155 u16 voltage;
156 } *hdr;
157
158 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
159 EEPROM_5000_CALIB_ALL);
160 return hdr->version;
161
162}
163
164static void iwl5000_gain_computation(struct iwl_priv *priv,
165 u32 average_noise[NUM_RX_CHAINS],
166 u16 min_average_noise_antenna_i,
167 u32 min_average_noise,
168 u8 default_chain)
169{
170 int i;
171 s32 delta_g;
172 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
173
174 /*
175 * Find Gain Code for the chains based on "default chain"
176 */
177 for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
178 if ((data->disconn_array[i])) {
179 data->delta_gain_code[i] = 0;
180 continue;
181 }
182
183 delta_g = (priv->cfg->chain_noise_scale *
184 ((s32)average_noise[default_chain] -
185 (s32)average_noise[i])) / 1500;
186
187 /* bound gain by 2 bits value max, 3rd bit is sign */
188 data->delta_gain_code[i] =
189 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
190
191 if (delta_g < 0)
192 /*
193 * set negative sign ...
194 * note to Intel developers: This is uCode API format,
195 * not the format of any internal device registers.
196 * Do not change this format for e.g. 6050 or similar
197 * devices. Change format only if more resolution
198 * (i.e. more than 2 bits magnitude) is needed.
199 */
200 data->delta_gain_code[i] |= (1 << 2);
201 }
202
203 IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
204 data->delta_gain_code[1], data->delta_gain_code[2]);
205
206 if (!data->radio_write) {
207 struct iwl_calib_chain_noise_gain_cmd cmd;
208
209 memset(&cmd, 0, sizeof(cmd));
210
211 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
212 cmd.hdr.first_group = 0;
213 cmd.hdr.groups_num = 1;
214 cmd.hdr.data_valid = 1;
215 cmd.delta_gain_1 = data->delta_gain_code[1];
216 cmd.delta_gain_2 = data->delta_gain_code[2];
217 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
218 sizeof(cmd), &cmd, NULL);
219
220 data->radio_write = 1;
221 data->state = IWL_CHAIN_NOISE_CALIBRATED;
222 }
223
224 data->chain_noise_a = 0;
225 data->chain_noise_b = 0;
226 data->chain_noise_c = 0;
227 data->chain_signal_a = 0;
228 data->chain_signal_b = 0;
229 data->chain_signal_c = 0;
230 data->beacon_count = 0;
231}
232
233static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
234{
235 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
236 int ret;
237
238 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
239 struct iwl_calib_chain_noise_reset_cmd cmd;
240 memset(&cmd, 0, sizeof(cmd));
241
242 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
243 cmd.hdr.first_group = 0;
244 cmd.hdr.groups_num = 1;
245 cmd.hdr.data_valid = 1;
246 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
247 sizeof(cmd), &cmd);
248 if (ret)
249 IWL_ERR(priv,
250 "Could not send REPLY_PHY_CALIBRATION_CMD\n");
251 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
252 IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
253 }
254}
255
256void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
257 __le32 *tx_flags)
258{
259 if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
260 (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
261 *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
262 else
263 *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
264}
265
266static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 103static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
267 .min_nrg_cck = 95, 104 .min_nrg_cck = 95,
268 .max_nrg_cck = 0, /* not used, set to 0 */ 105 .max_nrg_cck = 0, /* not used, set to 0 */
@@ -314,14 +151,6 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
314 .nrg_th_cca = 62, 151 .nrg_th_cca = 62,
315}; 152};
316 153
317const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
318 size_t offset)
319{
320 u32 address = eeprom_indirect_address(priv, offset);
321 BUG_ON(address >= priv->cfg->eeprom_size);
322 return &priv->eeprom[address];
323}
324
325static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 154static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
326{ 155{
327 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 156 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
@@ -337,356 +166,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
337 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; 166 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
338} 167}
339 168
340/* 169static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
341 * Calibration
342 */
343static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
344{
345 struct iwl_calib_xtal_freq_cmd cmd;
346 __le16 *xtal_calib =
347 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
348
349 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
350 cmd.hdr.first_group = 0;
351 cmd.hdr.groups_num = 1;
352 cmd.hdr.data_valid = 1;
353 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
354 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
355 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
356 (u8 *)&cmd, sizeof(cmd));
357}
358
359static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
360{
361 struct iwl_calib_cfg_cmd calib_cfg_cmd;
362 struct iwl_host_cmd cmd = {
363 .id = CALIBRATION_CFG_CMD,
364 .len = sizeof(struct iwl_calib_cfg_cmd),
365 .data = &calib_cfg_cmd,
366 };
367
368 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
369 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
370 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
371 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
372 calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
373
374 return iwl_send_cmd(priv, &cmd);
375}
376
377static void iwl5000_rx_calib_result(struct iwl_priv *priv,
378 struct iwl_rx_mem_buffer *rxb)
379{
380 struct iwl_rx_packet *pkt = rxb_addr(rxb);
381 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
382 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
383 int index;
384
385 /* reduce the size of the length field itself */
386 len -= 4;
387
388 /* Define the order in which the results will be sent to the runtime
389 * uCode. iwl_send_calib_results sends them in a row according to their
390 * index. We sort them here */
391 switch (hdr->op_code) {
392 case IWL_PHY_CALIBRATE_DC_CMD:
393 index = IWL_CALIB_DC;
394 break;
395 case IWL_PHY_CALIBRATE_LO_CMD:
396 index = IWL_CALIB_LO;
397 break;
398 case IWL_PHY_CALIBRATE_TX_IQ_CMD:
399 index = IWL_CALIB_TX_IQ;
400 break;
401 case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
402 index = IWL_CALIB_TX_IQ_PERD;
403 break;
404 case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
405 index = IWL_CALIB_BASE_BAND;
406 break;
407 default:
408 IWL_ERR(priv, "Unknown calibration notification %d\n",
409 hdr->op_code);
410 return;
411 }
412 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
413}
414
415static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
416 struct iwl_rx_mem_buffer *rxb)
417{
418 IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
419 queue_work(priv->workqueue, &priv->restart);
420}
421
422/*
423 * ucode
424 */
425static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
426 struct fw_desc *image, u32 dst_addr)
427{
428 dma_addr_t phy_addr = image->p_addr;
429 u32 byte_cnt = image->len;
430 int ret;
431
432 priv->ucode_write_complete = 0;
433
434 iwl_write_direct32(priv,
435 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
436 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
437
438 iwl_write_direct32(priv,
439 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
440
441 iwl_write_direct32(priv,
442 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
443 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
444
445 iwl_write_direct32(priv,
446 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
447 (iwl_get_dma_hi_addr(phy_addr)
448 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
449
450 iwl_write_direct32(priv,
451 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
452 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
453 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
454 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
455
456 iwl_write_direct32(priv,
457 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
458 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
459 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
460 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
461
462 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
463 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
464 priv->ucode_write_complete, 5 * HZ);
465 if (ret == -ERESTARTSYS) {
466 IWL_ERR(priv, "Could not load the %s uCode section due "
467 "to interrupt\n", name);
468 return ret;
469 }
470 if (!ret) {
471 IWL_ERR(priv, "Could not load the %s uCode section\n",
472 name);
473 return -ETIMEDOUT;
474 }
475
476 return 0;
477}
478
479static int iwl5000_load_given_ucode(struct iwl_priv *priv,
480 struct fw_desc *inst_image,
481 struct fw_desc *data_image)
482{
483 int ret = 0;
484
485 ret = iwl5000_load_section(priv, "INST", inst_image,
486 IWL50_RTC_INST_LOWER_BOUND);
487 if (ret)
488 return ret;
489
490 return iwl5000_load_section(priv, "DATA", data_image,
491 IWL50_RTC_DATA_LOWER_BOUND);
492}
493
494int iwl5000_load_ucode(struct iwl_priv *priv)
495{
496 int ret = 0;
497
498 /* check whether init ucode should be loaded, or rather runtime ucode */
499 if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
500 IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
501 ret = iwl5000_load_given_ucode(priv,
502 &priv->ucode_init, &priv->ucode_init_data);
503 if (!ret) {
504 IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
505 priv->ucode_type = UCODE_INIT;
506 }
507 } else {
508 IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
509 "Loading runtime ucode...\n");
510 ret = iwl5000_load_given_ucode(priv,
511 &priv->ucode_code, &priv->ucode_data);
512 if (!ret) {
513 IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
514 priv->ucode_type = UCODE_RT;
515 }
516 }
517
518 return ret;
519}
520
521void iwl5000_init_alive_start(struct iwl_priv *priv)
522{
523 int ret = 0;
524
525 /* Check alive response for "valid" sign from uCode */
526 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
527 /* We had an error bringing up the hardware, so take it
528 * all the way back down so we can try again */
529 IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
530 goto restart;
531 }
532
533 /* initialize uCode was loaded... verify inst image.
534 * This is a paranoid check, because we would not have gotten the
535 * "initialize" alive if code weren't properly loaded. */
536 if (iwl_verify_ucode(priv)) {
537 /* Runtime instruction load was bad;
538 * take it all the way back down so we can try again */
539 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
540 goto restart;
541 }
542
543 iwl_clear_stations_table(priv);
544 ret = priv->cfg->ops->lib->alive_notify(priv);
545 if (ret) {
546 IWL_WARN(priv,
547 "Could not complete ALIVE transition: %d\n", ret);
548 goto restart;
549 }
550
551 iwl5000_send_calib_cfg(priv);
552 return;
553
554restart:
555 /* real restart (first load init_ucode) */
556 queue_work(priv->workqueue, &priv->restart);
557}
558
559static void iwl5000_set_wr_ptrs(struct iwl_priv *priv,
560 int txq_id, u32 index)
561{
562 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
563 (index & 0xff) | (txq_id << 8));
564 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
565}
566
567static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
568 struct iwl_tx_queue *txq,
569 int tx_fifo_id, int scd_retry)
570{
571 int txq_id = txq->q.id;
572 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
573
574 iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
575 (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
576 (tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
577 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
578 IWL50_SCD_QUEUE_STTS_REG_MSK);
579
580 txq->sched_retry = scd_retry;
581
582 IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
583 active ? "Activate" : "Deactivate",
584 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
585}
586
587int iwl5000_alive_notify(struct iwl_priv *priv)
588{
589 u32 a;
590 unsigned long flags;
591 int i, chan;
592 u32 reg_val;
593
594 spin_lock_irqsave(&priv->lock, flags);
595
596 priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
597 a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
598 for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
599 a += 4)
600 iwl_write_targ_mem(priv, a, 0);
601 for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
602 a += 4)
603 iwl_write_targ_mem(priv, a, 0);
604 for (; a < priv->scd_base_addr +
605 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
606 iwl_write_targ_mem(priv, a, 0);
607
608 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
609 priv->scd_bc_tbls.dma >> 10);
610
611 /* Enable DMA channel */
612 for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
613 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
614 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
615 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
616
617 /* Update FH chicken bits */
618 reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
619 iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
620 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
621
622 iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
623 IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
624 iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
625
626 /* initiate the queues */
627 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
628 iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
629 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
630 iwl_write_targ_mem(priv, priv->scd_base_addr +
631 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
632 iwl_write_targ_mem(priv, priv->scd_base_addr +
633 IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
634 sizeof(u32),
635 ((SCD_WIN_SIZE <<
636 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
637 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
638 ((SCD_FRAME_LIMIT <<
639 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
640 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
641 }
642
643 iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
644 IWL_MASK(0, priv->hw_params.max_txq_num));
645
646 /* Activate all Tx DMA/FIFO channels */
647 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
648
649 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
650
651 /* make sure all queue are not stopped */
652 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
653 for (i = 0; i < 4; i++)
654 atomic_set(&priv->queue_stop_count[i], 0);
655
656 /* reset to 0 to enable all the queue first */
657 priv->txq_ctx_active_msk = 0;
658 /* map qos queues to fifos one-to-one */
659 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
660 int ac = iwl5000_default_queue_to_tx_fifo[i];
661 iwl_txq_ctx_activate(priv, i);
662 iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
663 }
664
665 /*
666 * TODO - need to initialize these queues and map them to FIFOs
667 * in the loop above, not only mark them as active. We do this
668 * because we want the first aggregation queue to be queue #10,
669 * but do not use 8 or 9 otherwise yet.
670 */
671 iwl_txq_ctx_activate(priv, 7);
672 iwl_txq_ctx_activate(priv, 8);
673 iwl_txq_ctx_activate(priv, 9);
674
675 spin_unlock_irqrestore(&priv->lock, flags);
676
677
678 iwl_send_wimax_coex(priv);
679
680 iwl5000_set_Xtal_calib(priv);
681 iwl_send_calib_results(priv);
682
683 return 0;
684}
685
686int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
687{ 170{
688 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 171 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
689 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 172 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
690 priv->cfg->num_of_queues = 173 priv->cfg->num_of_queues =
691 priv->cfg->mod_params->num_of_queues; 174 priv->cfg->mod_params->num_of_queues;
692 175
@@ -694,13 +177,13 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
694 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 177 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
695 priv->hw_params.scd_bc_tbls_size = 178 priv->hw_params.scd_bc_tbls_size =
696 priv->cfg->num_of_queues * 179 priv->cfg->num_of_queues *
697 sizeof(struct iwl5000_scd_bc_tbl); 180 sizeof(struct iwlagn_scd_bc_tbl);
698 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
699 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 182 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
700 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 183 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
701 184
702 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
703 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; 186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
704 187
705 priv->hw_params.max_bsm_size = 0; 188 priv->hw_params.max_bsm_size = 0;
706 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | 189 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
@@ -717,571 +200,61 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
717 200
718 /* Set initial sensitivity parameters */ 201 /* Set initial sensitivity parameters */
719 /* Set initial calibration set */ 202 /* Set initial calibration set */
720 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 203 priv->hw_params.sens = &iwl5000_sensitivity;
721 case CSR_HW_REV_TYPE_5150: 204 priv->hw_params.calib_init_cfg =
722 priv->hw_params.sens = &iwl5150_sensitivity; 205 BIT(IWL_CALIB_XTAL) |
723 priv->hw_params.calib_init_cfg = 206 BIT(IWL_CALIB_LO) |
724 BIT(IWL_CALIB_DC) | 207 BIT(IWL_CALIB_TX_IQ) |
725 BIT(IWL_CALIB_LO) | 208 BIT(IWL_CALIB_TX_IQ_PERD) |
726 BIT(IWL_CALIB_TX_IQ) | 209 BIT(IWL_CALIB_BASE_BAND);
727 BIT(IWL_CALIB_BASE_BAND);
728
729 break;
730 default:
731 priv->hw_params.sens = &iwl5000_sensitivity;
732 priv->hw_params.calib_init_cfg =
733 BIT(IWL_CALIB_XTAL) |
734 BIT(IWL_CALIB_LO) |
735 BIT(IWL_CALIB_TX_IQ) |
736 BIT(IWL_CALIB_TX_IQ_PERD) |
737 BIT(IWL_CALIB_BASE_BAND);
738 break;
739 }
740
741 return 0;
742}
743
744/**
745 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
746 */
747void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
748 struct iwl_tx_queue *txq,
749 u16 byte_cnt)
750{
751 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
752 int write_ptr = txq->q.write_ptr;
753 int txq_id = txq->q.id;
754 u8 sec_ctl = 0;
755 u8 sta_id = 0;
756 u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
757 __le16 bc_ent;
758
759 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
760
761 if (txq_id != IWL_CMD_QUEUE_NUM) {
762 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
763 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
764
765 switch (sec_ctl & TX_CMD_SEC_MSK) {
766 case TX_CMD_SEC_CCM:
767 len += CCMP_MIC_LEN;
768 break;
769 case TX_CMD_SEC_TKIP:
770 len += TKIP_ICV_LEN;
771 break;
772 case TX_CMD_SEC_WEP:
773 len += WEP_IV_LEN + WEP_ICV_LEN;
774 break;
775 }
776 }
777
778 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
779
780 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
781
782 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
783 scd_bc_tbl[txq_id].
784 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
785}
786
787void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
788 struct iwl_tx_queue *txq)
789{
790 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
791 int txq_id = txq->q.id;
792 int read_ptr = txq->q.read_ptr;
793 u8 sta_id = 0;
794 __le16 bc_ent;
795
796 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
797
798 if (txq_id != IWL_CMD_QUEUE_NUM)
799 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
800
801 bc_ent = cpu_to_le16(1 | (sta_id << 12));
802 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
803
804 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
805 scd_bc_tbl[txq_id].
806 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
807}
808
809static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
810 u16 txq_id)
811{
812 u32 tbl_dw_addr;
813 u32 tbl_dw;
814 u16 scd_q2ratid;
815
816 scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
817
818 tbl_dw_addr = priv->scd_base_addr +
819 IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
820
821 tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
822
823 if (txq_id & 0x1)
824 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
825 else
826 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
827
828 iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
829
830 return 0;
831}
832static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
833{
834 /* Simply stop the queue, but don't change any configuration;
835 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
836 iwl_write_prph(priv,
837 IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
838 (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
839 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
840}
841
842int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
843 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
844{
845 unsigned long flags;
846 u16 ra_tid;
847
848 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
849 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
850 <= txq_id)) {
851 IWL_WARN(priv,
852 "queue number out of range: %d, must be %d to %d\n",
853 txq_id, IWL50_FIRST_AMPDU_QUEUE,
854 IWL50_FIRST_AMPDU_QUEUE +
855 priv->cfg->num_of_ampdu_queues - 1);
856 return -EINVAL;
857 }
858
859 ra_tid = BUILD_RAxTID(sta_id, tid);
860
861 /* Modify device's station table to Tx this TID */
862 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
863
864 spin_lock_irqsave(&priv->lock, flags);
865
866 /* Stop this Tx queue before configuring it */
867 iwl5000_tx_queue_stop_scheduler(priv, txq_id);
868
869 /* Map receiver-address / traffic-ID to this queue */
870 iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
871
872 /* Set this queue as a chain-building queue */
873 iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
874
875 /* enable aggregations for the queue */
876 iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
877
878 /* Place first TFD at index corresponding to start sequence number.
879 * Assumes that ssn_idx is valid (!= 0xFFF) */
880 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
881 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
882 iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
883
884 /* Set up Tx window size and frame limit for this queue */
885 iwl_write_targ_mem(priv, priv->scd_base_addr +
886 IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
887 sizeof(u32),
888 ((SCD_WIN_SIZE <<
889 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
890 IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
891 ((SCD_FRAME_LIMIT <<
892 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
893 IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
894
895 iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
896
897 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
898 iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
899
900 spin_unlock_irqrestore(&priv->lock, flags);
901 210
902 return 0; 211 return 0;
903} 212}
904 213
905int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 214static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
906 u16 ssn_idx, u8 tx_fifo)
907{ 215{
908 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 216 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
909 (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 217 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
910 <= txq_id)) { 218 priv->cfg->num_of_queues =
911 IWL_ERR(priv, 219 priv->cfg->mod_params->num_of_queues;
912 "queue number out of range: %d, must be %d to %d\n",
913 txq_id, IWL50_FIRST_AMPDU_QUEUE,
914 IWL50_FIRST_AMPDU_QUEUE +
915 priv->cfg->num_of_ampdu_queues - 1);
916 return -EINVAL;
917 }
918
919 iwl5000_tx_queue_stop_scheduler(priv, txq_id);
920
921 iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
922
923 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
924 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
925 /* supposes that ssn_idx is valid (!= 0xFFF) */
926 iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
927
928 iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
929 iwl_txq_ctx_deactivate(priv, txq_id);
930 iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
931
932 return 0;
933}
934
935u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
936{
937 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
938 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
939 memcpy(addsta, cmd, size);
940 /* resrved in 5000 */
941 addsta->rate_n_flags = cpu_to_le16(0);
942 return size;
943}
944
945
946/*
947 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
948 * must be called under priv->lock and mac access
949 */
950void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
951{
952 iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
953}
954
955
956static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
957{
958 return le32_to_cpup((__le32 *)&tx_resp->status +
959 tx_resp->frame_count) & MAX_SN;
960}
961
962static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
963 struct iwl_ht_agg *agg,
964 struct iwl5000_tx_resp *tx_resp,
965 int txq_id, u16 start_idx)
966{
967 u16 status;
968 struct agg_tx_status *frame_status = &tx_resp->status;
969 struct ieee80211_tx_info *info = NULL;
970 struct ieee80211_hdr *hdr = NULL;
971 u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
972 int i, sh, idx;
973 u16 seq;
974
975 if (agg->wait_for_ba)
976 IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
977
978 agg->frame_count = tx_resp->frame_count;
979 agg->start_idx = start_idx;
980 agg->rate_n_flags = rate_n_flags;
981 agg->bitmap = 0;
982
983 /* # frames attempted by Tx command */
984 if (agg->frame_count == 1) {
985 /* Only one frame was attempted; no block-ack will arrive */
986 status = le16_to_cpu(frame_status[0].status);
987 idx = start_idx;
988
989 /* FIXME: code repetition */
990 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
991 agg->frame_count, agg->start_idx, idx);
992
993 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
994 info->status.rates[0].count = tx_resp->failure_frame + 1;
995 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
996 info->flags |= iwl_tx_status_to_mac80211(status);
997 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
998
999 /* FIXME: code repetition end */
1000
1001 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
1002 status & 0xff, tx_resp->failure_frame);
1003 IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
1004
1005 agg->wait_for_ba = 0;
1006 } else {
1007 /* Two or more frames were attempted; expect block-ack */
1008 u64 bitmap = 0;
1009 int start = agg->start_idx;
1010
1011 /* Construct bit-map of pending frames within Tx window */
1012 for (i = 0; i < agg->frame_count; i++) {
1013 u16 sc;
1014 status = le16_to_cpu(frame_status[i].status);
1015 seq = le16_to_cpu(frame_status[i].sequence);
1016 idx = SEQ_TO_INDEX(seq);
1017 txq_id = SEQ_TO_QUEUE(seq);
1018
1019 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
1020 AGG_TX_STATE_ABORT_MSK))
1021 continue;
1022 220
1023 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", 221 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
1024 agg->frame_count, txq_id, idx); 222 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
223 priv->hw_params.scd_bc_tbls_size =
224 priv->cfg->num_of_queues *
225 sizeof(struct iwlagn_scd_bc_tbl);
226 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
227 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
228 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
1025 229
1026 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); 230 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
1027 if (!hdr) { 231 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
1028 IWL_ERR(priv,
1029 "BUG_ON idx doesn't point to valid skb"
1030 " idx=%d, txq_id=%d\n", idx, txq_id);
1031 return -1;
1032 }
1033 232
1034 sc = le16_to_cpu(hdr->seq_ctrl); 233 priv->hw_params.max_bsm_size = 0;
1035 if (idx != (SEQ_TO_SN(sc) & 0xff)) { 234 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
1036 IWL_ERR(priv, 235 BIT(IEEE80211_BAND_5GHZ);
1037 "BUG_ON idx doesn't match seq control" 236 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
1038 " idx=%d, seq_idx=%d, seq=%d\n",
1039 idx, SEQ_TO_SN(sc),
1040 hdr->seq_ctrl);
1041 return -1;
1042 }
1043 237
1044 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", 238 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
1045 i, idx, SEQ_TO_SN(sc)); 239 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
240 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
241 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
1046 242
1047 sh = idx - start; 243 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
1048 if (sh > 64) { 244 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
1049 sh = (start - idx) + 0xff;
1050 bitmap = bitmap << sh;
1051 sh = 0;
1052 start = idx;
1053 } else if (sh < -64)
1054 sh = 0xff - (start - idx);
1055 else if (sh < 0) {
1056 sh = start - idx;
1057 start = idx;
1058 bitmap = bitmap << sh;
1059 sh = 0;
1060 }
1061 bitmap |= 1ULL << sh;
1062 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
1063 start, (unsigned long long)bitmap);
1064 }
1065 245
1066 agg->bitmap = bitmap; 246 /* Set initial sensitivity parameters */
1067 agg->start_idx = start; 247 /* Set initial calibration set */
1068 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", 248 priv->hw_params.sens = &iwl5150_sensitivity;
1069 agg->frame_count, agg->start_idx, 249 priv->hw_params.calib_init_cfg =
1070 (unsigned long long)agg->bitmap); 250 BIT(IWL_CALIB_DC) |
251 BIT(IWL_CALIB_LO) |
252 BIT(IWL_CALIB_TX_IQ) |
253 BIT(IWL_CALIB_BASE_BAND);
1071 254
1072 if (bitmap)
1073 agg->wait_for_ba = 1;
1074 }
1075 return 0; 255 return 0;
1076} 256}
1077 257
1078static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1079 struct iwl_rx_mem_buffer *rxb)
1080{
1081 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1082 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1083 int txq_id = SEQ_TO_QUEUE(sequence);
1084 int index = SEQ_TO_INDEX(sequence);
1085 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1086 struct ieee80211_tx_info *info;
1087 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1088 u32 status = le16_to_cpu(tx_resp->status.status);
1089 int tid;
1090 int sta_id;
1091 int freed;
1092
1093 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
1094 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
1095 "is out of range [0-%d] %d %d\n", txq_id,
1096 index, txq->q.n_bd, txq->q.write_ptr,
1097 txq->q.read_ptr);
1098 return;
1099 }
1100
1101 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
1102 memset(&info->status, 0, sizeof(info->status));
1103
1104 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
1105 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
1106
1107 if (txq->sched_retry) {
1108 const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp);
1109 struct iwl_ht_agg *agg = NULL;
1110
1111 agg = &priv->stations[sta_id].tid[tid].agg;
1112
1113 iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
1114
1115 /* check if BAR is needed */
1116 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
1117 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1118
1119 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
1120 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
1121 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
1122 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
1123 scd_ssn , index, txq_id, txq->swq_id);
1124
1125 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1126 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1127
1128 if (priv->mac80211_registered &&
1129 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1130 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
1131 if (agg->state == IWL_AGG_OFF)
1132 iwl_wake_queue(priv, txq_id);
1133 else
1134 iwl_wake_queue(priv, txq->swq_id);
1135 }
1136 }
1137 } else {
1138 BUG_ON(txq_id != txq->swq_id);
1139
1140 info->status.rates[0].count = tx_resp->failure_frame + 1;
1141 info->flags |= iwl_tx_status_to_mac80211(status);
1142 iwl_hwrate_to_tx_control(priv,
1143 le32_to_cpu(tx_resp->rate_n_flags),
1144 info);
1145
1146 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
1147 "0x%x retries %d\n",
1148 txq_id,
1149 iwl_get_tx_fail_reason(status), status,
1150 le32_to_cpu(tx_resp->rate_n_flags),
1151 tx_resp->failure_frame);
1152
1153 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1154 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1155
1156 if (priv->mac80211_registered &&
1157 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1158 iwl_wake_queue(priv, txq_id);
1159 }
1160
1161 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1162
1163 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1164 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
1165}
1166
1167/* Currently 5000 is the superset of everything */
1168u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
1169{
1170 return len;
1171}
1172
1173void iwl5000_setup_deferred_work(struct iwl_priv *priv)
1174{
1175 /* in 5000 the tx power calibration is done in uCode */
1176 priv->disable_tx_power_cal = 1;
1177}
1178
1179void iwl5000_rx_handler_setup(struct iwl_priv *priv)
1180{
1181 /* init calibration handlers */
1182 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
1183 iwl5000_rx_calib_result;
1184 priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
1185 iwl5000_rx_calib_complete;
1186 priv->rx_handlers[REPLY_TX] = iwl5000_rx_reply_tx;
1187}
1188
1189
1190int iwl5000_hw_valid_rtc_data_addr(u32 addr)
1191{
1192 return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
1193 (addr < IWL50_RTC_DATA_UPPER_BOUND);
1194}
1195
1196static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
1197{
1198 int ret = 0;
1199 struct iwl5000_rxon_assoc_cmd rxon_assoc;
1200 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
1201 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
1202
1203 if ((rxon1->flags == rxon2->flags) &&
1204 (rxon1->filter_flags == rxon2->filter_flags) &&
1205 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1206 (rxon1->ofdm_ht_single_stream_basic_rates ==
1207 rxon2->ofdm_ht_single_stream_basic_rates) &&
1208 (rxon1->ofdm_ht_dual_stream_basic_rates ==
1209 rxon2->ofdm_ht_dual_stream_basic_rates) &&
1210 (rxon1->ofdm_ht_triple_stream_basic_rates ==
1211 rxon2->ofdm_ht_triple_stream_basic_rates) &&
1212 (rxon1->acquisition_data == rxon2->acquisition_data) &&
1213 (rxon1->rx_chain == rxon2->rx_chain) &&
1214 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1215 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
1216 return 0;
1217 }
1218
1219 rxon_assoc.flags = priv->staging_rxon.flags;
1220 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1221 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1222 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1223 rxon_assoc.reserved1 = 0;
1224 rxon_assoc.reserved2 = 0;
1225 rxon_assoc.reserved3 = 0;
1226 rxon_assoc.ofdm_ht_single_stream_basic_rates =
1227 priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
1228 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1229 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
1230 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
1231 rxon_assoc.ofdm_ht_triple_stream_basic_rates =
1232 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
1233 rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
1234
1235 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
1236 sizeof(rxon_assoc), &rxon_assoc, NULL);
1237 if (ret)
1238 return ret;
1239
1240 return ret;
1241}
1242int iwl5000_send_tx_power(struct iwl_priv *priv)
1243{
1244 struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
1245 u8 tx_ant_cfg_cmd;
1246
1247 /* half dBm need to multiply */
1248 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
1249
1250 if (priv->tx_power_lmt_in_half_dbm &&
1251 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
1252 /*
1253 * For the newer devices which using enhanced/extend tx power
1254 * table in EEPROM, the format is in half dBm. driver need to
1255 * convert to dBm format before report to mac80211.
1256 * By doing so, there is a possibility of 1/2 dBm resolution
1257 * lost. driver will perform "round-up" operation before
1258 * reporting, but it will cause 1/2 dBm tx power over the
1259 * regulatory limit. Perform the checking here, if the
1260 * "tx_power_user_lmt" is higher than EEPROM value (in
1261 * half-dBm format), lower the tx power based on EEPROM
1262 */
1263 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
1264 }
1265 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
1266 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
1267
1268 if (IWL_UCODE_API(priv->ucode_ver) == 1)
1269 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
1270 else
1271 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
1272
1273 return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
1274 sizeof(tx_power_cmd), &tx_power_cmd,
1275 NULL);
1276}
1277
1278void iwl5000_temperature(struct iwl_priv *priv)
1279{
1280 /* store temperature from statistics (in Celsius) */
1281 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
1282 iwl_tt_handler(priv);
1283}
1284
1285static void iwl5150_temperature(struct iwl_priv *priv) 258static void iwl5150_temperature(struct iwl_priv *priv)
1286{ 259{
1287 u32 vt = 0; 260 u32 vt = 0;
@@ -1294,100 +267,6 @@ static void iwl5150_temperature(struct iwl_priv *priv)
1294 iwl_tt_handler(priv); 267 iwl_tt_handler(priv);
1295} 268}
1296 269
1297/* Calc max signal level (dBm) among 3 possible receivers */
1298int iwl5000_calc_rssi(struct iwl_priv *priv,
1299 struct iwl_rx_phy_res *rx_resp)
1300{
1301 /* data from PHY/DSP regarding signal strength, etc.,
1302 * contents are always there, not configurable by host
1303 */
1304 struct iwl5000_non_cfg_phy *ncphy =
1305 (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
1306 u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
1307 u8 agc;
1308
1309 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
1310 agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
1311
1312 /* Find max rssi among 3 possible receivers.
1313 * These values are measured by the digital signal processor (DSP).
1314 * They should stay fairly constant even as the signal strength varies,
1315 * if the radio's automatic gain control (AGC) is working right.
1316 * AGC value (see below) will provide the "interesting" info.
1317 */
1318 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
1319 rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
1320 rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
1321 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
1322 rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
1323
1324 max_rssi = max_t(u32, rssi_a, rssi_b);
1325 max_rssi = max_t(u32, max_rssi, rssi_c);
1326
1327 IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
1328 rssi_a, rssi_b, rssi_c, max_rssi, agc);
1329
1330 /* dBm = max_rssi dB - agc dB - constant.
1331 * Higher AGC (higher radio gain) means lower signal. */
1332 return max_rssi - agc - IWL49_RSSI_OFFSET;
1333}
1334
1335static int iwl5000_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
1336{
1337 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
1338 .valid = cpu_to_le32(valid_tx_ant),
1339 };
1340
1341 if (IWL_UCODE_API(priv->ucode_ver) > 1) {
1342 IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
1343 return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
1344 sizeof(struct iwl_tx_ant_config_cmd),
1345 &tx_ant_cmd);
1346 } else {
1347 IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
1348 return -EOPNOTSUPP;
1349 }
1350}
1351
1352
1353#define IWL5000_UCODE_GET(item) \
1354static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
1355 u32 api_ver) \
1356{ \
1357 if (api_ver <= 2) \
1358 return le32_to_cpu(ucode->u.v1.item); \
1359 return le32_to_cpu(ucode->u.v2.item); \
1360}
1361
1362static u32 iwl5000_ucode_get_header_size(u32 api_ver)
1363{
1364 if (api_ver <= 2)
1365 return UCODE_HEADER_SIZE(1);
1366 return UCODE_HEADER_SIZE(2);
1367}
1368
1369static u32 iwl5000_ucode_get_build(const struct iwl_ucode_header *ucode,
1370 u32 api_ver)
1371{
1372 if (api_ver <= 2)
1373 return 0;
1374 return le32_to_cpu(ucode->u.v2.build);
1375}
1376
1377static u8 *iwl5000_ucode_get_data(const struct iwl_ucode_header *ucode,
1378 u32 api_ver)
1379{
1380 if (api_ver <= 2)
1381 return (u8 *) ucode->u.v1.data;
1382 return (u8 *) ucode->u.v2.data;
1383}
1384
1385IWL5000_UCODE_GET(inst_size);
1386IWL5000_UCODE_GET(data_size);
1387IWL5000_UCODE_GET(init_size);
1388IWL5000_UCODE_GET(init_data_size);
1389IWL5000_UCODE_GET(boot_size);
1390
1391static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) 270static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1392{ 271{
1393 struct iwl5000_channel_switch_cmd cmd; 272 struct iwl5000_channel_switch_cmd cmd;
@@ -1420,54 +299,27 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1420 return iwl_send_cmd_sync(priv, &hcmd); 299 return iwl_send_cmd_sync(priv, &hcmd);
1421} 300}
1422 301
1423struct iwl_hcmd_ops iwl5000_hcmd = { 302static struct iwl_lib_ops iwl5000_lib = {
1424 .rxon_assoc = iwl5000_send_rxon_assoc,
1425 .commit_rxon = iwl_commit_rxon,
1426 .set_rxon_chain = iwl_set_rxon_chain,
1427 .set_tx_ant = iwl5000_send_tx_ant_config,
1428};
1429
1430struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1431 .get_hcmd_size = iwl5000_get_hcmd_size,
1432 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
1433 .gain_computation = iwl5000_gain_computation,
1434 .chain_noise_reset = iwl5000_chain_noise_reset,
1435 .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
1436 .calc_rssi = iwl5000_calc_rssi,
1437};
1438
1439struct iwl_ucode_ops iwl5000_ucode = {
1440 .get_header_size = iwl5000_ucode_get_header_size,
1441 .get_build = iwl5000_ucode_get_build,
1442 .get_inst_size = iwl5000_ucode_get_inst_size,
1443 .get_data_size = iwl5000_ucode_get_data_size,
1444 .get_init_size = iwl5000_ucode_get_init_size,
1445 .get_init_data_size = iwl5000_ucode_get_init_data_size,
1446 .get_boot_size = iwl5000_ucode_get_boot_size,
1447 .get_data = iwl5000_ucode_get_data,
1448};
1449
1450struct iwl_lib_ops iwl5000_lib = {
1451 .set_hw_params = iwl5000_hw_set_hw_params, 303 .set_hw_params = iwl5000_hw_set_hw_params,
1452 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 304 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
1453 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 305 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
1454 .txq_set_sched = iwl5000_txq_set_sched, 306 .txq_set_sched = iwlagn_txq_set_sched,
1455 .txq_agg_enable = iwl5000_txq_agg_enable, 307 .txq_agg_enable = iwlagn_txq_agg_enable,
1456 .txq_agg_disable = iwl5000_txq_agg_disable, 308 .txq_agg_disable = iwlagn_txq_agg_disable,
1457 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 309 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
1458 .txq_free_tfd = iwl_hw_txq_free_tfd, 310 .txq_free_tfd = iwl_hw_txq_free_tfd,
1459 .txq_init = iwl_hw_tx_queue_init, 311 .txq_init = iwl_hw_tx_queue_init,
1460 .rx_handler_setup = iwl5000_rx_handler_setup, 312 .rx_handler_setup = iwlagn_rx_handler_setup,
1461 .setup_deferred_work = iwl5000_setup_deferred_work, 313 .setup_deferred_work = iwlagn_setup_deferred_work,
1462 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 314 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
1463 .dump_nic_event_log = iwl_dump_nic_event_log, 315 .dump_nic_event_log = iwl_dump_nic_event_log,
1464 .dump_nic_error_log = iwl_dump_nic_error_log, 316 .dump_nic_error_log = iwl_dump_nic_error_log,
1465 .dump_csr = iwl_dump_csr, 317 .dump_csr = iwl_dump_csr,
1466 .dump_fh = iwl_dump_fh, 318 .dump_fh = iwl_dump_fh,
1467 .load_ucode = iwl5000_load_ucode, 319 .load_ucode = iwlagn_load_ucode,
1468 .init_alive_start = iwl5000_init_alive_start, 320 .init_alive_start = iwlagn_init_alive_start,
1469 .alive_notify = iwl5000_alive_notify, 321 .alive_notify = iwlagn_alive_notify,
1470 .send_tx_power = iwl5000_send_tx_power, 322 .send_tx_power = iwlagn_send_tx_power,
1471 .update_chain_flags = iwl_update_chain_flags, 323 .update_chain_flags = iwl_update_chain_flags,
1472 .set_channel_switch = iwl5000_hw_channel_switch, 324 .set_channel_switch = iwl5000_hw_channel_switch,
1473 .apm_ops = { 325 .apm_ops = {
@@ -1478,50 +330,58 @@ struct iwl_lib_ops iwl5000_lib = {
1478 }, 330 },
1479 .eeprom_ops = { 331 .eeprom_ops = {
1480 .regulatory_bands = { 332 .regulatory_bands = {
1481 EEPROM_5000_REG_BAND_1_CHANNELS, 333 EEPROM_REG_BAND_1_CHANNELS,
1482 EEPROM_5000_REG_BAND_2_CHANNELS, 334 EEPROM_REG_BAND_2_CHANNELS,
1483 EEPROM_5000_REG_BAND_3_CHANNELS, 335 EEPROM_REG_BAND_3_CHANNELS,
1484 EEPROM_5000_REG_BAND_4_CHANNELS, 336 EEPROM_REG_BAND_4_CHANNELS,
1485 EEPROM_5000_REG_BAND_5_CHANNELS, 337 EEPROM_REG_BAND_5_CHANNELS,
1486 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 338 EEPROM_REG_BAND_24_HT40_CHANNELS,
1487 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 339 EEPROM_REG_BAND_52_HT40_CHANNELS
1488 }, 340 },
1489 .verify_signature = iwlcore_eeprom_verify_signature, 341 .verify_signature = iwlcore_eeprom_verify_signature,
1490 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 342 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
1491 .release_semaphore = iwlcore_eeprom_release_semaphore, 343 .release_semaphore = iwlcore_eeprom_release_semaphore,
1492 .calib_version = iwl5000_eeprom_calib_version, 344 .calib_version = iwlagn_eeprom_calib_version,
1493 .query_addr = iwl5000_eeprom_query_addr, 345 .query_addr = iwlagn_eeprom_query_addr,
1494 }, 346 },
1495 .post_associate = iwl_post_associate, 347 .post_associate = iwl_post_associate,
1496 .isr = iwl_isr_ict, 348 .isr = iwl_isr_ict,
1497 .config_ap = iwl_config_ap, 349 .config_ap = iwl_config_ap,
1498 .temp_ops = { 350 .temp_ops = {
1499 .temperature = iwl5000_temperature, 351 .temperature = iwlagn_temperature,
1500 .set_ct_kill = iwl5000_set_ct_threshold, 352 .set_ct_kill = iwl5000_set_ct_threshold,
1501 }, 353 },
1502 .add_bcast_station = iwl_add_bcast_station, 354 .manage_ibss_station = iwlagn_manage_ibss_station,
355 .debugfs_ops = {
356 .rx_stats_read = iwl_ucode_rx_stats_read,
357 .tx_stats_read = iwl_ucode_tx_stats_read,
358 .general_stats_read = iwl_ucode_general_stats_read,
359 },
360 .recover_from_tx_stall = iwl_bg_monitor_recover,
361 .check_plcp_health = iwl_good_plcp_health,
362 .check_ack_health = iwl_good_ack_health,
1503}; 363};
1504 364
1505static struct iwl_lib_ops iwl5150_lib = { 365static struct iwl_lib_ops iwl5150_lib = {
1506 .set_hw_params = iwl5000_hw_set_hw_params, 366 .set_hw_params = iwl5150_hw_set_hw_params,
1507 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 367 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
1508 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 368 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
1509 .txq_set_sched = iwl5000_txq_set_sched, 369 .txq_set_sched = iwlagn_txq_set_sched,
1510 .txq_agg_enable = iwl5000_txq_agg_enable, 370 .txq_agg_enable = iwlagn_txq_agg_enable,
1511 .txq_agg_disable = iwl5000_txq_agg_disable, 371 .txq_agg_disable = iwlagn_txq_agg_disable,
1512 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 372 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
1513 .txq_free_tfd = iwl_hw_txq_free_tfd, 373 .txq_free_tfd = iwl_hw_txq_free_tfd,
1514 .txq_init = iwl_hw_tx_queue_init, 374 .txq_init = iwl_hw_tx_queue_init,
1515 .rx_handler_setup = iwl5000_rx_handler_setup, 375 .rx_handler_setup = iwlagn_rx_handler_setup,
1516 .setup_deferred_work = iwl5000_setup_deferred_work, 376 .setup_deferred_work = iwlagn_setup_deferred_work,
1517 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 377 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
1518 .dump_nic_event_log = iwl_dump_nic_event_log, 378 .dump_nic_event_log = iwl_dump_nic_event_log,
1519 .dump_nic_error_log = iwl_dump_nic_error_log, 379 .dump_nic_error_log = iwl_dump_nic_error_log,
1520 .dump_csr = iwl_dump_csr, 380 .dump_csr = iwl_dump_csr,
1521 .load_ucode = iwl5000_load_ucode, 381 .load_ucode = iwlagn_load_ucode,
1522 .init_alive_start = iwl5000_init_alive_start, 382 .init_alive_start = iwlagn_init_alive_start,
1523 .alive_notify = iwl5000_alive_notify, 383 .alive_notify = iwlagn_alive_notify,
1524 .send_tx_power = iwl5000_send_tx_power, 384 .send_tx_power = iwlagn_send_tx_power,
1525 .update_chain_flags = iwl_update_chain_flags, 385 .update_chain_flags = iwl_update_chain_flags,
1526 .set_channel_switch = iwl5000_hw_channel_switch, 386 .set_channel_switch = iwl5000_hw_channel_switch,
1527 .apm_ops = { 387 .apm_ops = {
@@ -1532,19 +392,19 @@ static struct iwl_lib_ops iwl5150_lib = {
1532 }, 392 },
1533 .eeprom_ops = { 393 .eeprom_ops = {
1534 .regulatory_bands = { 394 .regulatory_bands = {
1535 EEPROM_5000_REG_BAND_1_CHANNELS, 395 EEPROM_REG_BAND_1_CHANNELS,
1536 EEPROM_5000_REG_BAND_2_CHANNELS, 396 EEPROM_REG_BAND_2_CHANNELS,
1537 EEPROM_5000_REG_BAND_3_CHANNELS, 397 EEPROM_REG_BAND_3_CHANNELS,
1538 EEPROM_5000_REG_BAND_4_CHANNELS, 398 EEPROM_REG_BAND_4_CHANNELS,
1539 EEPROM_5000_REG_BAND_5_CHANNELS, 399 EEPROM_REG_BAND_5_CHANNELS,
1540 EEPROM_5000_REG_BAND_24_HT40_CHANNELS, 400 EEPROM_REG_BAND_24_HT40_CHANNELS,
1541 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 401 EEPROM_REG_BAND_52_HT40_CHANNELS
1542 }, 402 },
1543 .verify_signature = iwlcore_eeprom_verify_signature, 403 .verify_signature = iwlcore_eeprom_verify_signature,
1544 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 404 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
1545 .release_semaphore = iwlcore_eeprom_release_semaphore, 405 .release_semaphore = iwlcore_eeprom_release_semaphore,
1546 .calib_version = iwl5000_eeprom_calib_version, 406 .calib_version = iwlagn_eeprom_calib_version,
1547 .query_addr = iwl5000_eeprom_query_addr, 407 .query_addr = iwlagn_eeprom_query_addr,
1548 }, 408 },
1549 .post_associate = iwl_post_associate, 409 .post_associate = iwl_post_associate,
1550 .isr = iwl_isr_ict, 410 .isr = iwl_isr_ict,
@@ -1553,45 +413,44 @@ static struct iwl_lib_ops iwl5150_lib = {
1553 .temperature = iwl5150_temperature, 413 .temperature = iwl5150_temperature,
1554 .set_ct_kill = iwl5150_set_ct_threshold, 414 .set_ct_kill = iwl5150_set_ct_threshold,
1555 }, 415 },
1556 .add_bcast_station = iwl_add_bcast_station, 416 .manage_ibss_station = iwlagn_manage_ibss_station,
417 .debugfs_ops = {
418 .rx_stats_read = iwl_ucode_rx_stats_read,
419 .tx_stats_read = iwl_ucode_tx_stats_read,
420 .general_stats_read = iwl_ucode_general_stats_read,
421 },
422 .recover_from_tx_stall = iwl_bg_monitor_recover,
423 .check_plcp_health = iwl_good_plcp_health,
424 .check_ack_health = iwl_good_ack_health,
1557}; 425};
1558 426
1559static const struct iwl_ops iwl5000_ops = { 427static const struct iwl_ops iwl5000_ops = {
1560 .ucode = &iwl5000_ucode,
1561 .lib = &iwl5000_lib, 428 .lib = &iwl5000_lib,
1562 .hcmd = &iwl5000_hcmd, 429 .hcmd = &iwlagn_hcmd,
1563 .utils = &iwl5000_hcmd_utils, 430 .utils = &iwlagn_hcmd_utils,
1564 .led = &iwlagn_led_ops, 431 .led = &iwlagn_led_ops,
1565}; 432};
1566 433
1567static const struct iwl_ops iwl5150_ops = { 434static const struct iwl_ops iwl5150_ops = {
1568 .ucode = &iwl5000_ucode,
1569 .lib = &iwl5150_lib, 435 .lib = &iwl5150_lib,
1570 .hcmd = &iwl5000_hcmd, 436 .hcmd = &iwlagn_hcmd,
1571 .utils = &iwl5000_hcmd_utils, 437 .utils = &iwlagn_hcmd_utils,
1572 .led = &iwlagn_led_ops, 438 .led = &iwlagn_led_ops,
1573}; 439};
1574 440
1575struct iwl_mod_params iwl50_mod_params = {
1576 .amsdu_size_8K = 1,
1577 .restart_fw = 1,
1578 /* the rest are 0 by default */
1579};
1580
1581
1582struct iwl_cfg iwl5300_agn_cfg = { 441struct iwl_cfg iwl5300_agn_cfg = {
1583 .name = "5300AGN", 442 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
1584 .fw_name_pre = IWL5000_FW_PRE, 443 .fw_name_pre = IWL5000_FW_PRE,
1585 .ucode_api_max = IWL5000_UCODE_API_MAX, 444 .ucode_api_max = IWL5000_UCODE_API_MAX,
1586 .ucode_api_min = IWL5000_UCODE_API_MIN, 445 .ucode_api_min = IWL5000_UCODE_API_MIN,
1587 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 446 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1588 .ops = &iwl5000_ops, 447 .ops = &iwl5000_ops,
1589 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 448 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1590 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 449 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1591 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 450 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1592 .num_of_queues = IWL50_NUM_QUEUES, 451 .num_of_queues = IWLAGN_NUM_QUEUES,
1593 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 452 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1594 .mod_params = &iwl50_mod_params, 453 .mod_params = &iwlagn_mod_params,
1595 .valid_tx_ant = ANT_ABC, 454 .valid_tx_ant = ANT_ABC,
1596 .valid_rx_ant = ANT_ABC, 455 .valid_rx_ant = ANT_ABC,
1597 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 456 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1603,21 +462,26 @@ struct iwl_cfg iwl5300_agn_cfg = {
1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 462 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1604 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 463 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605 .chain_noise_scale = 1000, 464 .chain_noise_scale = 1000,
465 .monitor_recover_period = IWL_MONITORING_PERIOD,
466 .max_event_log_size = 512,
467 .ucode_tracing = true,
468 .sensitivity_calib_by_driver = true,
469 .chain_noise_calib_by_driver = true,
1606}; 470};
1607 471
1608struct iwl_cfg iwl5100_bgn_cfg = { 472struct iwl_cfg iwl5100_bgn_cfg = {
1609 .name = "5100BGN", 473 .name = "Intel(R) WiFi Link 5100 BGN",
1610 .fw_name_pre = IWL5000_FW_PRE, 474 .fw_name_pre = IWL5000_FW_PRE,
1611 .ucode_api_max = IWL5000_UCODE_API_MAX, 475 .ucode_api_max = IWL5000_UCODE_API_MAX,
1612 .ucode_api_min = IWL5000_UCODE_API_MIN, 476 .ucode_api_min = IWL5000_UCODE_API_MIN,
1613 .sku = IWL_SKU_G|IWL_SKU_N, 477 .sku = IWL_SKU_G|IWL_SKU_N,
1614 .ops = &iwl5000_ops, 478 .ops = &iwl5000_ops,
1615 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 479 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1616 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 480 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1617 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 481 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1618 .num_of_queues = IWL50_NUM_QUEUES, 482 .num_of_queues = IWLAGN_NUM_QUEUES,
1619 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 483 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1620 .mod_params = &iwl50_mod_params, 484 .mod_params = &iwlagn_mod_params,
1621 .valid_tx_ant = ANT_B, 485 .valid_tx_ant = ANT_B,
1622 .valid_rx_ant = ANT_AB, 486 .valid_rx_ant = ANT_AB,
1623 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 487 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1629,21 +493,26 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 493 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1630 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 494 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1631 .chain_noise_scale = 1000, 495 .chain_noise_scale = 1000,
496 .monitor_recover_period = IWL_MONITORING_PERIOD,
497 .max_event_log_size = 512,
498 .ucode_tracing = true,
499 .sensitivity_calib_by_driver = true,
500 .chain_noise_calib_by_driver = true,
1632}; 501};
1633 502
1634struct iwl_cfg iwl5100_abg_cfg = { 503struct iwl_cfg iwl5100_abg_cfg = {
1635 .name = "5100ABG", 504 .name = "Intel(R) WiFi Link 5100 ABG",
1636 .fw_name_pre = IWL5000_FW_PRE, 505 .fw_name_pre = IWL5000_FW_PRE,
1637 .ucode_api_max = IWL5000_UCODE_API_MAX, 506 .ucode_api_max = IWL5000_UCODE_API_MAX,
1638 .ucode_api_min = IWL5000_UCODE_API_MIN, 507 .ucode_api_min = IWL5000_UCODE_API_MIN,
1639 .sku = IWL_SKU_A|IWL_SKU_G, 508 .sku = IWL_SKU_A|IWL_SKU_G,
1640 .ops = &iwl5000_ops, 509 .ops = &iwl5000_ops,
1641 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 510 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1642 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 511 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1643 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 512 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1644 .num_of_queues = IWL50_NUM_QUEUES, 513 .num_of_queues = IWLAGN_NUM_QUEUES,
1645 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 514 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1646 .mod_params = &iwl50_mod_params, 515 .mod_params = &iwlagn_mod_params,
1647 .valid_tx_ant = ANT_B, 516 .valid_tx_ant = ANT_B,
1648 .valid_rx_ant = ANT_AB, 517 .valid_rx_ant = ANT_AB,
1649 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 518 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1653,21 +522,26 @@ struct iwl_cfg iwl5100_abg_cfg = {
1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 522 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 523 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1655 .chain_noise_scale = 1000, 524 .chain_noise_scale = 1000,
525 .monitor_recover_period = IWL_MONITORING_PERIOD,
526 .max_event_log_size = 512,
527 .ucode_tracing = true,
528 .sensitivity_calib_by_driver = true,
529 .chain_noise_calib_by_driver = true,
1656}; 530};
1657 531
1658struct iwl_cfg iwl5100_agn_cfg = { 532struct iwl_cfg iwl5100_agn_cfg = {
1659 .name = "5100AGN", 533 .name = "Intel(R) WiFi Link 5100 AGN",
1660 .fw_name_pre = IWL5000_FW_PRE, 534 .fw_name_pre = IWL5000_FW_PRE,
1661 .ucode_api_max = IWL5000_UCODE_API_MAX, 535 .ucode_api_max = IWL5000_UCODE_API_MAX,
1662 .ucode_api_min = IWL5000_UCODE_API_MIN, 536 .ucode_api_min = IWL5000_UCODE_API_MIN,
1663 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 537 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1664 .ops = &iwl5000_ops, 538 .ops = &iwl5000_ops,
1665 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 539 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1666 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 540 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
1667 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 541 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
1668 .num_of_queues = IWL50_NUM_QUEUES, 542 .num_of_queues = IWLAGN_NUM_QUEUES,
1669 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 543 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1670 .mod_params = &iwl50_mod_params, 544 .mod_params = &iwlagn_mod_params,
1671 .valid_tx_ant = ANT_B, 545 .valid_tx_ant = ANT_B,
1672 .valid_rx_ant = ANT_AB, 546 .valid_rx_ant = ANT_AB,
1673 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 547 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1679,21 +553,26 @@ struct iwl_cfg iwl5100_agn_cfg = {
1679 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 553 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1680 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 554 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1681 .chain_noise_scale = 1000, 555 .chain_noise_scale = 1000,
556 .monitor_recover_period = IWL_MONITORING_PERIOD,
557 .max_event_log_size = 512,
558 .ucode_tracing = true,
559 .sensitivity_calib_by_driver = true,
560 .chain_noise_calib_by_driver = true,
1682}; 561};
1683 562
1684struct iwl_cfg iwl5350_agn_cfg = { 563struct iwl_cfg iwl5350_agn_cfg = {
1685 .name = "5350AGN", 564 .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
1686 .fw_name_pre = IWL5000_FW_PRE, 565 .fw_name_pre = IWL5000_FW_PRE,
1687 .ucode_api_max = IWL5000_UCODE_API_MAX, 566 .ucode_api_max = IWL5000_UCODE_API_MAX,
1688 .ucode_api_min = IWL5000_UCODE_API_MIN, 567 .ucode_api_min = IWL5000_UCODE_API_MIN,
1689 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 568 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1690 .ops = &iwl5000_ops, 569 .ops = &iwl5000_ops,
1691 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 570 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1692 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 571 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1693 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 572 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1694 .num_of_queues = IWL50_NUM_QUEUES, 573 .num_of_queues = IWLAGN_NUM_QUEUES,
1695 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 574 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1696 .mod_params = &iwl50_mod_params, 575 .mod_params = &iwlagn_mod_params,
1697 .valid_tx_ant = ANT_ABC, 576 .valid_tx_ant = ANT_ABC,
1698 .valid_rx_ant = ANT_ABC, 577 .valid_rx_ant = ANT_ABC,
1699 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 578 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1705,21 +584,26 @@ struct iwl_cfg iwl5350_agn_cfg = {
1705 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 584 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1706 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 585 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1707 .chain_noise_scale = 1000, 586 .chain_noise_scale = 1000,
587 .monitor_recover_period = IWL_MONITORING_PERIOD,
588 .max_event_log_size = 512,
589 .ucode_tracing = true,
590 .sensitivity_calib_by_driver = true,
591 .chain_noise_calib_by_driver = true,
1708}; 592};
1709 593
1710struct iwl_cfg iwl5150_agn_cfg = { 594struct iwl_cfg iwl5150_agn_cfg = {
1711 .name = "5150AGN", 595 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
1712 .fw_name_pre = IWL5150_FW_PRE, 596 .fw_name_pre = IWL5150_FW_PRE,
1713 .ucode_api_max = IWL5150_UCODE_API_MAX, 597 .ucode_api_max = IWL5150_UCODE_API_MAX,
1714 .ucode_api_min = IWL5150_UCODE_API_MIN, 598 .ucode_api_min = IWL5150_UCODE_API_MIN,
1715 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 599 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
1716 .ops = &iwl5150_ops, 600 .ops = &iwl5150_ops,
1717 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 601 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1718 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 602 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1719 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 603 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1720 .num_of_queues = IWL50_NUM_QUEUES, 604 .num_of_queues = IWLAGN_NUM_QUEUES,
1721 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 605 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1722 .mod_params = &iwl50_mod_params, 606 .mod_params = &iwlagn_mod_params,
1723 .valid_tx_ant = ANT_A, 607 .valid_tx_ant = ANT_A,
1724 .valid_rx_ant = ANT_AB, 608 .valid_rx_ant = ANT_AB,
1725 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 609 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1731,21 +615,26 @@ struct iwl_cfg iwl5150_agn_cfg = {
1731 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 615 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1732 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 616 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1733 .chain_noise_scale = 1000, 617 .chain_noise_scale = 1000,
618 .monitor_recover_period = IWL_MONITORING_PERIOD,
619 .max_event_log_size = 512,
620 .ucode_tracing = true,
621 .sensitivity_calib_by_driver = true,
622 .chain_noise_calib_by_driver = true,
1734}; 623};
1735 624
1736struct iwl_cfg iwl5150_abg_cfg = { 625struct iwl_cfg iwl5150_abg_cfg = {
1737 .name = "5150ABG", 626 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
1738 .fw_name_pre = IWL5150_FW_PRE, 627 .fw_name_pre = IWL5150_FW_PRE,
1739 .ucode_api_max = IWL5150_UCODE_API_MAX, 628 .ucode_api_max = IWL5150_UCODE_API_MAX,
1740 .ucode_api_min = IWL5150_UCODE_API_MIN, 629 .ucode_api_min = IWL5150_UCODE_API_MIN,
1741 .sku = IWL_SKU_A|IWL_SKU_G, 630 .sku = IWL_SKU_A|IWL_SKU_G,
1742 .ops = &iwl5150_ops, 631 .ops = &iwl5150_ops,
1743 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 632 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
1744 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 633 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
1745 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 634 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
1746 .num_of_queues = IWL50_NUM_QUEUES, 635 .num_of_queues = IWLAGN_NUM_QUEUES,
1747 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 636 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
1748 .mod_params = &iwl50_mod_params, 637 .mod_params = &iwlagn_mod_params,
1749 .valid_tx_ant = ANT_A, 638 .valid_tx_ant = ANT_A,
1750 .valid_rx_ant = ANT_AB, 639 .valid_rx_ant = ANT_AB,
1751 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 640 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
@@ -1755,20 +644,12 @@ struct iwl_cfg iwl5150_abg_cfg = {
1755 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 644 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1756 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 645 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1757 .chain_noise_scale = 1000, 646 .chain_noise_scale = 1000,
647 .monitor_recover_period = IWL_MONITORING_PERIOD,
648 .max_event_log_size = 512,
649 .ucode_tracing = true,
650 .sensitivity_calib_by_driver = true,
651 .chain_noise_calib_by_driver = true,
1758}; 652};
1759 653
1760MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 654MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
1761MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); 655MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
1762
1763module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO);
1764MODULE_PARM_DESC(swcrypto50,
1765 "using software crypto engine (default 0 [hardware])\n");
1766module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO);
1767MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
1768module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO);
1769MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
1770module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K,
1771 int, S_IRUGO);
1772MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
1773module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO);
1774MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 92b3e64fc14d..9fbf54cd3e1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -42,18 +42,22 @@
42#include "iwl-core.h" 42#include "iwl-core.h"
43#include "iwl-io.h" 43#include "iwl-io.h"
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-agn.h"
45#include "iwl-helpers.h" 46#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 47#include "iwl-agn-hw.h"
47#include "iwl-6000-hw.h" 48#include "iwl-6000-hw.h"
48#include "iwl-agn-led.h" 49#include "iwl-agn-led.h"
50#include "iwl-agn-debugfs.h"
49 51
50/* Highest firmware API version supported */ 52/* Highest firmware API version supported */
51#define IWL6000_UCODE_API_MAX 4 53#define IWL6000_UCODE_API_MAX 4
52#define IWL6050_UCODE_API_MAX 4 54#define IWL6050_UCODE_API_MAX 4
55#define IWL6000G2_UCODE_API_MAX 4
53 56
54/* Lowest firmware API version supported */ 57/* Lowest firmware API version supported */
55#define IWL6000_UCODE_API_MIN 4 58#define IWL6000_UCODE_API_MIN 4
56#define IWL6050_UCODE_API_MIN 4 59#define IWL6050_UCODE_API_MIN 4
60#define IWL6000G2_UCODE_API_MIN 4
57 61
58#define IWL6000_FW_PRE "iwlwifi-6000-" 62#define IWL6000_FW_PRE "iwlwifi-6000-"
59#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" 63#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -63,6 +67,11 @@
63#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" 67#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
64#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) 68#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
65 69
70#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-"
71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
73
74
66static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 75static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
67{ 76{
68 /* want Celsius */ 77 /* want Celsius */
@@ -136,7 +145,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
136static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) 145static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
137{ 146{
138 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && 147 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
139 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) 148 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
140 priv->cfg->num_of_queues = 149 priv->cfg->num_of_queues =
141 priv->cfg->mod_params->num_of_queues; 150 priv->cfg->mod_params->num_of_queues;
142 151
@@ -144,7 +153,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
144 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; 153 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
145 priv->hw_params.scd_bc_tbls_size = 154 priv->hw_params.scd_bc_tbls_size =
146 priv->cfg->num_of_queues * 155 priv->cfg->num_of_queues *
147 sizeof(struct iwl5000_scd_bc_tbl); 156 sizeof(struct iwlagn_scd_bc_tbl);
148 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 157 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
149 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 158 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
150 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 159 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
@@ -168,24 +177,56 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
168 /* Set initial sensitivity parameters */ 177 /* Set initial sensitivity parameters */
169 /* Set initial calibration set */ 178 /* Set initial calibration set */
170 priv->hw_params.sens = &iwl6000_sensitivity; 179 priv->hw_params.sens = &iwl6000_sensitivity;
171 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 180 priv->hw_params.calib_init_cfg =
172 case CSR_HW_REV_TYPE_6x50: 181 BIT(IWL_CALIB_XTAL) |
173 priv->hw_params.calib_init_cfg = 182 BIT(IWL_CALIB_LO) |
174 BIT(IWL_CALIB_XTAL) | 183 BIT(IWL_CALIB_TX_IQ) |
175 BIT(IWL_CALIB_DC) | 184 BIT(IWL_CALIB_BASE_BAND);
176 BIT(IWL_CALIB_LO) | 185
177 BIT(IWL_CALIB_TX_IQ) | 186 return 0;
178 BIT(IWL_CALIB_BASE_BAND); 187}
179 188
180 break; 189static int iwl6050_hw_set_hw_params(struct iwl_priv *priv)
181 default: 190{
182 priv->hw_params.calib_init_cfg = 191 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
183 BIT(IWL_CALIB_XTAL) | 192 priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
184 BIT(IWL_CALIB_LO) | 193 priv->cfg->num_of_queues =
185 BIT(IWL_CALIB_TX_IQ) | 194 priv->cfg->mod_params->num_of_queues;
186 BIT(IWL_CALIB_BASE_BAND); 195
187 break; 196 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
188 } 197 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
198 priv->hw_params.scd_bc_tbls_size =
199 priv->cfg->num_of_queues *
200 sizeof(struct iwlagn_scd_bc_tbl);
201 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
202 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
203 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
204
205 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
206 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
207
208 priv->hw_params.max_bsm_size = 0;
209 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
210 BIT(IEEE80211_BAND_5GHZ);
211 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
212
213 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
214 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
215 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
216 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
217
218 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
219 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
220
221 /* Set initial sensitivity parameters */
222 /* Set initial calibration set */
223 priv->hw_params.sens = &iwl6000_sensitivity;
224 priv->hw_params.calib_init_cfg =
225 BIT(IWL_CALIB_XTAL) |
226 BIT(IWL_CALIB_DC) |
227 BIT(IWL_CALIB_LO) |
228 BIT(IWL_CALIB_TX_IQ) |
229 BIT(IWL_CALIB_BASE_BAND);
189 230
190 return 0; 231 return 0;
191} 232}
@@ -225,25 +266,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
225 266
226static struct iwl_lib_ops iwl6000_lib = { 267static struct iwl_lib_ops iwl6000_lib = {
227 .set_hw_params = iwl6000_hw_set_hw_params, 268 .set_hw_params = iwl6000_hw_set_hw_params,
228 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 269 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
229 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 270 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
230 .txq_set_sched = iwl5000_txq_set_sched, 271 .txq_set_sched = iwlagn_txq_set_sched,
231 .txq_agg_enable = iwl5000_txq_agg_enable, 272 .txq_agg_enable = iwlagn_txq_agg_enable,
232 .txq_agg_disable = iwl5000_txq_agg_disable, 273 .txq_agg_disable = iwlagn_txq_agg_disable,
233 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 274 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
234 .txq_free_tfd = iwl_hw_txq_free_tfd, 275 .txq_free_tfd = iwl_hw_txq_free_tfd,
235 .txq_init = iwl_hw_tx_queue_init, 276 .txq_init = iwl_hw_tx_queue_init,
236 .rx_handler_setup = iwl5000_rx_handler_setup, 277 .rx_handler_setup = iwlagn_rx_handler_setup,
237 .setup_deferred_work = iwl5000_setup_deferred_work, 278 .setup_deferred_work = iwlagn_setup_deferred_work,
238 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 279 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
239 .load_ucode = iwl5000_load_ucode, 280 .load_ucode = iwlagn_load_ucode,
240 .dump_nic_event_log = iwl_dump_nic_event_log, 281 .dump_nic_event_log = iwl_dump_nic_event_log,
241 .dump_nic_error_log = iwl_dump_nic_error_log, 282 .dump_nic_error_log = iwl_dump_nic_error_log,
242 .dump_csr = iwl_dump_csr, 283 .dump_csr = iwl_dump_csr,
243 .dump_fh = iwl_dump_fh, 284 .dump_fh = iwl_dump_fh,
244 .init_alive_start = iwl5000_init_alive_start, 285 .init_alive_start = iwlagn_init_alive_start,
245 .alive_notify = iwl5000_alive_notify, 286 .alive_notify = iwlagn_alive_notify,
246 .send_tx_power = iwl5000_send_tx_power, 287 .send_tx_power = iwlagn_send_tx_power,
247 .update_chain_flags = iwl_update_chain_flags, 288 .update_chain_flags = iwl_update_chain_flags,
248 .set_channel_switch = iwl6000_hw_channel_switch, 289 .set_channel_switch = iwl6000_hw_channel_switch,
249 .apm_ops = { 290 .apm_ops = {
@@ -254,60 +295,67 @@ static struct iwl_lib_ops iwl6000_lib = {
254 }, 295 },
255 .eeprom_ops = { 296 .eeprom_ops = {
256 .regulatory_bands = { 297 .regulatory_bands = {
257 EEPROM_5000_REG_BAND_1_CHANNELS, 298 EEPROM_REG_BAND_1_CHANNELS,
258 EEPROM_5000_REG_BAND_2_CHANNELS, 299 EEPROM_REG_BAND_2_CHANNELS,
259 EEPROM_5000_REG_BAND_3_CHANNELS, 300 EEPROM_REG_BAND_3_CHANNELS,
260 EEPROM_5000_REG_BAND_4_CHANNELS, 301 EEPROM_REG_BAND_4_CHANNELS,
261 EEPROM_5000_REG_BAND_5_CHANNELS, 302 EEPROM_REG_BAND_5_CHANNELS,
262 EEPROM_6000_REG_BAND_24_HT40_CHANNELS, 303 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
263 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 304 EEPROM_REG_BAND_52_HT40_CHANNELS
264 }, 305 },
265 .verify_signature = iwlcore_eeprom_verify_signature, 306 .verify_signature = iwlcore_eeprom_verify_signature,
266 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 307 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
267 .release_semaphore = iwlcore_eeprom_release_semaphore, 308 .release_semaphore = iwlcore_eeprom_release_semaphore,
268 .calib_version = iwl5000_eeprom_calib_version, 309 .calib_version = iwlagn_eeprom_calib_version,
269 .query_addr = iwl5000_eeprom_query_addr, 310 .query_addr = iwlagn_eeprom_query_addr,
270 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 311 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
271 }, 312 },
272 .post_associate = iwl_post_associate, 313 .post_associate = iwl_post_associate,
273 .isr = iwl_isr_ict, 314 .isr = iwl_isr_ict,
274 .config_ap = iwl_config_ap, 315 .config_ap = iwl_config_ap,
275 .temp_ops = { 316 .temp_ops = {
276 .temperature = iwl5000_temperature, 317 .temperature = iwlagn_temperature,
277 .set_ct_kill = iwl6000_set_ct_threshold, 318 .set_ct_kill = iwl6000_set_ct_threshold,
278 }, 319 },
279 .add_bcast_station = iwl_add_bcast_station, 320 .manage_ibss_station = iwlagn_manage_ibss_station,
321 .debugfs_ops = {
322 .rx_stats_read = iwl_ucode_rx_stats_read,
323 .tx_stats_read = iwl_ucode_tx_stats_read,
324 .general_stats_read = iwl_ucode_general_stats_read,
325 },
326 .recover_from_tx_stall = iwl_bg_monitor_recover,
327 .check_plcp_health = iwl_good_plcp_health,
328 .check_ack_health = iwl_good_ack_health,
280}; 329};
281 330
282static const struct iwl_ops iwl6000_ops = { 331static const struct iwl_ops iwl6000_ops = {
283 .ucode = &iwl5000_ucode,
284 .lib = &iwl6000_lib, 332 .lib = &iwl6000_lib,
285 .hcmd = &iwl5000_hcmd, 333 .hcmd = &iwlagn_hcmd,
286 .utils = &iwl5000_hcmd_utils, 334 .utils = &iwlagn_hcmd_utils,
287 .led = &iwlagn_led_ops, 335 .led = &iwlagn_led_ops,
288}; 336};
289 337
290static struct iwl_lib_ops iwl6050_lib = { 338static struct iwl_lib_ops iwl6050_lib = {
291 .set_hw_params = iwl6000_hw_set_hw_params, 339 .set_hw_params = iwl6050_hw_set_hw_params,
292 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 340 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
293 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 341 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
294 .txq_set_sched = iwl5000_txq_set_sched, 342 .txq_set_sched = iwlagn_txq_set_sched,
295 .txq_agg_enable = iwl5000_txq_agg_enable, 343 .txq_agg_enable = iwlagn_txq_agg_enable,
296 .txq_agg_disable = iwl5000_txq_agg_disable, 344 .txq_agg_disable = iwlagn_txq_agg_disable,
297 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 345 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
298 .txq_free_tfd = iwl_hw_txq_free_tfd, 346 .txq_free_tfd = iwl_hw_txq_free_tfd,
299 .txq_init = iwl_hw_tx_queue_init, 347 .txq_init = iwl_hw_tx_queue_init,
300 .rx_handler_setup = iwl5000_rx_handler_setup, 348 .rx_handler_setup = iwlagn_rx_handler_setup,
301 .setup_deferred_work = iwl5000_setup_deferred_work, 349 .setup_deferred_work = iwlagn_setup_deferred_work,
302 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 350 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
303 .load_ucode = iwl5000_load_ucode, 351 .load_ucode = iwlagn_load_ucode,
304 .dump_nic_event_log = iwl_dump_nic_event_log, 352 .dump_nic_event_log = iwl_dump_nic_event_log,
305 .dump_nic_error_log = iwl_dump_nic_error_log, 353 .dump_nic_error_log = iwl_dump_nic_error_log,
306 .dump_csr = iwl_dump_csr, 354 .dump_csr = iwl_dump_csr,
307 .dump_fh = iwl_dump_fh, 355 .dump_fh = iwl_dump_fh,
308 .init_alive_start = iwl5000_init_alive_start, 356 .init_alive_start = iwlagn_init_alive_start,
309 .alive_notify = iwl5000_alive_notify, 357 .alive_notify = iwlagn_alive_notify,
310 .send_tx_power = iwl5000_send_tx_power, 358 .send_tx_power = iwlagn_send_tx_power,
311 .update_chain_flags = iwl_update_chain_flags, 359 .update_chain_flags = iwl_update_chain_flags,
312 .set_channel_switch = iwl6000_hw_channel_switch, 360 .set_channel_switch = iwl6000_hw_channel_switch,
313 .apm_ops = { 361 .apm_ops = {
@@ -318,45 +366,90 @@ static struct iwl_lib_ops iwl6050_lib = {
318 }, 366 },
319 .eeprom_ops = { 367 .eeprom_ops = {
320 .regulatory_bands = { 368 .regulatory_bands = {
321 EEPROM_5000_REG_BAND_1_CHANNELS, 369 EEPROM_REG_BAND_1_CHANNELS,
322 EEPROM_5000_REG_BAND_2_CHANNELS, 370 EEPROM_REG_BAND_2_CHANNELS,
323 EEPROM_5000_REG_BAND_3_CHANNELS, 371 EEPROM_REG_BAND_3_CHANNELS,
324 EEPROM_5000_REG_BAND_4_CHANNELS, 372 EEPROM_REG_BAND_4_CHANNELS,
325 EEPROM_5000_REG_BAND_5_CHANNELS, 373 EEPROM_REG_BAND_5_CHANNELS,
326 EEPROM_6000_REG_BAND_24_HT40_CHANNELS, 374 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
327 EEPROM_5000_REG_BAND_52_HT40_CHANNELS 375 EEPROM_REG_BAND_52_HT40_CHANNELS
328 }, 376 },
329 .verify_signature = iwlcore_eeprom_verify_signature, 377 .verify_signature = iwlcore_eeprom_verify_signature,
330 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, 378 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
331 .release_semaphore = iwlcore_eeprom_release_semaphore, 379 .release_semaphore = iwlcore_eeprom_release_semaphore,
332 .calib_version = iwl5000_eeprom_calib_version, 380 .calib_version = iwlagn_eeprom_calib_version,
333 .query_addr = iwl5000_eeprom_query_addr, 381 .query_addr = iwlagn_eeprom_query_addr,
334 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 382 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
335 }, 383 },
336 .post_associate = iwl_post_associate, 384 .post_associate = iwl_post_associate,
337 .isr = iwl_isr_ict, 385 .isr = iwl_isr_ict,
338 .config_ap = iwl_config_ap, 386 .config_ap = iwl_config_ap,
339 .temp_ops = { 387 .temp_ops = {
340 .temperature = iwl5000_temperature, 388 .temperature = iwlagn_temperature,
341 .set_ct_kill = iwl6000_set_ct_threshold, 389 .set_ct_kill = iwl6000_set_ct_threshold,
342 .set_calib_version = iwl6050_set_calib_version, 390 .set_calib_version = iwl6050_set_calib_version,
343 }, 391 },
344 .add_bcast_station = iwl_add_bcast_station, 392 .manage_ibss_station = iwlagn_manage_ibss_station,
393 .debugfs_ops = {
394 .rx_stats_read = iwl_ucode_rx_stats_read,
395 .tx_stats_read = iwl_ucode_tx_stats_read,
396 .general_stats_read = iwl_ucode_general_stats_read,
397 },
398 .recover_from_tx_stall = iwl_bg_monitor_recover,
399 .check_plcp_health = iwl_good_plcp_health,
400 .check_ack_health = iwl_good_ack_health,
345}; 401};
346 402
347static const struct iwl_ops iwl6050_ops = { 403static const struct iwl_ops iwl6050_ops = {
348 .ucode = &iwl5000_ucode,
349 .lib = &iwl6050_lib, 404 .lib = &iwl6050_lib,
350 .hcmd = &iwl5000_hcmd, 405 .hcmd = &iwlagn_hcmd,
351 .utils = &iwl5000_hcmd_utils, 406 .utils = &iwlagn_hcmd_utils,
352 .led = &iwlagn_led_ops, 407 .led = &iwlagn_led_ops,
353}; 408};
354 409
410
411struct iwl_cfg iwl6000g2a_2agn_cfg = {
412 .name = "6000 Series 2x2 AGN Gen2a",
413 .fw_name_pre = IWL6000G2A_FW_PRE,
414 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
415 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
416 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
417 .ops = &iwl6000_ops,
418 .eeprom_size = OTP_LOW_IMAGE_SIZE,
419 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
420 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
421 .num_of_queues = IWLAGN_NUM_QUEUES,
422 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
423 .mod_params = &iwlagn_mod_params,
424 .valid_tx_ant = ANT_AB,
425 .valid_rx_ant = ANT_AB,
426 .pll_cfg_val = 0,
427 .set_l0s = true,
428 .use_bsm = false,
429 .pa_type = IWL_PA_SYSTEM,
430 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
431 .shadow_ram_support = true,
432 .ht_greenfield_support = true,
433 .led_compensation = 51,
434 .use_rts_for_ht = true, /* use rts/cts protection */
435 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
436 .supports_idle = true,
437 .adv_thermal_throttle = true,
438 .support_ct_kill_exit = true,
439 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
440 .chain_noise_scale = 1000,
441 .monitor_recover_period = IWL_MONITORING_PERIOD,
442 .max_event_log_size = 512,
443 .ucode_tracing = true,
444 .sensitivity_calib_by_driver = true,
445 .chain_noise_calib_by_driver = true,
446};
447
355/* 448/*
356 * "i": Internal configuration, use internal Power Amplifier 449 * "i": Internal configuration, use internal Power Amplifier
357 */ 450 */
358struct iwl_cfg iwl6000i_2agn_cfg = { 451struct iwl_cfg iwl6000i_2agn_cfg = {
359 .name = "6000 Series 2x2 AGN", 452 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
360 .fw_name_pre = IWL6000_FW_PRE, 453 .fw_name_pre = IWL6000_FW_PRE,
361 .ucode_api_max = IWL6000_UCODE_API_MAX, 454 .ucode_api_max = IWL6000_UCODE_API_MAX,
362 .ucode_api_min = IWL6000_UCODE_API_MIN, 455 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -364,10 +457,10 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
364 .ops = &iwl6000_ops, 457 .ops = &iwl6000_ops,
365 .eeprom_size = OTP_LOW_IMAGE_SIZE, 458 .eeprom_size = OTP_LOW_IMAGE_SIZE,
366 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 459 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
367 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 460 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
368 .num_of_queues = IWL50_NUM_QUEUES, 461 .num_of_queues = IWLAGN_NUM_QUEUES,
369 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 462 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
370 .mod_params = &iwl50_mod_params, 463 .mod_params = &iwlagn_mod_params,
371 .valid_tx_ant = ANT_BC, 464 .valid_tx_ant = ANT_BC,
372 .valid_rx_ant = ANT_BC, 465 .valid_rx_ant = ANT_BC,
373 .pll_cfg_val = 0, 466 .pll_cfg_val = 0,
@@ -385,10 +478,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
385 .support_ct_kill_exit = true, 478 .support_ct_kill_exit = true,
386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 479 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
387 .chain_noise_scale = 1000, 480 .chain_noise_scale = 1000,
481 .monitor_recover_period = IWL_MONITORING_PERIOD,
482 .max_event_log_size = 1024,
483 .ucode_tracing = true,
484 .sensitivity_calib_by_driver = true,
485 .chain_noise_calib_by_driver = true,
388}; 486};
389 487
390struct iwl_cfg iwl6000i_2abg_cfg = { 488struct iwl_cfg iwl6000i_2abg_cfg = {
391 .name = "6000 Series 2x2 ABG", 489 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
392 .fw_name_pre = IWL6000_FW_PRE, 490 .fw_name_pre = IWL6000_FW_PRE,
393 .ucode_api_max = IWL6000_UCODE_API_MAX, 491 .ucode_api_max = IWL6000_UCODE_API_MAX,
394 .ucode_api_min = IWL6000_UCODE_API_MIN, 492 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -396,10 +494,10 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
396 .ops = &iwl6000_ops, 494 .ops = &iwl6000_ops,
397 .eeprom_size = OTP_LOW_IMAGE_SIZE, 495 .eeprom_size = OTP_LOW_IMAGE_SIZE,
398 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 496 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
399 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 497 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
400 .num_of_queues = IWL50_NUM_QUEUES, 498 .num_of_queues = IWLAGN_NUM_QUEUES,
401 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 499 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
402 .mod_params = &iwl50_mod_params, 500 .mod_params = &iwlagn_mod_params,
403 .valid_tx_ant = ANT_BC, 501 .valid_tx_ant = ANT_BC,
404 .valid_rx_ant = ANT_BC, 502 .valid_rx_ant = ANT_BC,
405 .pll_cfg_val = 0, 503 .pll_cfg_val = 0,
@@ -408,7 +506,6 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
408 .pa_type = IWL_PA_INTERNAL, 506 .pa_type = IWL_PA_INTERNAL,
409 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 507 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
410 .shadow_ram_support = true, 508 .shadow_ram_support = true,
411 .ht_greenfield_support = true,
412 .led_compensation = 51, 509 .led_compensation = 51,
413 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 510 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
414 .supports_idle = true, 511 .supports_idle = true,
@@ -416,10 +513,15 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
416 .support_ct_kill_exit = true, 513 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 514 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
418 .chain_noise_scale = 1000, 515 .chain_noise_scale = 1000,
516 .monitor_recover_period = IWL_MONITORING_PERIOD,
517 .max_event_log_size = 1024,
518 .ucode_tracing = true,
519 .sensitivity_calib_by_driver = true,
520 .chain_noise_calib_by_driver = true,
419}; 521};
420 522
421struct iwl_cfg iwl6000i_2bg_cfg = { 523struct iwl_cfg iwl6000i_2bg_cfg = {
422 .name = "6000 Series 2x2 BG", 524 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
423 .fw_name_pre = IWL6000_FW_PRE, 525 .fw_name_pre = IWL6000_FW_PRE,
424 .ucode_api_max = IWL6000_UCODE_API_MAX, 526 .ucode_api_max = IWL6000_UCODE_API_MAX,
425 .ucode_api_min = IWL6000_UCODE_API_MIN, 527 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -427,10 +529,10 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
427 .ops = &iwl6000_ops, 529 .ops = &iwl6000_ops,
428 .eeprom_size = OTP_LOW_IMAGE_SIZE, 530 .eeprom_size = OTP_LOW_IMAGE_SIZE,
429 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 531 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
430 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 532 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
431 .num_of_queues = IWL50_NUM_QUEUES, 533 .num_of_queues = IWLAGN_NUM_QUEUES,
432 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 534 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
433 .mod_params = &iwl50_mod_params, 535 .mod_params = &iwlagn_mod_params,
434 .valid_tx_ant = ANT_BC, 536 .valid_tx_ant = ANT_BC,
435 .valid_rx_ant = ANT_BC, 537 .valid_rx_ant = ANT_BC,
436 .pll_cfg_val = 0, 538 .pll_cfg_val = 0,
@@ -439,7 +541,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
439 .pa_type = IWL_PA_INTERNAL, 541 .pa_type = IWL_PA_INTERNAL,
440 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 542 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
441 .shadow_ram_support = true, 543 .shadow_ram_support = true,
442 .ht_greenfield_support = true,
443 .led_compensation = 51, 544 .led_compensation = 51,
444 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 545 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
445 .supports_idle = true, 546 .supports_idle = true,
@@ -447,10 +548,15 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
447 .support_ct_kill_exit = true, 548 .support_ct_kill_exit = true,
448 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 549 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
449 .chain_noise_scale = 1000, 550 .chain_noise_scale = 1000,
551 .monitor_recover_period = IWL_MONITORING_PERIOD,
552 .max_event_log_size = 1024,
553 .ucode_tracing = true,
554 .sensitivity_calib_by_driver = true,
555 .chain_noise_calib_by_driver = true,
450}; 556};
451 557
452struct iwl_cfg iwl6050_2agn_cfg = { 558struct iwl_cfg iwl6050_2agn_cfg = {
453 .name = "6050 Series 2x2 AGN", 559 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
454 .fw_name_pre = IWL6050_FW_PRE, 560 .fw_name_pre = IWL6050_FW_PRE,
455 .ucode_api_max = IWL6050_UCODE_API_MAX, 561 .ucode_api_max = IWL6050_UCODE_API_MAX,
456 .ucode_api_min = IWL6050_UCODE_API_MIN, 562 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -458,10 +564,10 @@ struct iwl_cfg iwl6050_2agn_cfg = {
458 .ops = &iwl6050_ops, 564 .ops = &iwl6050_ops,
459 .eeprom_size = OTP_LOW_IMAGE_SIZE, 565 .eeprom_size = OTP_LOW_IMAGE_SIZE,
460 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 566 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
461 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 567 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
462 .num_of_queues = IWL50_NUM_QUEUES, 568 .num_of_queues = IWLAGN_NUM_QUEUES,
463 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 569 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
464 .mod_params = &iwl50_mod_params, 570 .mod_params = &iwlagn_mod_params,
465 .valid_tx_ant = ANT_AB, 571 .valid_tx_ant = ANT_AB,
466 .valid_rx_ant = ANT_AB, 572 .valid_rx_ant = ANT_AB,
467 .pll_cfg_val = 0, 573 .pll_cfg_val = 0,
@@ -479,10 +585,15 @@ struct iwl_cfg iwl6050_2agn_cfg = {
479 .support_ct_kill_exit = true, 585 .support_ct_kill_exit = true,
480 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 586 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
481 .chain_noise_scale = 1500, 587 .chain_noise_scale = 1500,
588 .monitor_recover_period = IWL_MONITORING_PERIOD,
589 .max_event_log_size = 1024,
590 .ucode_tracing = true,
591 .sensitivity_calib_by_driver = true,
592 .chain_noise_calib_by_driver = true,
482}; 593};
483 594
484struct iwl_cfg iwl6050_2abg_cfg = { 595struct iwl_cfg iwl6050_2abg_cfg = {
485 .name = "6050 Series 2x2 ABG", 596 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
486 .fw_name_pre = IWL6050_FW_PRE, 597 .fw_name_pre = IWL6050_FW_PRE,
487 .ucode_api_max = IWL6050_UCODE_API_MAX, 598 .ucode_api_max = IWL6050_UCODE_API_MAX,
488 .ucode_api_min = IWL6050_UCODE_API_MIN, 599 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -490,10 +601,10 @@ struct iwl_cfg iwl6050_2abg_cfg = {
490 .ops = &iwl6050_ops, 601 .ops = &iwl6050_ops,
491 .eeprom_size = OTP_LOW_IMAGE_SIZE, 602 .eeprom_size = OTP_LOW_IMAGE_SIZE,
492 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, 603 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
493 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 604 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
494 .num_of_queues = IWL50_NUM_QUEUES, 605 .num_of_queues = IWLAGN_NUM_QUEUES,
495 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 606 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
496 .mod_params = &iwl50_mod_params, 607 .mod_params = &iwlagn_mod_params,
497 .valid_tx_ant = ANT_AB, 608 .valid_tx_ant = ANT_AB,
498 .valid_rx_ant = ANT_AB, 609 .valid_rx_ant = ANT_AB,
499 .pll_cfg_val = 0, 610 .pll_cfg_val = 0,
@@ -502,7 +613,6 @@ struct iwl_cfg iwl6050_2abg_cfg = {
502 .pa_type = IWL_PA_SYSTEM, 613 .pa_type = IWL_PA_SYSTEM,
503 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 614 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
504 .shadow_ram_support = true, 615 .shadow_ram_support = true,
505 .ht_greenfield_support = true,
506 .led_compensation = 51, 616 .led_compensation = 51,
507 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 617 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
508 .supports_idle = true, 618 .supports_idle = true,
@@ -510,10 +620,15 @@ struct iwl_cfg iwl6050_2abg_cfg = {
510 .support_ct_kill_exit = true, 620 .support_ct_kill_exit = true,
511 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 621 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
512 .chain_noise_scale = 1500, 622 .chain_noise_scale = 1500,
623 .monitor_recover_period = IWL_MONITORING_PERIOD,
624 .max_event_log_size = 1024,
625 .ucode_tracing = true,
626 .sensitivity_calib_by_driver = true,
627 .chain_noise_calib_by_driver = true,
513}; 628};
514 629
515struct iwl_cfg iwl6000_3agn_cfg = { 630struct iwl_cfg iwl6000_3agn_cfg = {
516 .name = "6000 Series 3x3 AGN", 631 .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
517 .fw_name_pre = IWL6000_FW_PRE, 632 .fw_name_pre = IWL6000_FW_PRE,
518 .ucode_api_max = IWL6000_UCODE_API_MAX, 633 .ucode_api_max = IWL6000_UCODE_API_MAX,
519 .ucode_api_min = IWL6000_UCODE_API_MIN, 634 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -521,10 +636,10 @@ struct iwl_cfg iwl6000_3agn_cfg = {
521 .ops = &iwl6000_ops, 636 .ops = &iwl6000_ops,
522 .eeprom_size = OTP_LOW_IMAGE_SIZE, 637 .eeprom_size = OTP_LOW_IMAGE_SIZE,
523 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 638 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
524 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 639 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
525 .num_of_queues = IWL50_NUM_QUEUES, 640 .num_of_queues = IWLAGN_NUM_QUEUES,
526 .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, 641 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
527 .mod_params = &iwl50_mod_params, 642 .mod_params = &iwlagn_mod_params,
528 .valid_tx_ant = ANT_ABC, 643 .valid_tx_ant = ANT_ABC,
529 .valid_rx_ant = ANT_ABC, 644 .valid_rx_ant = ANT_ABC,
530 .pll_cfg_val = 0, 645 .pll_cfg_val = 0,
@@ -542,7 +657,13 @@ struct iwl_cfg iwl6000_3agn_cfg = {
542 .support_ct_kill_exit = true, 657 .support_ct_kill_exit = true,
543 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 658 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
544 .chain_noise_scale = 1000, 659 .chain_noise_scale = 1000,
660 .monitor_recover_period = IWL_MONITORING_PERIOD,
661 .max_event_log_size = 1024,
662 .ucode_tracing = true,
663 .sensitivity_calib_by_driver = true,
664 .chain_noise_calib_by_driver = true,
545}; 665};
546 666
547MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 667MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
548MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 668MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
669MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
new file mode 100644
index 000000000000..48c023b4ca36
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -0,0 +1,850 @@
1/******************************************************************************
2*
3* GPL LICENSE SUMMARY
4*
5* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6*
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
9* published by the Free Software Foundation.
10*
11* This program is distributed in the hope that it will be useful, but
12* WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14* General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19* USA
20*
21* The full GNU General Public License is included in this distribution
22* in the file called LICENSE.GPL.
23*
24* Contact Information:
25* Intel Linux Wireless <ilw@linux.intel.com>
26* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27*****************************************************************************/
28
29#include "iwl-agn-debugfs.h"
30
31ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
32 size_t count, loff_t *ppos)
33 {
34 struct iwl_priv *priv = file->private_data;
35 int pos = 0;
36 char *buf;
37 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
38 sizeof(struct statistics_rx_non_phy) * 40 +
39 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
40 ssize_t ret;
41 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
42 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
43 struct statistics_rx_non_phy *general, *accum_general;
44 struct statistics_rx_non_phy *delta_general, *max_general;
45 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
46
47 if (!iwl_is_alive(priv))
48 return -EAGAIN;
49
50 buf = kzalloc(bufsz, GFP_KERNEL);
51 if (!buf) {
52 IWL_ERR(priv, "Can not allocate Buffer\n");
53 return -ENOMEM;
54 }
55
56 /*
57 * the statistic information display here is based on
58 * the last statistics notification from uCode
59 * might not reflect the current uCode activity
60 */
61 ofdm = &priv->statistics.rx.ofdm;
62 cck = &priv->statistics.rx.cck;
63 general = &priv->statistics.rx.general;
64 ht = &priv->statistics.rx.ofdm_ht;
65 accum_ofdm = &priv->accum_statistics.rx.ofdm;
66 accum_cck = &priv->accum_statistics.rx.cck;
67 accum_general = &priv->accum_statistics.rx.general;
68 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
69 delta_ofdm = &priv->delta_statistics.rx.ofdm;
70 delta_cck = &priv->delta_statistics.rx.cck;
71 delta_general = &priv->delta_statistics.rx.general;
72 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
73 max_ofdm = &priv->max_delta.rx.ofdm;
74 max_cck = &priv->max_delta.rx.cck;
75 max_general = &priv->max_delta.rx.general;
76 max_ht = &priv->max_delta.rx.ofdm_ht;
77
78 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
79 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
80 "acumulative delta max\n",
81 "Statistics_Rx - OFDM:");
82 pos += scnprintf(buf + pos, bufsz - pos,
83 " %-30s %10u %10u %10u %10u\n",
84 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
85 accum_ofdm->ina_cnt,
86 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
87 pos += scnprintf(buf + pos, bufsz - pos,
88 " %-30s %10u %10u %10u %10u\n",
89 "fina_cnt:",
90 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
91 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
92 pos += scnprintf(buf + pos, bufsz - pos,
93 " %-30s %10u %10u %10u %10u\n",
94 "plcp_err:",
95 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
96 delta_ofdm->plcp_err, max_ofdm->plcp_err);
97 pos += scnprintf(buf + pos, bufsz - pos,
98 " %-30s %10u %10u %10u %10u\n", "crc32_err:",
99 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
100 delta_ofdm->crc32_err, max_ofdm->crc32_err);
101 pos += scnprintf(buf + pos, bufsz - pos,
102 " %-30s %10u %10u %10u %10u\n", "overrun_err:",
103 le32_to_cpu(ofdm->overrun_err),
104 accum_ofdm->overrun_err, delta_ofdm->overrun_err,
105 max_ofdm->overrun_err);
106 pos += scnprintf(buf + pos, bufsz - pos,
107 " %-30s %10u %10u %10u %10u\n",
108 "early_overrun_err:",
109 le32_to_cpu(ofdm->early_overrun_err),
110 accum_ofdm->early_overrun_err,
111 delta_ofdm->early_overrun_err,
112 max_ofdm->early_overrun_err);
113 pos += scnprintf(buf + pos, bufsz - pos,
114 " %-30s %10u %10u %10u %10u\n",
115 "crc32_good:", le32_to_cpu(ofdm->crc32_good),
116 accum_ofdm->crc32_good, delta_ofdm->crc32_good,
117 max_ofdm->crc32_good);
118 pos += scnprintf(buf + pos, bufsz - pos,
119 " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:",
120 le32_to_cpu(ofdm->false_alarm_cnt),
121 accum_ofdm->false_alarm_cnt,
122 delta_ofdm->false_alarm_cnt,
123 max_ofdm->false_alarm_cnt);
124 pos += scnprintf(buf + pos, bufsz - pos,
125 " %-30s %10u %10u %10u %10u\n",
126 "fina_sync_err_cnt:",
127 le32_to_cpu(ofdm->fina_sync_err_cnt),
128 accum_ofdm->fina_sync_err_cnt,
129 delta_ofdm->fina_sync_err_cnt,
130 max_ofdm->fina_sync_err_cnt);
131 pos += scnprintf(buf + pos, bufsz - pos,
132 " %-30s %10u %10u %10u %10u\n", "sfd_timeout:",
133 le32_to_cpu(ofdm->sfd_timeout),
134 accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
135 max_ofdm->sfd_timeout);
136 pos += scnprintf(buf + pos, bufsz - pos,
137 " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
138 le32_to_cpu(ofdm->fina_timeout),
139 accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
140 max_ofdm->fina_timeout);
141 pos += scnprintf(buf + pos, bufsz - pos,
142 " %-30s %10u %10u %10u %10u\n",
143 "unresponded_rts:",
144 le32_to_cpu(ofdm->unresponded_rts),
145 accum_ofdm->unresponded_rts,
146 delta_ofdm->unresponded_rts,
147 max_ofdm->unresponded_rts);
148 pos += scnprintf(buf + pos, bufsz - pos,
149 " %-30s %10u %10u %10u %10u\n",
150 "rxe_frame_lmt_ovrun:",
151 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
152 accum_ofdm->rxe_frame_limit_overrun,
153 delta_ofdm->rxe_frame_limit_overrun,
154 max_ofdm->rxe_frame_limit_overrun);
155 pos += scnprintf(buf + pos, bufsz - pos,
156 " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
157 le32_to_cpu(ofdm->sent_ack_cnt),
158 accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
159 max_ofdm->sent_ack_cnt);
160 pos += scnprintf(buf + pos, bufsz - pos,
161 " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
162 le32_to_cpu(ofdm->sent_cts_cnt),
163 accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
164 max_ofdm->sent_cts_cnt);
165 pos += scnprintf(buf + pos, bufsz - pos,
166 " %-30s %10u %10u %10u %10u\n",
167 "sent_ba_rsp_cnt:",
168 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
169 accum_ofdm->sent_ba_rsp_cnt,
170 delta_ofdm->sent_ba_rsp_cnt,
171 max_ofdm->sent_ba_rsp_cnt);
172 pos += scnprintf(buf + pos, bufsz - pos,
173 " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
174 le32_to_cpu(ofdm->dsp_self_kill),
175 accum_ofdm->dsp_self_kill,
176 delta_ofdm->dsp_self_kill,
177 max_ofdm->dsp_self_kill);
178 pos += scnprintf(buf + pos, bufsz - pos,
179 " %-30s %10u %10u %10u %10u\n",
180 "mh_format_err:",
181 le32_to_cpu(ofdm->mh_format_err),
182 accum_ofdm->mh_format_err,
183 delta_ofdm->mh_format_err,
184 max_ofdm->mh_format_err);
185 pos += scnprintf(buf + pos, bufsz - pos,
186 " %-30s %10u %10u %10u %10u\n",
187 "re_acq_main_rssi_sum:",
188 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
189 accum_ofdm->re_acq_main_rssi_sum,
190 delta_ofdm->re_acq_main_rssi_sum,
191 max_ofdm->re_acq_main_rssi_sum);
192
193 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
194 "acumulative delta max\n",
195 "Statistics_Rx - CCK:");
196 pos += scnprintf(buf + pos, bufsz - pos,
197 " %-30s %10u %10u %10u %10u\n",
198 "ina_cnt:",
199 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
200 delta_cck->ina_cnt, max_cck->ina_cnt);
201 pos += scnprintf(buf + pos, bufsz - pos,
202 " %-30s %10u %10u %10u %10u\n",
203 "fina_cnt:",
204 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
205 delta_cck->fina_cnt, max_cck->fina_cnt);
206 pos += scnprintf(buf + pos, bufsz - pos,
207 " %-30s %10u %10u %10u %10u\n",
208 "plcp_err:",
209 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
210 delta_cck->plcp_err, max_cck->plcp_err);
211 pos += scnprintf(buf + pos, bufsz - pos,
212 " %-30s %10u %10u %10u %10u\n",
213 "crc32_err:",
214 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
215 delta_cck->crc32_err, max_cck->crc32_err);
216 pos += scnprintf(buf + pos, bufsz - pos,
217 " %-30s %10u %10u %10u %10u\n",
218 "overrun_err:",
219 le32_to_cpu(cck->overrun_err),
220 accum_cck->overrun_err, delta_cck->overrun_err,
221 max_cck->overrun_err);
222 pos += scnprintf(buf + pos, bufsz - pos,
223 " %-30s %10u %10u %10u %10u\n",
224 "early_overrun_err:",
225 le32_to_cpu(cck->early_overrun_err),
226 accum_cck->early_overrun_err,
227 delta_cck->early_overrun_err,
228 max_cck->early_overrun_err);
229 pos += scnprintf(buf + pos, bufsz - pos,
230 " %-30s %10u %10u %10u %10u\n",
231 "crc32_good:",
232 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
233 delta_cck->crc32_good, max_cck->crc32_good);
234 pos += scnprintf(buf + pos, bufsz - pos,
235 " %-30s %10u %10u %10u %10u\n",
236 "false_alarm_cnt:",
237 le32_to_cpu(cck->false_alarm_cnt),
238 accum_cck->false_alarm_cnt,
239 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
240 pos += scnprintf(buf + pos, bufsz - pos,
241 " %-30s %10u %10u %10u %10u\n",
242 "fina_sync_err_cnt:",
243 le32_to_cpu(cck->fina_sync_err_cnt),
244 accum_cck->fina_sync_err_cnt,
245 delta_cck->fina_sync_err_cnt,
246 max_cck->fina_sync_err_cnt);
247 pos += scnprintf(buf + pos, bufsz - pos,
248 " %-30s %10u %10u %10u %10u\n",
249 "sfd_timeout:",
250 le32_to_cpu(cck->sfd_timeout),
251 accum_cck->sfd_timeout, delta_cck->sfd_timeout,
252 max_cck->sfd_timeout);
253 pos += scnprintf(buf + pos, bufsz - pos,
254 " %-30s %10u %10u %10u %10u\n", "fina_timeout:",
255 le32_to_cpu(cck->fina_timeout),
256 accum_cck->fina_timeout, delta_cck->fina_timeout,
257 max_cck->fina_timeout);
258 pos += scnprintf(buf + pos, bufsz - pos,
259 " %-30s %10u %10u %10u %10u\n",
260 "unresponded_rts:",
261 le32_to_cpu(cck->unresponded_rts),
262 accum_cck->unresponded_rts, delta_cck->unresponded_rts,
263 max_cck->unresponded_rts);
264 pos += scnprintf(buf + pos, bufsz - pos,
265 " %-30s %10u %10u %10u %10u\n",
266 "rxe_frame_lmt_ovrun:",
267 le32_to_cpu(cck->rxe_frame_limit_overrun),
268 accum_cck->rxe_frame_limit_overrun,
269 delta_cck->rxe_frame_limit_overrun,
270 max_cck->rxe_frame_limit_overrun);
271 pos += scnprintf(buf + pos, bufsz - pos,
272 " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:",
273 le32_to_cpu(cck->sent_ack_cnt),
274 accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
275 max_cck->sent_ack_cnt);
276 pos += scnprintf(buf + pos, bufsz - pos,
277 " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:",
278 le32_to_cpu(cck->sent_cts_cnt),
279 accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
280 max_cck->sent_cts_cnt);
281 pos += scnprintf(buf + pos, bufsz - pos,
282 " %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:",
283 le32_to_cpu(cck->sent_ba_rsp_cnt),
284 accum_cck->sent_ba_rsp_cnt,
285 delta_cck->sent_ba_rsp_cnt,
286 max_cck->sent_ba_rsp_cnt);
287 pos += scnprintf(buf + pos, bufsz - pos,
288 " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:",
289 le32_to_cpu(cck->dsp_self_kill),
290 accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
291 max_cck->dsp_self_kill);
292 pos += scnprintf(buf + pos, bufsz - pos,
293 " %-30s %10u %10u %10u %10u\n", "mh_format_err:",
294 le32_to_cpu(cck->mh_format_err),
295 accum_cck->mh_format_err, delta_cck->mh_format_err,
296 max_cck->mh_format_err);
297 pos += scnprintf(buf + pos, bufsz - pos,
298 " %-30s %10u %10u %10u %10u\n",
299 "re_acq_main_rssi_sum:",
300 le32_to_cpu(cck->re_acq_main_rssi_sum),
301 accum_cck->re_acq_main_rssi_sum,
302 delta_cck->re_acq_main_rssi_sum,
303 max_cck->re_acq_main_rssi_sum);
304
305 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
306 "acumulative delta max\n",
307 "Statistics_Rx - GENERAL:");
308 pos += scnprintf(buf + pos, bufsz - pos,
309 " %-30s %10u %10u %10u %10u\n", "bogus_cts:",
310 le32_to_cpu(general->bogus_cts),
311 accum_general->bogus_cts, delta_general->bogus_cts,
312 max_general->bogus_cts);
313 pos += scnprintf(buf + pos, bufsz - pos,
314 " %-30s %10u %10u %10u %10u\n", "bogus_ack:",
315 le32_to_cpu(general->bogus_ack),
316 accum_general->bogus_ack, delta_general->bogus_ack,
317 max_general->bogus_ack);
318 pos += scnprintf(buf + pos, bufsz - pos,
319 " %-30s %10u %10u %10u %10u\n",
320 "non_bssid_frames:",
321 le32_to_cpu(general->non_bssid_frames),
322 accum_general->non_bssid_frames,
323 delta_general->non_bssid_frames,
324 max_general->non_bssid_frames);
325 pos += scnprintf(buf + pos, bufsz - pos,
326 " %-30s %10u %10u %10u %10u\n",
327 "filtered_frames:",
328 le32_to_cpu(general->filtered_frames),
329 accum_general->filtered_frames,
330 delta_general->filtered_frames,
331 max_general->filtered_frames);
332 pos += scnprintf(buf + pos, bufsz - pos,
333 " %-30s %10u %10u %10u %10u\n",
334 "non_channel_beacons:",
335 le32_to_cpu(general->non_channel_beacons),
336 accum_general->non_channel_beacons,
337 delta_general->non_channel_beacons,
338 max_general->non_channel_beacons);
339 pos += scnprintf(buf + pos, bufsz - pos,
340 " %-30s %10u %10u %10u %10u\n",
341 "channel_beacons:",
342 le32_to_cpu(general->channel_beacons),
343 accum_general->channel_beacons,
344 delta_general->channel_beacons,
345 max_general->channel_beacons);
346 pos += scnprintf(buf + pos, bufsz - pos,
347 " %-30s %10u %10u %10u %10u\n",
348 "num_missed_bcon:",
349 le32_to_cpu(general->num_missed_bcon),
350 accum_general->num_missed_bcon,
351 delta_general->num_missed_bcon,
352 max_general->num_missed_bcon);
353 pos += scnprintf(buf + pos, bufsz - pos,
354 " %-30s %10u %10u %10u %10u\n",
355 "adc_rx_saturation_time:",
356 le32_to_cpu(general->adc_rx_saturation_time),
357 accum_general->adc_rx_saturation_time,
358 delta_general->adc_rx_saturation_time,
359 max_general->adc_rx_saturation_time);
360 pos += scnprintf(buf + pos, bufsz - pos,
361 " %-30s %10u %10u %10u %10u\n",
362 "ina_detect_search_tm:",
363 le32_to_cpu(general->ina_detection_search_time),
364 accum_general->ina_detection_search_time,
365 delta_general->ina_detection_search_time,
366 max_general->ina_detection_search_time);
367 pos += scnprintf(buf + pos, bufsz - pos,
368 " %-30s %10u %10u %10u %10u\n",
369 "beacon_silence_rssi_a:",
370 le32_to_cpu(general->beacon_silence_rssi_a),
371 accum_general->beacon_silence_rssi_a,
372 delta_general->beacon_silence_rssi_a,
373 max_general->beacon_silence_rssi_a);
374 pos += scnprintf(buf + pos, bufsz - pos,
375 " %-30s %10u %10u %10u %10u\n",
376 "beacon_silence_rssi_b:",
377 le32_to_cpu(general->beacon_silence_rssi_b),
378 accum_general->beacon_silence_rssi_b,
379 delta_general->beacon_silence_rssi_b,
380 max_general->beacon_silence_rssi_b);
381 pos += scnprintf(buf + pos, bufsz - pos,
382 " %-30s %10u %10u %10u %10u\n",
383 "beacon_silence_rssi_c:",
384 le32_to_cpu(general->beacon_silence_rssi_c),
385 accum_general->beacon_silence_rssi_c,
386 delta_general->beacon_silence_rssi_c,
387 max_general->beacon_silence_rssi_c);
388 pos += scnprintf(buf + pos, bufsz - pos,
389 " %-30s %10u %10u %10u %10u\n",
390 "interference_data_flag:",
391 le32_to_cpu(general->interference_data_flag),
392 accum_general->interference_data_flag,
393 delta_general->interference_data_flag,
394 max_general->interference_data_flag);
395 pos += scnprintf(buf + pos, bufsz - pos,
396 " %-30s %10u %10u %10u %10u\n",
397 "channel_load:",
398 le32_to_cpu(general->channel_load),
399 accum_general->channel_load,
400 delta_general->channel_load,
401 max_general->channel_load);
402 pos += scnprintf(buf + pos, bufsz - pos,
403 " %-30s %10u %10u %10u %10u\n",
404 "dsp_false_alarms:",
405 le32_to_cpu(general->dsp_false_alarms),
406 accum_general->dsp_false_alarms,
407 delta_general->dsp_false_alarms,
408 max_general->dsp_false_alarms);
409 pos += scnprintf(buf + pos, bufsz - pos,
410 " %-30s %10u %10u %10u %10u\n",
411 "beacon_rssi_a:",
412 le32_to_cpu(general->beacon_rssi_a),
413 accum_general->beacon_rssi_a,
414 delta_general->beacon_rssi_a,
415 max_general->beacon_rssi_a);
416 pos += scnprintf(buf + pos, bufsz - pos,
417 " %-30s %10u %10u %10u %10u\n",
418 "beacon_rssi_b:",
419 le32_to_cpu(general->beacon_rssi_b),
420 accum_general->beacon_rssi_b,
421 delta_general->beacon_rssi_b,
422 max_general->beacon_rssi_b);
423 pos += scnprintf(buf + pos, bufsz - pos,
424 " %-30s %10u %10u %10u %10u\n",
425 "beacon_rssi_c:",
426 le32_to_cpu(general->beacon_rssi_c),
427 accum_general->beacon_rssi_c,
428 delta_general->beacon_rssi_c,
429 max_general->beacon_rssi_c);
430 pos += scnprintf(buf + pos, bufsz - pos,
431 " %-30s %10u %10u %10u %10u\n",
432 "beacon_energy_a:",
433 le32_to_cpu(general->beacon_energy_a),
434 accum_general->beacon_energy_a,
435 delta_general->beacon_energy_a,
436 max_general->beacon_energy_a);
437 pos += scnprintf(buf + pos, bufsz - pos,
438 " %-30s %10u %10u %10u %10u\n",
439 "beacon_energy_b:",
440 le32_to_cpu(general->beacon_energy_b),
441 accum_general->beacon_energy_b,
442 delta_general->beacon_energy_b,
443 max_general->beacon_energy_b);
444 pos += scnprintf(buf + pos, bufsz - pos,
445 " %-30s %10u %10u %10u %10u\n",
446 "beacon_energy_c:",
447 le32_to_cpu(general->beacon_energy_c),
448 accum_general->beacon_energy_c,
449 delta_general->beacon_energy_c,
450 max_general->beacon_energy_c);
451
452 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
453 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
454 "acumulative delta max\n",
455 "Statistics_Rx - OFDM_HT:");
456 pos += scnprintf(buf + pos, bufsz - pos,
457 " %-30s %10u %10u %10u %10u\n",
458 "plcp_err:",
459 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
460 delta_ht->plcp_err, max_ht->plcp_err);
461 pos += scnprintf(buf + pos, bufsz - pos,
462 " %-30s %10u %10u %10u %10u\n",
463 "overrun_err:",
464 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
465 delta_ht->overrun_err, max_ht->overrun_err);
466 pos += scnprintf(buf + pos, bufsz - pos,
467 " %-30s %10u %10u %10u %10u\n",
468 "early_overrun_err:",
469 le32_to_cpu(ht->early_overrun_err),
470 accum_ht->early_overrun_err,
471 delta_ht->early_overrun_err,
472 max_ht->early_overrun_err);
473 pos += scnprintf(buf + pos, bufsz - pos,
474 " %-30s %10u %10u %10u %10u\n",
475 "crc32_good:",
476 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
477 delta_ht->crc32_good, max_ht->crc32_good);
478 pos += scnprintf(buf + pos, bufsz - pos,
479 " %-30s %10u %10u %10u %10u\n",
480 "crc32_err:",
481 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
482 delta_ht->crc32_err, max_ht->crc32_err);
483 pos += scnprintf(buf + pos, bufsz - pos,
484 " %-30s %10u %10u %10u %10u\n",
485 "mh_format_err:",
486 le32_to_cpu(ht->mh_format_err),
487 accum_ht->mh_format_err,
488 delta_ht->mh_format_err, max_ht->mh_format_err);
489 pos += scnprintf(buf + pos, bufsz - pos,
490 " %-30s %10u %10u %10u %10u\n",
491 "agg_crc32_good:",
492 le32_to_cpu(ht->agg_crc32_good),
493 accum_ht->agg_crc32_good,
494 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
495 pos += scnprintf(buf + pos, bufsz - pos,
496 " %-30s %10u %10u %10u %10u\n",
497 "agg_mpdu_cnt:",
498 le32_to_cpu(ht->agg_mpdu_cnt),
499 accum_ht->agg_mpdu_cnt,
500 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
501 pos += scnprintf(buf + pos, bufsz - pos,
502 " %-30s %10u %10u %10u %10u\n",
503 "agg_cnt:",
504 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
505 delta_ht->agg_cnt, max_ht->agg_cnt);
506 pos += scnprintf(buf + pos, bufsz - pos,
507 " %-30s %10u %10u %10u %10u\n",
508 "unsupport_mcs:",
509 le32_to_cpu(ht->unsupport_mcs),
510 accum_ht->unsupport_mcs,
511 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
512
513 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
514 kfree(buf);
515 return ret;
516}
517
518ssize_t iwl_ucode_tx_stats_read(struct file *file,
519 char __user *user_buf,
520 size_t count, loff_t *ppos)
521{
522 struct iwl_priv *priv = file->private_data;
523 int pos = 0;
524 char *buf;
525 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
526 ssize_t ret;
527 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
528
529 if (!iwl_is_alive(priv))
530 return -EAGAIN;
531
532 buf = kzalloc(bufsz, GFP_KERNEL);
533 if (!buf) {
534 IWL_ERR(priv, "Can not allocate Buffer\n");
535 return -ENOMEM;
536 }
537
538 /* the statistic information display here is based on
539 * the last statistics notification from uCode
540 * might not reflect the current uCode activity
541 */
542 tx = &priv->statistics.tx;
543 accum_tx = &priv->accum_statistics.tx;
544 delta_tx = &priv->delta_statistics.tx;
545 max_tx = &priv->max_delta.tx;
546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
547 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
548 "acumulative delta max\n",
549 "Statistics_Tx:");
550 pos += scnprintf(buf + pos, bufsz - pos,
551 " %-30s %10u %10u %10u %10u\n",
552 "preamble:",
553 le32_to_cpu(tx->preamble_cnt),
554 accum_tx->preamble_cnt,
555 delta_tx->preamble_cnt, max_tx->preamble_cnt);
556 pos += scnprintf(buf + pos, bufsz - pos,
557 " %-30s %10u %10u %10u %10u\n",
558 "rx_detected_cnt:",
559 le32_to_cpu(tx->rx_detected_cnt),
560 accum_tx->rx_detected_cnt,
561 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
562 pos += scnprintf(buf + pos, bufsz - pos,
563 " %-30s %10u %10u %10u %10u\n",
564 "bt_prio_defer_cnt:",
565 le32_to_cpu(tx->bt_prio_defer_cnt),
566 accum_tx->bt_prio_defer_cnt,
567 delta_tx->bt_prio_defer_cnt,
568 max_tx->bt_prio_defer_cnt);
569 pos += scnprintf(buf + pos, bufsz - pos,
570 " %-30s %10u %10u %10u %10u\n",
571 "bt_prio_kill_cnt:",
572 le32_to_cpu(tx->bt_prio_kill_cnt),
573 accum_tx->bt_prio_kill_cnt,
574 delta_tx->bt_prio_kill_cnt,
575 max_tx->bt_prio_kill_cnt);
576 pos += scnprintf(buf + pos, bufsz - pos,
577 " %-30s %10u %10u %10u %10u\n",
578 "few_bytes_cnt:",
579 le32_to_cpu(tx->few_bytes_cnt),
580 accum_tx->few_bytes_cnt,
581 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
582 pos += scnprintf(buf + pos, bufsz - pos,
583 " %-30s %10u %10u %10u %10u\n",
584 "cts_timeout:",
585 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
586 delta_tx->cts_timeout, max_tx->cts_timeout);
587 pos += scnprintf(buf + pos, bufsz - pos,
588 " %-30s %10u %10u %10u %10u\n",
589 "ack_timeout:",
590 le32_to_cpu(tx->ack_timeout),
591 accum_tx->ack_timeout,
592 delta_tx->ack_timeout, max_tx->ack_timeout);
593 pos += scnprintf(buf + pos, bufsz - pos,
594 " %-30s %10u %10u %10u %10u\n",
595 "expected_ack_cnt:",
596 le32_to_cpu(tx->expected_ack_cnt),
597 accum_tx->expected_ack_cnt,
598 delta_tx->expected_ack_cnt,
599 max_tx->expected_ack_cnt);
600 pos += scnprintf(buf + pos, bufsz - pos,
601 " %-30s %10u %10u %10u %10u\n",
602 "actual_ack_cnt:",
603 le32_to_cpu(tx->actual_ack_cnt),
604 accum_tx->actual_ack_cnt,
605 delta_tx->actual_ack_cnt,
606 max_tx->actual_ack_cnt);
607 pos += scnprintf(buf + pos, bufsz - pos,
608 " %-30s %10u %10u %10u %10u\n",
609 "dump_msdu_cnt:",
610 le32_to_cpu(tx->dump_msdu_cnt),
611 accum_tx->dump_msdu_cnt,
612 delta_tx->dump_msdu_cnt,
613 max_tx->dump_msdu_cnt);
614 pos += scnprintf(buf + pos, bufsz - pos,
615 " %-30s %10u %10u %10u %10u\n",
616 "abort_nxt_frame_mismatch:",
617 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
618 accum_tx->burst_abort_next_frame_mismatch_cnt,
619 delta_tx->burst_abort_next_frame_mismatch_cnt,
620 max_tx->burst_abort_next_frame_mismatch_cnt);
621 pos += scnprintf(buf + pos, bufsz - pos,
622 " %-30s %10u %10u %10u %10u\n",
623 "abort_missing_nxt_frame:",
624 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
625 accum_tx->burst_abort_missing_next_frame_cnt,
626 delta_tx->burst_abort_missing_next_frame_cnt,
627 max_tx->burst_abort_missing_next_frame_cnt);
628 pos += scnprintf(buf + pos, bufsz - pos,
629 " %-30s %10u %10u %10u %10u\n",
630 "cts_timeout_collision:",
631 le32_to_cpu(tx->cts_timeout_collision),
632 accum_tx->cts_timeout_collision,
633 delta_tx->cts_timeout_collision,
634 max_tx->cts_timeout_collision);
635 pos += scnprintf(buf + pos, bufsz - pos,
636 " %-30s %10u %10u %10u %10u\n",
637 "ack_ba_timeout_collision:",
638 le32_to_cpu(tx->ack_or_ba_timeout_collision),
639 accum_tx->ack_or_ba_timeout_collision,
640 delta_tx->ack_or_ba_timeout_collision,
641 max_tx->ack_or_ba_timeout_collision);
642 pos += scnprintf(buf + pos, bufsz - pos,
643 " %-30s %10u %10u %10u %10u\n",
644 "agg ba_timeout:",
645 le32_to_cpu(tx->agg.ba_timeout),
646 accum_tx->agg.ba_timeout,
647 delta_tx->agg.ba_timeout,
648 max_tx->agg.ba_timeout);
649 pos += scnprintf(buf + pos, bufsz - pos,
650 " %-30s %10u %10u %10u %10u\n",
651 "agg ba_resched_frames:",
652 le32_to_cpu(tx->agg.ba_reschedule_frames),
653 accum_tx->agg.ba_reschedule_frames,
654 delta_tx->agg.ba_reschedule_frames,
655 max_tx->agg.ba_reschedule_frames);
656 pos += scnprintf(buf + pos, bufsz - pos,
657 " %-30s %10u %10u %10u %10u\n",
658 "agg scd_query_agg_frame:",
659 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
660 accum_tx->agg.scd_query_agg_frame_cnt,
661 delta_tx->agg.scd_query_agg_frame_cnt,
662 max_tx->agg.scd_query_agg_frame_cnt);
663 pos += scnprintf(buf + pos, bufsz - pos,
664 " %-30s %10u %10u %10u %10u\n",
665 "agg scd_query_no_agg:",
666 le32_to_cpu(tx->agg.scd_query_no_agg),
667 accum_tx->agg.scd_query_no_agg,
668 delta_tx->agg.scd_query_no_agg,
669 max_tx->agg.scd_query_no_agg);
670 pos += scnprintf(buf + pos, bufsz - pos,
671 " %-30s %10u %10u %10u %10u\n",
672 "agg scd_query_agg:",
673 le32_to_cpu(tx->agg.scd_query_agg),
674 accum_tx->agg.scd_query_agg,
675 delta_tx->agg.scd_query_agg,
676 max_tx->agg.scd_query_agg);
677 pos += scnprintf(buf + pos, bufsz - pos,
678 " %-30s %10u %10u %10u %10u\n",
679 "agg scd_query_mismatch:",
680 le32_to_cpu(tx->agg.scd_query_mismatch),
681 accum_tx->agg.scd_query_mismatch,
682 delta_tx->agg.scd_query_mismatch,
683 max_tx->agg.scd_query_mismatch);
684 pos += scnprintf(buf + pos, bufsz - pos,
685 " %-30s %10u %10u %10u %10u\n",
686 "agg frame_not_ready:",
687 le32_to_cpu(tx->agg.frame_not_ready),
688 accum_tx->agg.frame_not_ready,
689 delta_tx->agg.frame_not_ready,
690 max_tx->agg.frame_not_ready);
691 pos += scnprintf(buf + pos, bufsz - pos,
692 " %-30s %10u %10u %10u %10u\n",
693 "agg underrun:",
694 le32_to_cpu(tx->agg.underrun),
695 accum_tx->agg.underrun,
696 delta_tx->agg.underrun, max_tx->agg.underrun);
697 pos += scnprintf(buf + pos, bufsz - pos,
698 " %-30s %10u %10u %10u %10u\n",
699 "agg bt_prio_kill:",
700 le32_to_cpu(tx->agg.bt_prio_kill),
701 accum_tx->agg.bt_prio_kill,
702 delta_tx->agg.bt_prio_kill,
703 max_tx->agg.bt_prio_kill);
704 pos += scnprintf(buf + pos, bufsz - pos,
705 " %-30s %10u %10u %10u %10u\n",
706 "agg rx_ba_rsp_cnt:",
707 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
708 accum_tx->agg.rx_ba_rsp_cnt,
709 delta_tx->agg.rx_ba_rsp_cnt,
710 max_tx->agg.rx_ba_rsp_cnt);
711
712 if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
713 pos += scnprintf(buf + pos, bufsz - pos,
714 "tx power: (1/2 dB step)\n");
715 if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
716 pos += scnprintf(buf + pos, bufsz - pos,
717 "\tantenna A: 0x%X\n",
718 tx->tx_power.ant_a);
719 if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
720 pos += scnprintf(buf + pos, bufsz - pos,
721 "\tantenna B: 0x%X\n",
722 tx->tx_power.ant_b);
723 if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
724 pos += scnprintf(buf + pos, bufsz - pos,
725 "\tantenna C: 0x%X\n",
726 tx->tx_power.ant_c);
727 }
728 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
729 kfree(buf);
730 return ret;
731}
732
733ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
734 size_t count, loff_t *ppos)
735{
736 struct iwl_priv *priv = file->private_data;
737 int pos = 0;
738 char *buf;
739 int bufsz = sizeof(struct statistics_general) * 10 + 300;
740 ssize_t ret;
741 struct statistics_general *general, *accum_general;
742 struct statistics_general *delta_general, *max_general;
743 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
744 struct statistics_div *div, *accum_div, *delta_div, *max_div;
745
746 if (!iwl_is_alive(priv))
747 return -EAGAIN;
748
749 buf = kzalloc(bufsz, GFP_KERNEL);
750 if (!buf) {
751 IWL_ERR(priv, "Can not allocate Buffer\n");
752 return -ENOMEM;
753 }
754
755 /* the statistic information display here is based on
756 * the last statistics notification from uCode
757 * might not reflect the current uCode activity
758 */
759 general = &priv->statistics.general;
760 dbg = &priv->statistics.general.dbg;
761 div = &priv->statistics.general.div;
762 accum_general = &priv->accum_statistics.general;
763 delta_general = &priv->delta_statistics.general;
764 max_general = &priv->max_delta.general;
765 accum_dbg = &priv->accum_statistics.general.dbg;
766 delta_dbg = &priv->delta_statistics.general.dbg;
767 max_dbg = &priv->max_delta.general.dbg;
768 accum_div = &priv->accum_statistics.general.div;
769 delta_div = &priv->delta_statistics.general.div;
770 max_div = &priv->max_delta.general.div;
771 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
772 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
773 "acumulative delta max\n",
774 "Statistics_General:");
775 pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
776 "temperature:",
777 le32_to_cpu(general->temperature));
778 pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n",
779 "temperature_m:",
780 le32_to_cpu(general->temperature_m));
781 pos += scnprintf(buf + pos, bufsz - pos,
782 " %-30s %10u %10u %10u %10u\n",
783 "burst_check:",
784 le32_to_cpu(dbg->burst_check),
785 accum_dbg->burst_check,
786 delta_dbg->burst_check, max_dbg->burst_check);
787 pos += scnprintf(buf + pos, bufsz - pos,
788 " %-30s %10u %10u %10u %10u\n",
789 "burst_count:",
790 le32_to_cpu(dbg->burst_count),
791 accum_dbg->burst_count,
792 delta_dbg->burst_count, max_dbg->burst_count);
793 pos += scnprintf(buf + pos, bufsz - pos,
794 " %-30s %10u %10u %10u %10u\n",
795 "sleep_time:",
796 le32_to_cpu(general->sleep_time),
797 accum_general->sleep_time,
798 delta_general->sleep_time, max_general->sleep_time);
799 pos += scnprintf(buf + pos, bufsz - pos,
800 " %-30s %10u %10u %10u %10u\n",
801 "slots_out:",
802 le32_to_cpu(general->slots_out),
803 accum_general->slots_out,
804 delta_general->slots_out, max_general->slots_out);
805 pos += scnprintf(buf + pos, bufsz - pos,
806 " %-30s %10u %10u %10u %10u\n",
807 "slots_idle:",
808 le32_to_cpu(general->slots_idle),
809 accum_general->slots_idle,
810 delta_general->slots_idle, max_general->slots_idle);
811 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
812 le32_to_cpu(general->ttl_timestamp));
813 pos += scnprintf(buf + pos, bufsz - pos,
814 " %-30s %10u %10u %10u %10u\n",
815 "tx_on_a:",
816 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
817 delta_div->tx_on_a, max_div->tx_on_a);
818 pos += scnprintf(buf + pos, bufsz - pos,
819 " %-30s %10u %10u %10u %10u\n",
820 "tx_on_b:",
821 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
822 delta_div->tx_on_b, max_div->tx_on_b);
823 pos += scnprintf(buf + pos, bufsz - pos,
824 " %-30s %10u %10u %10u %10u\n",
825 "exec_time:",
826 le32_to_cpu(div->exec_time), accum_div->exec_time,
827 delta_div->exec_time, max_div->exec_time);
828 pos += scnprintf(buf + pos, bufsz - pos,
829 " %-30s %10u %10u %10u %10u\n",
830 "probe_time:",
831 le32_to_cpu(div->probe_time), accum_div->probe_time,
832 delta_div->probe_time, max_div->probe_time);
833 pos += scnprintf(buf + pos, bufsz - pos,
834 " %-30s %10u %10u %10u %10u\n",
835 "rx_enable_counter:",
836 le32_to_cpu(general->rx_enable_counter),
837 accum_general->rx_enable_counter,
838 delta_general->rx_enable_counter,
839 max_general->rx_enable_counter);
840 pos += scnprintf(buf + pos, bufsz - pos,
841 " %-30s %10u %10u %10u %10u\n",
842 "num_of_sos_states:",
843 le32_to_cpu(general->num_of_sos_states),
844 accum_general->num_of_sos_states,
845 delta_general->num_of_sos_states,
846 max_general->num_of_sos_states);
847 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
848 kfree(buf);
849 return ret;
850}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
new file mode 100644
index 000000000000..59b1f25f0d85
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
@@ -0,0 +1,56 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include "iwl-dev.h"
30#include "iwl-core.h"
31#include "iwl-debug.h"
32
33#ifdef CONFIG_IWLWIFI_DEBUGFS
34ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
35 size_t count, loff_t *ppos);
36ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
37 size_t count, loff_t *ppos);
38ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
39 size_t count, loff_t *ppos);
40#else
41static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
42 size_t count, loff_t *ppos)
43{
44 return 0;
45}
46static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
47 size_t count, loff_t *ppos)
48{
49 return 0;
50}
51static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
52 size_t count, loff_t *ppos)
53{
54 return 0;
55}
56#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
new file mode 100644
index 000000000000..44ef5d93befc
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -0,0 +1,276 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-agn.h"
39
40static int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
41{
42 int ret = 0;
43 struct iwl5000_rxon_assoc_cmd rxon_assoc;
44 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
45 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
46
47 if ((rxon1->flags == rxon2->flags) &&
48 (rxon1->filter_flags == rxon2->filter_flags) &&
49 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
50 (rxon1->ofdm_ht_single_stream_basic_rates ==
51 rxon2->ofdm_ht_single_stream_basic_rates) &&
52 (rxon1->ofdm_ht_dual_stream_basic_rates ==
53 rxon2->ofdm_ht_dual_stream_basic_rates) &&
54 (rxon1->ofdm_ht_triple_stream_basic_rates ==
55 rxon2->ofdm_ht_triple_stream_basic_rates) &&
56 (rxon1->acquisition_data == rxon2->acquisition_data) &&
57 (rxon1->rx_chain == rxon2->rx_chain) &&
58 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
59 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
60 return 0;
61 }
62
63 rxon_assoc.flags = priv->staging_rxon.flags;
64 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
65 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
66 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
67 rxon_assoc.reserved1 = 0;
68 rxon_assoc.reserved2 = 0;
69 rxon_assoc.reserved3 = 0;
70 rxon_assoc.ofdm_ht_single_stream_basic_rates =
71 priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
72 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
73 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
74 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
75 rxon_assoc.ofdm_ht_triple_stream_basic_rates =
76 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
77 rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
78
79 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
80 sizeof(rxon_assoc), &rxon_assoc, NULL);
81 if (ret)
82 return ret;
83
84 return ret;
85}
86
87static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
88{
89 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
90 .valid = cpu_to_le32(valid_tx_ant),
91 };
92
93 if (IWL_UCODE_API(priv->ucode_ver) > 1) {
94 IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
95 return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
96 sizeof(struct iwl_tx_ant_config_cmd),
97 &tx_ant_cmd);
98 } else {
99 IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
100 return -EOPNOTSUPP;
101 }
102}
103
104/* Currently this is the superset of everything */
105static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
106{
107 return len;
108}
109
110static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
111{
112 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
113 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
114 memcpy(addsta, cmd, size);
115 /* resrved in 5000 */
116 addsta->rate_n_flags = cpu_to_le16(0);
117 return size;
118}
119
120static void iwlagn_gain_computation(struct iwl_priv *priv,
121 u32 average_noise[NUM_RX_CHAINS],
122 u16 min_average_noise_antenna_i,
123 u32 min_average_noise,
124 u8 default_chain)
125{
126 int i;
127 s32 delta_g;
128 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
129
130 /*
131 * Find Gain Code for the chains based on "default chain"
132 */
133 for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
134 if ((data->disconn_array[i])) {
135 data->delta_gain_code[i] = 0;
136 continue;
137 }
138
139 delta_g = (priv->cfg->chain_noise_scale *
140 ((s32)average_noise[default_chain] -
141 (s32)average_noise[i])) / 1500;
142
143 /* bound gain by 2 bits value max, 3rd bit is sign */
144 data->delta_gain_code[i] =
145 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
146
147 if (delta_g < 0)
148 /*
149 * set negative sign ...
150 * note to Intel developers: This is uCode API format,
151 * not the format of any internal device registers.
152 * Do not change this format for e.g. 6050 or similar
153 * devices. Change format only if more resolution
154 * (i.e. more than 2 bits magnitude) is needed.
155 */
156 data->delta_gain_code[i] |= (1 << 2);
157 }
158
159 IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
160 data->delta_gain_code[1], data->delta_gain_code[2]);
161
162 if (!data->radio_write) {
163 struct iwl_calib_chain_noise_gain_cmd cmd;
164
165 memset(&cmd, 0, sizeof(cmd));
166
167 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
168 cmd.hdr.first_group = 0;
169 cmd.hdr.groups_num = 1;
170 cmd.hdr.data_valid = 1;
171 cmd.delta_gain_1 = data->delta_gain_code[1];
172 cmd.delta_gain_2 = data->delta_gain_code[2];
173 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
174 sizeof(cmd), &cmd, NULL);
175
176 data->radio_write = 1;
177 data->state = IWL_CHAIN_NOISE_CALIBRATED;
178 }
179
180 data->chain_noise_a = 0;
181 data->chain_noise_b = 0;
182 data->chain_noise_c = 0;
183 data->chain_signal_a = 0;
184 data->chain_signal_b = 0;
185 data->chain_signal_c = 0;
186 data->beacon_count = 0;
187}
188
189static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
190{
191 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
192 int ret;
193
194 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
195 struct iwl_calib_chain_noise_reset_cmd cmd;
196 memset(&cmd, 0, sizeof(cmd));
197
198 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
199 cmd.hdr.first_group = 0;
200 cmd.hdr.groups_num = 1;
201 cmd.hdr.data_valid = 1;
202 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
203 sizeof(cmd), &cmd);
204 if (ret)
205 IWL_ERR(priv,
206 "Could not send REPLY_PHY_CALIBRATION_CMD\n");
207 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
208 IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
209 }
210}
211
212static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
213 __le32 *tx_flags)
214{
215 if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
216 (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
217 *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
218 else
219 *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
220}
221
222/* Calc max signal level (dBm) among 3 possible receivers */
223static int iwlagn_calc_rssi(struct iwl_priv *priv,
224 struct iwl_rx_phy_res *rx_resp)
225{
226 /* data from PHY/DSP regarding signal strength, etc.,
227 * contents are always there, not configurable by host
228 */
229 struct iwl5000_non_cfg_phy *ncphy =
230 (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
231 u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
232 u8 agc;
233
234 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
235 agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
236
237 /* Find max rssi among 3 possible receivers.
238 * These values are measured by the digital signal processor (DSP).
239 * They should stay fairly constant even as the signal strength varies,
240 * if the radio's automatic gain control (AGC) is working right.
241 * AGC value (see below) will provide the "interesting" info.
242 */
243 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
244 rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
245 rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
246 val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
247 rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
248
249 max_rssi = max_t(u32, rssi_a, rssi_b);
250 max_rssi = max_t(u32, max_rssi, rssi_c);
251
252 IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
253 rssi_a, rssi_b, rssi_c, max_rssi, agc);
254
255 /* dBm = max_rssi dB - agc dB - constant.
256 * Higher AGC (higher radio gain) means lower signal. */
257 return max_rssi - agc - IWLAGN_RSSI_OFFSET;
258}
259
260struct iwl_hcmd_ops iwlagn_hcmd = {
261 .rxon_assoc = iwlagn_send_rxon_assoc,
262 .commit_rxon = iwl_commit_rxon,
263 .set_rxon_chain = iwl_set_rxon_chain,
264 .set_tx_ant = iwlagn_send_tx_ant_config,
265 .send_bt_config = iwl_send_bt_config,
266};
267
268struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
269 .get_hcmd_size = iwlagn_get_hcmd_size,
270 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
271 .gain_computation = iwlagn_gain_computation,
272 .chain_noise_reset = iwlagn_chain_noise_reset,
273 .rts_tx_cmd_flag = iwlagn_rts_tx_cmd_flag,
274 .calc_rssi = iwlagn_calc_rssi,
275 .request_scan = iwlagn_request_scan,
276};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
new file mode 100644
index 000000000000..f9a3fbb6338f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -0,0 +1,118 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 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 * Please use this file (iwl-agn-hw.h) only for hardware-related definitions.
65 */
66
67#ifndef __iwl_agn_hw_h__
68#define __iwl_agn_hw_h__
69
70#define IWLAGN_RTC_INST_LOWER_BOUND (0x000000)
71#define IWLAGN_RTC_INST_UPPER_BOUND (0x020000)
72
73#define IWLAGN_RTC_DATA_LOWER_BOUND (0x800000)
74#define IWLAGN_RTC_DATA_UPPER_BOUND (0x80C000)
75
76#define IWLAGN_RTC_INST_SIZE (IWLAGN_RTC_INST_UPPER_BOUND - \
77 IWLAGN_RTC_INST_LOWER_BOUND)
78#define IWLAGN_RTC_DATA_SIZE (IWLAGN_RTC_DATA_UPPER_BOUND - \
79 IWLAGN_RTC_DATA_LOWER_BOUND)
80
81/* RSSI to dBm */
82#define IWLAGN_RSSI_OFFSET 44
83
84/* PCI registers */
85#define PCI_CFG_RETRY_TIMEOUT 0x041
86
87/* PCI register values */
88#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
89#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
90
91#define IWLAGN_DEFAULT_TX_RETRY 15
92
93/* Limit range of txpower output target to be between these values */
94#define IWLAGN_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */
95#define IWLAGN_TX_POWER_TARGET_POWER_MAX (16) /* 16 dBm */
96
97/* EEPROM */
98#define IWLAGN_EEPROM_IMG_SIZE 2048
99
100#define IWLAGN_CMD_FIFO_NUM 7
101#define IWLAGN_NUM_QUEUES 20
102#define IWLAGN_NUM_AMPDU_QUEUES 10
103#define IWLAGN_FIRST_AMPDU_QUEUE 10
104
105/* Fixed (non-configurable) rx data from phy */
106
107/**
108 * struct iwlagn_schedq_bc_tbl scheduler byte count table
109 * base physical address provided by SCD_DRAM_BASE_ADDR
110 * @tfd_offset 0-12 - tx command byte count
111 * 12-16 - station index
112 */
113struct iwlagn_scd_bc_tbl {
114 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
115} __attribute__ ((packed));
116
117
118#endif /* __iwl_agn_hw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
new file mode 100644
index 000000000000..a273e373b7b0
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -0,0 +1,307 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/etherdevice.h>
32#include <linux/sched.h>
33#include <net/mac80211.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-agn.h"
38#include "iwl-helpers.h"
39
40#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
41
42/* Free dram table */
43void iwl_free_isr_ict(struct iwl_priv *priv)
44{
45 if (priv->_agn.ict_tbl_vir) {
46 dma_free_coherent(&priv->pci_dev->dev,
47 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
48 priv->_agn.ict_tbl_vir,
49 priv->_agn.ict_tbl_dma);
50 priv->_agn.ict_tbl_vir = NULL;
51 }
52}
53
54
55/* allocate dram shared table it is a PAGE_SIZE aligned
56 * also reset all data related to ICT table interrupt.
57 */
58int iwl_alloc_isr_ict(struct iwl_priv *priv)
59{
60
61 if (priv->cfg->use_isr_legacy)
62 return 0;
63 /* allocate shrared data table */
64 priv->_agn.ict_tbl_vir =
65 dma_alloc_coherent(&priv->pci_dev->dev,
66 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
67 &priv->_agn.ict_tbl_dma, GFP_KERNEL);
68 if (!priv->_agn.ict_tbl_vir)
69 return -ENOMEM;
70
71 /* align table to PAGE_SIZE boundry */
72 priv->_agn.aligned_ict_tbl_dma = ALIGN(priv->_agn.ict_tbl_dma, PAGE_SIZE);
73
74 IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
75 (unsigned long long)priv->_agn.ict_tbl_dma,
76 (unsigned long long)priv->_agn.aligned_ict_tbl_dma,
77 (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
78
79 priv->_agn.ict_tbl = priv->_agn.ict_tbl_vir +
80 (priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma);
81
82 IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
83 priv->_agn.ict_tbl, priv->_agn.ict_tbl_vir,
84 (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
85
86 /* reset table and index to all 0 */
87 memset(priv->_agn.ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
88 priv->_agn.ict_index = 0;
89
90 /* add periodic RX interrupt */
91 priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
92 return 0;
93}
94
95/* Device is going up inform it about using ICT interrupt table,
96 * also we need to tell the driver to start using ICT interrupt.
97 */
98int iwl_reset_ict(struct iwl_priv *priv)
99{
100 u32 val;
101 unsigned long flags;
102
103 if (!priv->_agn.ict_tbl_vir)
104 return 0;
105
106 spin_lock_irqsave(&priv->lock, flags);
107 iwl_disable_interrupts(priv);
108
109 memset(&priv->_agn.ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
110
111 val = priv->_agn.aligned_ict_tbl_dma >> PAGE_SHIFT;
112
113 val |= CSR_DRAM_INT_TBL_ENABLE;
114 val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
115
116 IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
117 "aligned dma address %Lx\n",
118 val, (unsigned long long)priv->_agn.aligned_ict_tbl_dma);
119
120 iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
121 priv->_agn.use_ict = true;
122 priv->_agn.ict_index = 0;
123 iwl_write32(priv, CSR_INT, priv->inta_mask);
124 iwl_enable_interrupts(priv);
125 spin_unlock_irqrestore(&priv->lock, flags);
126
127 return 0;
128}
129
130/* Device is going down disable ict interrupt usage */
131void iwl_disable_ict(struct iwl_priv *priv)
132{
133 unsigned long flags;
134
135 spin_lock_irqsave(&priv->lock, flags);
136 priv->_agn.use_ict = false;
137 spin_unlock_irqrestore(&priv->lock, flags);
138}
139
140static irqreturn_t iwl_isr(int irq, void *data)
141{
142 struct iwl_priv *priv = data;
143 u32 inta, inta_mask;
144 unsigned long flags;
145#ifdef CONFIG_IWLWIFI_DEBUG
146 u32 inta_fh;
147#endif
148 if (!priv)
149 return IRQ_NONE;
150
151 spin_lock_irqsave(&priv->lock, flags);
152
153 /* Disable (but don't clear!) interrupts here to avoid
154 * back-to-back ISRs and sporadic interrupts from our NIC.
155 * If we have something to service, the tasklet will re-enable ints.
156 * If we *don't* have something, we'll re-enable before leaving here. */
157 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
158 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
159
160 /* Discover which interrupts are active/pending */
161 inta = iwl_read32(priv, CSR_INT);
162
163 /* Ignore interrupt if there's nothing in NIC to service.
164 * This may be due to IRQ shared with another device,
165 * or due to sporadic interrupts thrown from our NIC. */
166 if (!inta) {
167 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
168 goto none;
169 }
170
171 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
172 /* Hardware disappeared. It might have already raised
173 * an interrupt */
174 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
175 goto unplugged;
176 }
177
178#ifdef CONFIG_IWLWIFI_DEBUG
179 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
180 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
181 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
182 "fh 0x%08x\n", inta, inta_mask, inta_fh);
183 }
184#endif
185
186 priv->_agn.inta |= inta;
187 /* iwl_irq_tasklet() will service interrupts and re-enable them */
188 if (likely(inta))
189 tasklet_schedule(&priv->irq_tasklet);
190 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
191 iwl_enable_interrupts(priv);
192
193 unplugged:
194 spin_unlock_irqrestore(&priv->lock, flags);
195 return IRQ_HANDLED;
196
197 none:
198 /* re-enable interrupts here since we don't have anything to service. */
199 /* only Re-enable if diabled by irq and no schedules tasklet. */
200 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
201 iwl_enable_interrupts(priv);
202
203 spin_unlock_irqrestore(&priv->lock, flags);
204 return IRQ_NONE;
205}
206
207/* interrupt handler using ict table, with this interrupt driver will
208 * stop using INTA register to get device's interrupt, reading this register
209 * is expensive, device will write interrupts in ICT dram table, increment
210 * index then will fire interrupt to driver, driver will OR all ICT table
211 * entries from current index up to table entry with 0 value. the result is
212 * the interrupt we need to service, driver will set the entries back to 0 and
213 * set index.
214 */
215irqreturn_t iwl_isr_ict(int irq, void *data)
216{
217 struct iwl_priv *priv = data;
218 u32 inta, inta_mask;
219 u32 val = 0;
220 unsigned long flags;
221
222 if (!priv)
223 return IRQ_NONE;
224
225 /* dram interrupt table not set yet,
226 * use legacy interrupt.
227 */
228 if (!priv->_agn.use_ict)
229 return iwl_isr(irq, data);
230
231 spin_lock_irqsave(&priv->lock, flags);
232
233 /* Disable (but don't clear!) interrupts here to avoid
234 * back-to-back ISRs and sporadic interrupts from our NIC.
235 * If we have something to service, the tasklet will re-enable ints.
236 * If we *don't* have something, we'll re-enable before leaving here.
237 */
238 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
239 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
240
241
242 /* Ignore interrupt if there's nothing in NIC to service.
243 * This may be due to IRQ shared with another device,
244 * or due to sporadic interrupts thrown from our NIC. */
245 if (!priv->_agn.ict_tbl[priv->_agn.ict_index]) {
246 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
247 goto none;
248 }
249
250 /* read all entries that not 0 start with ict_index */
251 while (priv->_agn.ict_tbl[priv->_agn.ict_index]) {
252
253 val |= le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]);
254 IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
255 priv->_agn.ict_index,
256 le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]));
257 priv->_agn.ict_tbl[priv->_agn.ict_index] = 0;
258 priv->_agn.ict_index = iwl_queue_inc_wrap(priv->_agn.ict_index,
259 ICT_COUNT);
260
261 }
262
263 /* We should not get this value, just ignore it. */
264 if (val == 0xffffffff)
265 val = 0;
266
267 /*
268 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
269 * (bit 15 before shifting it to 31) to clear when using interrupt
270 * coalescing. fortunately, bits 18 and 19 stay set when this happens
271 * so we use them to decide on the real state of the Rx bit.
272 * In order words, bit 15 is set if bit 18 or bit 19 are set.
273 */
274 if (val & 0xC0000)
275 val |= 0x8000;
276
277 inta = (0xff & val) | ((0xff00 & val) << 16);
278 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
279 inta, inta_mask, val);
280
281 inta &= priv->inta_mask;
282 priv->_agn.inta |= inta;
283
284 /* iwl_irq_tasklet() will service interrupts and re-enable them */
285 if (likely(inta))
286 tasklet_schedule(&priv->irq_tasklet);
287 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) {
288 /* Allow interrupt if was disabled by this handler and
289 * no tasklet was schedules, We should not enable interrupt,
290 * tasklet will enable it.
291 */
292 iwl_enable_interrupts(priv);
293 }
294
295 spin_unlock_irqrestore(&priv->lock, flags);
296 return IRQ_HANDLED;
297
298 none:
299 /* re-enable interrupts here since we don't have anything to service.
300 * only Re-enable if disabled by irq.
301 */
302 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
303 iwl_enable_interrupts(priv);
304
305 spin_unlock_irqrestore(&priv->lock, flags);
306 return IRQ_NONE;
307}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
new file mode 100644
index 000000000000..1004cfc403b1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -0,0 +1,1530 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29#include <linux/etherdevice.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h"
40#include "iwl-agn.h"
41#include "iwl-sta.h"
42
43static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
44{
45 return le32_to_cpup((__le32 *)&tx_resp->status +
46 tx_resp->frame_count) & MAX_SN;
47}
48
49static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
50 struct iwl_ht_agg *agg,
51 struct iwl5000_tx_resp *tx_resp,
52 int txq_id, u16 start_idx)
53{
54 u16 status;
55 struct agg_tx_status *frame_status = &tx_resp->status;
56 struct ieee80211_tx_info *info = NULL;
57 struct ieee80211_hdr *hdr = NULL;
58 u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
59 int i, sh, idx;
60 u16 seq;
61
62 if (agg->wait_for_ba)
63 IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
64
65 agg->frame_count = tx_resp->frame_count;
66 agg->start_idx = start_idx;
67 agg->rate_n_flags = rate_n_flags;
68 agg->bitmap = 0;
69
70 /* # frames attempted by Tx command */
71 if (agg->frame_count == 1) {
72 /* Only one frame was attempted; no block-ack will arrive */
73 status = le16_to_cpu(frame_status[0].status);
74 idx = start_idx;
75
76 /* FIXME: code repetition */
77 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
78 agg->frame_count, agg->start_idx, idx);
79
80 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
81 info->status.rates[0].count = tx_resp->failure_frame + 1;
82 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
83 info->flags |= iwl_tx_status_to_mac80211(status);
84 iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
85
86 /* FIXME: code repetition end */
87
88 IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
89 status & 0xff, tx_resp->failure_frame);
90 IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
91
92 agg->wait_for_ba = 0;
93 } else {
94 /* Two or more frames were attempted; expect block-ack */
95 u64 bitmap = 0;
96 int start = agg->start_idx;
97
98 /* Construct bit-map of pending frames within Tx window */
99 for (i = 0; i < agg->frame_count; i++) {
100 u16 sc;
101 status = le16_to_cpu(frame_status[i].status);
102 seq = le16_to_cpu(frame_status[i].sequence);
103 idx = SEQ_TO_INDEX(seq);
104 txq_id = SEQ_TO_QUEUE(seq);
105
106 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
107 AGG_TX_STATE_ABORT_MSK))
108 continue;
109
110 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
111 agg->frame_count, txq_id, idx);
112
113 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
114 if (!hdr) {
115 IWL_ERR(priv,
116 "BUG_ON idx doesn't point to valid skb"
117 " idx=%d, txq_id=%d\n", idx, txq_id);
118 return -1;
119 }
120
121 sc = le16_to_cpu(hdr->seq_ctrl);
122 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
123 IWL_ERR(priv,
124 "BUG_ON idx doesn't match seq control"
125 " idx=%d, seq_idx=%d, seq=%d\n",
126 idx, SEQ_TO_SN(sc),
127 hdr->seq_ctrl);
128 return -1;
129 }
130
131 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
132 i, idx, SEQ_TO_SN(sc));
133
134 sh = idx - start;
135 if (sh > 64) {
136 sh = (start - idx) + 0xff;
137 bitmap = bitmap << sh;
138 sh = 0;
139 start = idx;
140 } else if (sh < -64)
141 sh = 0xff - (start - idx);
142 else if (sh < 0) {
143 sh = start - idx;
144 start = idx;
145 bitmap = bitmap << sh;
146 sh = 0;
147 }
148 bitmap |= 1ULL << sh;
149 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
150 start, (unsigned long long)bitmap);
151 }
152
153 agg->bitmap = bitmap;
154 agg->start_idx = start;
155 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
156 agg->frame_count, agg->start_idx,
157 (unsigned long long)agg->bitmap);
158
159 if (bitmap)
160 agg->wait_for_ba = 1;
161 }
162 return 0;
163}
164
165void iwl_check_abort_status(struct iwl_priv *priv,
166 u8 frame_count, u32 status)
167{
168 if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
169 IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n");
170 }
171}
172
173static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
174 struct iwl_rx_mem_buffer *rxb)
175{
176 struct iwl_rx_packet *pkt = rxb_addr(rxb);
177 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
178 int txq_id = SEQ_TO_QUEUE(sequence);
179 int index = SEQ_TO_INDEX(sequence);
180 struct iwl_tx_queue *txq = &priv->txq[txq_id];
181 struct ieee80211_tx_info *info;
182 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
183 u32 status = le16_to_cpu(tx_resp->status.status);
184 int tid;
185 int sta_id;
186 int freed;
187
188 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
189 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
190 "is out of range [0-%d] %d %d\n", txq_id,
191 index, txq->q.n_bd, txq->q.write_ptr,
192 txq->q.read_ptr);
193 return;
194 }
195
196 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
197 memset(&info->status, 0, sizeof(info->status));
198
199 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
200 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
201
202 if (txq->sched_retry) {
203 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
204 struct iwl_ht_agg *agg = NULL;
205
206 agg = &priv->stations[sta_id].tid[tid].agg;
207
208 iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
209
210 /* check if BAR is needed */
211 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
212 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
213
214 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
215 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
216 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
217 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
218 scd_ssn , index, txq_id, txq->swq_id);
219
220 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
221 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
222
223 if (priv->mac80211_registered &&
224 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
225 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
226 if (agg->state == IWL_AGG_OFF)
227 iwl_wake_queue(priv, txq_id);
228 else
229 iwl_wake_queue(priv, txq->swq_id);
230 }
231 }
232 } else {
233 BUG_ON(txq_id != txq->swq_id);
234
235 info->status.rates[0].count = tx_resp->failure_frame + 1;
236 info->flags |= iwl_tx_status_to_mac80211(status);
237 iwlagn_hwrate_to_tx_control(priv,
238 le32_to_cpu(tx_resp->rate_n_flags),
239 info);
240
241 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
242 "0x%x retries %d\n",
243 txq_id,
244 iwl_get_tx_fail_reason(status), status,
245 le32_to_cpu(tx_resp->rate_n_flags),
246 tx_resp->failure_frame);
247
248 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
249 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
250
251 if (priv->mac80211_registered &&
252 (iwl_queue_space(&txq->q) > txq->q.low_mark))
253 iwl_wake_queue(priv, txq_id);
254 }
255
256 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
257
258 iwl_check_abort_status(priv, tx_resp->frame_count, status);
259}
260
261void iwlagn_rx_handler_setup(struct iwl_priv *priv)
262{
263 /* init calibration handlers */
264 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
265 iwlagn_rx_calib_result;
266 priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
267 iwlagn_rx_calib_complete;
268 priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
269}
270
271void iwlagn_setup_deferred_work(struct iwl_priv *priv)
272{
273 /* in agn, the tx power calibration is done in uCode */
274 priv->disable_tx_power_cal = 1;
275}
276
277int iwlagn_hw_valid_rtc_data_addr(u32 addr)
278{
279 return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) &&
280 (addr < IWLAGN_RTC_DATA_UPPER_BOUND);
281}
282
283int iwlagn_send_tx_power(struct iwl_priv *priv)
284{
285 struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
286 u8 tx_ant_cfg_cmd;
287
288 /* half dBm need to multiply */
289 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
290
291 if (priv->tx_power_lmt_in_half_dbm &&
292 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
293 /*
294 * For the newer devices which using enhanced/extend tx power
295 * table in EEPROM, the format is in half dBm. driver need to
296 * convert to dBm format before report to mac80211.
297 * By doing so, there is a possibility of 1/2 dBm resolution
298 * lost. driver will perform "round-up" operation before
299 * reporting, but it will cause 1/2 dBm tx power over the
300 * regulatory limit. Perform the checking here, if the
301 * "tx_power_user_lmt" is higher than EEPROM value (in
302 * half-dBm format), lower the tx power based on EEPROM
303 */
304 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
305 }
306 tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
307 tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
308
309 if (IWL_UCODE_API(priv->ucode_ver) == 1)
310 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
311 else
312 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
313
314 return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
315 sizeof(tx_power_cmd), &tx_power_cmd,
316 NULL);
317}
318
319void iwlagn_temperature(struct iwl_priv *priv)
320{
321 /* store temperature from statistics (in Celsius) */
322 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
323 iwl_tt_handler(priv);
324}
325
326u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
327{
328 struct iwl_eeprom_calib_hdr {
329 u8 version;
330 u8 pa_type;
331 u16 voltage;
332 } *hdr;
333
334 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
335 EEPROM_CALIB_ALL);
336 return hdr->version;
337
338}
339
340/*
341 * EEPROM
342 */
343static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
344{
345 u16 offset = 0;
346
347 if ((address & INDIRECT_ADDRESS) == 0)
348 return address;
349
350 switch (address & INDIRECT_TYPE_MSK) {
351 case INDIRECT_HOST:
352 offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
353 break;
354 case INDIRECT_GENERAL:
355 offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
356 break;
357 case INDIRECT_REGULATORY:
358 offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
359 break;
360 case INDIRECT_CALIBRATION:
361 offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
362 break;
363 case INDIRECT_PROCESS_ADJST:
364 offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
365 break;
366 case INDIRECT_OTHERS:
367 offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
368 break;
369 default:
370 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
371 address & INDIRECT_TYPE_MSK);
372 break;
373 }
374
375 /* translate the offset from words to byte */
376 return (address & ADDRESS_MSK) + (offset << 1);
377}
378
379const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
380 size_t offset)
381{
382 u32 address = eeprom_indirect_address(priv, offset);
383 BUG_ON(address >= priv->cfg->eeprom_size);
384 return &priv->eeprom[address];
385}
386
387struct iwl_mod_params iwlagn_mod_params = {
388 .amsdu_size_8K = 1,
389 .restart_fw = 1,
390 /* the rest are 0 by default */
391};
392
393void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
394{
395 unsigned long flags;
396 int i;
397 spin_lock_irqsave(&rxq->lock, flags);
398 INIT_LIST_HEAD(&rxq->rx_free);
399 INIT_LIST_HEAD(&rxq->rx_used);
400 /* Fill the rx_used queue with _all_ of the Rx buffers */
401 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
402 /* In the reset function, these buffers may have been allocated
403 * to an SKB, so we need to unmap and free potential storage */
404 if (rxq->pool[i].page != NULL) {
405 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
406 PAGE_SIZE << priv->hw_params.rx_page_order,
407 PCI_DMA_FROMDEVICE);
408 __iwl_free_pages(priv, rxq->pool[i].page);
409 rxq->pool[i].page = NULL;
410 }
411 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
412 }
413
414 for (i = 0; i < RX_QUEUE_SIZE; i++)
415 rxq->queue[i] = NULL;
416
417 /* Set us so that we have processed and used all buffers, but have
418 * not restocked the Rx queue with fresh buffers */
419 rxq->read = rxq->write = 0;
420 rxq->write_actual = 0;
421 rxq->free_count = 0;
422 spin_unlock_irqrestore(&rxq->lock, flags);
423}
424
425int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
426{
427 u32 rb_size;
428 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
429 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
430
431 if (!priv->cfg->use_isr_legacy)
432 rb_timeout = RX_RB_TIMEOUT;
433
434 if (priv->cfg->mod_params->amsdu_size_8K)
435 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
436 else
437 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
438
439 /* Stop Rx DMA */
440 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
441
442 /* Reset driver's Rx queue write index */
443 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
444
445 /* Tell device where to find RBD circular buffer in DRAM */
446 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
447 (u32)(rxq->dma_addr >> 8));
448
449 /* Tell device where in DRAM to update its Rx status */
450 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
451 rxq->rb_stts_dma >> 4);
452
453 /* Enable Rx DMA
454 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
455 * the credit mechanism in 5000 HW RX FIFO
456 * Direct rx interrupts to hosts
457 * Rx buffer size 4 or 8k
458 * RB timeout 0x10
459 * 256 RBDs
460 */
461 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
462 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
463 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
464 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
465 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
466 rb_size|
467 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
468 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
469
470 /* Set interrupt coalescing timer to default (2048 usecs) */
471 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
472
473 return 0;
474}
475
476int iwlagn_hw_nic_init(struct iwl_priv *priv)
477{
478 unsigned long flags;
479 struct iwl_rx_queue *rxq = &priv->rxq;
480 int ret;
481
482 /* nic_init */
483 spin_lock_irqsave(&priv->lock, flags);
484 priv->cfg->ops->lib->apm_ops.init(priv);
485
486 /* Set interrupt coalescing calibration timer to default (512 usecs) */
487 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
488
489 spin_unlock_irqrestore(&priv->lock, flags);
490
491 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
492
493 priv->cfg->ops->lib->apm_ops.config(priv);
494
495 /* Allocate the RX queue, or reset if it is already allocated */
496 if (!rxq->bd) {
497 ret = iwl_rx_queue_alloc(priv);
498 if (ret) {
499 IWL_ERR(priv, "Unable to initialize Rx queue\n");
500 return -ENOMEM;
501 }
502 } else
503 iwlagn_rx_queue_reset(priv, rxq);
504
505 iwlagn_rx_replenish(priv);
506
507 iwlagn_rx_init(priv, rxq);
508
509 spin_lock_irqsave(&priv->lock, flags);
510
511 rxq->need_update = 1;
512 iwl_rx_queue_update_write_ptr(priv, rxq);
513
514 spin_unlock_irqrestore(&priv->lock, flags);
515
516 /* Allocate or reset and init all Tx and Command queues */
517 if (!priv->txq) {
518 ret = iwlagn_txq_ctx_alloc(priv);
519 if (ret)
520 return ret;
521 } else
522 iwlagn_txq_ctx_reset(priv);
523
524 set_bit(STATUS_INIT, &priv->status);
525
526 return 0;
527}
528
529/**
530 * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
531 */
532static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv,
533 dma_addr_t dma_addr)
534{
535 return cpu_to_le32((u32)(dma_addr >> 8));
536}
537
538/**
539 * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool
540 *
541 * If there are slots in the RX queue that need to be restocked,
542 * and we have free pre-allocated buffers, fill the ranks as much
543 * as we can, pulling from rx_free.
544 *
545 * This moves the 'write' index forward to catch up with 'processed', and
546 * also updates the memory address in the firmware to reference the new
547 * target buffer.
548 */
549void iwlagn_rx_queue_restock(struct iwl_priv *priv)
550{
551 struct iwl_rx_queue *rxq = &priv->rxq;
552 struct list_head *element;
553 struct iwl_rx_mem_buffer *rxb;
554 unsigned long flags;
555
556 spin_lock_irqsave(&rxq->lock, flags);
557 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
558 /* The overwritten rxb must be a used one */
559 rxb = rxq->queue[rxq->write];
560 BUG_ON(rxb && rxb->page);
561
562 /* Get next free Rx buffer, remove from free list */
563 element = rxq->rx_free.next;
564 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
565 list_del(element);
566
567 /* Point to Rx buffer via next RBD in circular buffer */
568 rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv,
569 rxb->page_dma);
570 rxq->queue[rxq->write] = rxb;
571 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
572 rxq->free_count--;
573 }
574 spin_unlock_irqrestore(&rxq->lock, flags);
575 /* If the pre-allocated buffer pool is dropping low, schedule to
576 * refill it */
577 if (rxq->free_count <= RX_LOW_WATERMARK)
578 queue_work(priv->workqueue, &priv->rx_replenish);
579
580
581 /* If we've added more space for the firmware to place data, tell it.
582 * Increment device's write pointer in multiples of 8. */
583 if (rxq->write_actual != (rxq->write & ~0x7)) {
584 spin_lock_irqsave(&rxq->lock, flags);
585 rxq->need_update = 1;
586 spin_unlock_irqrestore(&rxq->lock, flags);
587 iwl_rx_queue_update_write_ptr(priv, rxq);
588 }
589}
590
591/**
592 * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free
593 *
594 * When moving to rx_free an SKB is allocated for the slot.
595 *
596 * Also restock the Rx queue via iwl_rx_queue_restock.
597 * This is called as a scheduled work item (except for during initialization)
598 */
599void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
600{
601 struct iwl_rx_queue *rxq = &priv->rxq;
602 struct list_head *element;
603 struct iwl_rx_mem_buffer *rxb;
604 struct page *page;
605 unsigned long flags;
606 gfp_t gfp_mask = priority;
607
608 while (1) {
609 spin_lock_irqsave(&rxq->lock, flags);
610 if (list_empty(&rxq->rx_used)) {
611 spin_unlock_irqrestore(&rxq->lock, flags);
612 return;
613 }
614 spin_unlock_irqrestore(&rxq->lock, flags);
615
616 if (rxq->free_count > RX_LOW_WATERMARK)
617 gfp_mask |= __GFP_NOWARN;
618
619 if (priv->hw_params.rx_page_order > 0)
620 gfp_mask |= __GFP_COMP;
621
622 /* Alloc a new receive buffer */
623 page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
624 if (!page) {
625 if (net_ratelimit())
626 IWL_DEBUG_INFO(priv, "alloc_pages failed, "
627 "order: %d\n",
628 priv->hw_params.rx_page_order);
629
630 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
631 net_ratelimit())
632 IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
633 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
634 rxq->free_count);
635 /* We don't reschedule replenish work here -- we will
636 * call the restock method and if it still needs
637 * more buffers it will schedule replenish */
638 return;
639 }
640
641 spin_lock_irqsave(&rxq->lock, flags);
642
643 if (list_empty(&rxq->rx_used)) {
644 spin_unlock_irqrestore(&rxq->lock, flags);
645 __free_pages(page, priv->hw_params.rx_page_order);
646 return;
647 }
648 element = rxq->rx_used.next;
649 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
650 list_del(element);
651
652 spin_unlock_irqrestore(&rxq->lock, flags);
653
654 BUG_ON(rxb->page);
655 rxb->page = page;
656 /* Get physical address of the RB */
657 rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
658 PAGE_SIZE << priv->hw_params.rx_page_order,
659 PCI_DMA_FROMDEVICE);
660 /* dma address must be no more than 36 bits */
661 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
662 /* and also 256 byte aligned! */
663 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
664
665 spin_lock_irqsave(&rxq->lock, flags);
666
667 list_add_tail(&rxb->list, &rxq->rx_free);
668 rxq->free_count++;
669 priv->alloc_rxb_page++;
670
671 spin_unlock_irqrestore(&rxq->lock, flags);
672 }
673}
674
675void iwlagn_rx_replenish(struct iwl_priv *priv)
676{
677 unsigned long flags;
678
679 iwlagn_rx_allocate(priv, GFP_KERNEL);
680
681 spin_lock_irqsave(&priv->lock, flags);
682 iwlagn_rx_queue_restock(priv);
683 spin_unlock_irqrestore(&priv->lock, flags);
684}
685
686void iwlagn_rx_replenish_now(struct iwl_priv *priv)
687{
688 iwlagn_rx_allocate(priv, GFP_ATOMIC);
689
690 iwlagn_rx_queue_restock(priv);
691}
692
693/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
694 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
695 * This free routine walks the list of POOL entries and if SKB is set to
696 * non NULL it is unmapped and freed
697 */
698void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
699{
700 int i;
701 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
702 if (rxq->pool[i].page != NULL) {
703 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
704 PAGE_SIZE << priv->hw_params.rx_page_order,
705 PCI_DMA_FROMDEVICE);
706 __iwl_free_pages(priv, rxq->pool[i].page);
707 rxq->pool[i].page = NULL;
708 }
709 }
710
711 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
712 rxq->dma_addr);
713 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
714 rxq->rb_stts, rxq->rb_stts_dma);
715 rxq->bd = NULL;
716 rxq->rb_stts = NULL;
717}
718
719int iwlagn_rxq_stop(struct iwl_priv *priv)
720{
721
722 /* stop Rx DMA */
723 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
724 iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
725 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
726
727 return 0;
728}
729
730int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
731{
732 int idx = 0;
733 int band_offset = 0;
734
735 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
736 if (rate_n_flags & RATE_MCS_HT_MSK) {
737 idx = (rate_n_flags & 0xff);
738 return idx;
739 /* Legacy rate format, search for match in table */
740 } else {
741 if (band == IEEE80211_BAND_5GHZ)
742 band_offset = IWL_FIRST_OFDM_RATE;
743 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
744 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
745 return idx - band_offset;
746 }
747
748 return -1;
749}
750
751/* Calc max signal level (dBm) among 3 possible receivers */
752static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
753 struct iwl_rx_phy_res *rx_resp)
754{
755 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
756}
757
758#ifdef CONFIG_IWLWIFI_DEBUG
759/**
760 * iwlagn_dbg_report_frame - dump frame to syslog during debug sessions
761 *
762 * You may hack this function to show different aspects of received frames,
763 * including selective frame dumps.
764 * group100 parameter selects whether to show 1 out of 100 good data frames.
765 * All beacon and probe response frames are printed.
766 */
767static void iwlagn_dbg_report_frame(struct iwl_priv *priv,
768 struct iwl_rx_phy_res *phy_res, u16 length,
769 struct ieee80211_hdr *header, int group100)
770{
771 u32 to_us;
772 u32 print_summary = 0;
773 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
774 u32 hundred = 0;
775 u32 dataframe = 0;
776 __le16 fc;
777 u16 seq_ctl;
778 u16 channel;
779 u16 phy_flags;
780 u32 rate_n_flags;
781 u32 tsf_low;
782 int rssi;
783
784 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
785 return;
786
787 /* MAC header */
788 fc = header->frame_control;
789 seq_ctl = le16_to_cpu(header->seq_ctrl);
790
791 /* metadata */
792 channel = le16_to_cpu(phy_res->channel);
793 phy_flags = le16_to_cpu(phy_res->phy_flags);
794 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
795
796 /* signal statistics */
797 rssi = iwlagn_calc_rssi(priv, phy_res);
798 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
799
800 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
801
802 /* if data frame is to us and all is good,
803 * (optionally) print summary for only 1 out of every 100 */
804 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
805 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
806 dataframe = 1;
807 if (!group100)
808 print_summary = 1; /* print each frame */
809 else if (priv->framecnt_to_us < 100) {
810 priv->framecnt_to_us++;
811 print_summary = 0;
812 } else {
813 priv->framecnt_to_us = 0;
814 print_summary = 1;
815 hundred = 1;
816 }
817 } else {
818 /* print summary for all other frames */
819 print_summary = 1;
820 }
821
822 if (print_summary) {
823 char *title;
824 int rate_idx;
825 u32 bitrate;
826
827 if (hundred)
828 title = "100Frames";
829 else if (ieee80211_has_retry(fc))
830 title = "Retry";
831 else if (ieee80211_is_assoc_resp(fc))
832 title = "AscRsp";
833 else if (ieee80211_is_reassoc_resp(fc))
834 title = "RasRsp";
835 else if (ieee80211_is_probe_resp(fc)) {
836 title = "PrbRsp";
837 print_dump = 1; /* dump frame contents */
838 } else if (ieee80211_is_beacon(fc)) {
839 title = "Beacon";
840 print_dump = 1; /* dump frame contents */
841 } else if (ieee80211_is_atim(fc))
842 title = "ATIM";
843 else if (ieee80211_is_auth(fc))
844 title = "Auth";
845 else if (ieee80211_is_deauth(fc))
846 title = "DeAuth";
847 else if (ieee80211_is_disassoc(fc))
848 title = "DisAssoc";
849 else
850 title = "Frame";
851
852 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
853 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
854 bitrate = 0;
855 WARN_ON_ONCE(1);
856 } else {
857 bitrate = iwl_rates[rate_idx].ieee / 2;
858 }
859
860 /* print frame summary.
861 * MAC addresses show just the last byte (for brevity),
862 * but you can hack it to show more, if you'd like to. */
863 if (dataframe)
864 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
865 "len=%u, rssi=%d, chnl=%d, rate=%u,\n",
866 title, le16_to_cpu(fc), header->addr1[5],
867 length, rssi, channel, bitrate);
868 else {
869 /* src/dst addresses assume managed mode */
870 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
871 "len=%u, rssi=%d, tim=%lu usec, "
872 "phy=0x%02x, chnl=%d\n",
873 title, le16_to_cpu(fc), header->addr1[5],
874 header->addr3[5], length, rssi,
875 tsf_low - priv->scan_start_tsf,
876 phy_flags, channel);
877 }
878 }
879 if (print_dump)
880 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
881}
882#endif
883
884static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
885{
886 u32 decrypt_out = 0;
887
888 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
889 RX_RES_STATUS_STATION_FOUND)
890 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
891 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
892
893 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
894
895 /* packet was not encrypted */
896 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
897 RX_RES_STATUS_SEC_TYPE_NONE)
898 return decrypt_out;
899
900 /* packet was encrypted with unknown alg */
901 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
902 RX_RES_STATUS_SEC_TYPE_ERR)
903 return decrypt_out;
904
905 /* decryption was not done in HW */
906 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
907 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
908 return decrypt_out;
909
910 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
911
912 case RX_RES_STATUS_SEC_TYPE_CCMP:
913 /* alg is CCM: check MIC only */
914 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
915 /* Bad MIC */
916 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
917 else
918 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
919
920 break;
921
922 case RX_RES_STATUS_SEC_TYPE_TKIP:
923 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
924 /* Bad TTAK */
925 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
926 break;
927 }
928 /* fall through if TTAK OK */
929 default:
930 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
931 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
932 else
933 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
934 break;
935 }
936
937 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
938 decrypt_in, decrypt_out);
939
940 return decrypt_out;
941}
942
943static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
944 struct ieee80211_hdr *hdr,
945 u16 len,
946 u32 ampdu_status,
947 struct iwl_rx_mem_buffer *rxb,
948 struct ieee80211_rx_status *stats)
949{
950 struct sk_buff *skb;
951 __le16 fc = hdr->frame_control;
952
953 /* We only process data packets if the interface is open */
954 if (unlikely(!priv->is_open)) {
955 IWL_DEBUG_DROP_LIMIT(priv,
956 "Dropping packet while interface is not open.\n");
957 return;
958 }
959
960 /* In case of HW accelerated crypto and bad decryption, drop */
961 if (!priv->cfg->mod_params->sw_crypto &&
962 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
963 return;
964
965 skb = dev_alloc_skb(128);
966 if (!skb) {
967 IWL_ERR(priv, "dev_alloc_skb failed\n");
968 return;
969 }
970
971 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
972
973 iwl_update_stats(priv, false, fc, len);
974 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
975
976 ieee80211_rx(priv->hw, skb);
977 priv->alloc_rxb_page--;
978 rxb->page = NULL;
979}
980
981/* Called for REPLY_RX (legacy ABG frames), or
982 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
983void iwlagn_rx_reply_rx(struct iwl_priv *priv,
984 struct iwl_rx_mem_buffer *rxb)
985{
986 struct ieee80211_hdr *header;
987 struct ieee80211_rx_status rx_status;
988 struct iwl_rx_packet *pkt = rxb_addr(rxb);
989 struct iwl_rx_phy_res *phy_res;
990 __le32 rx_pkt_status;
991 struct iwl4965_rx_mpdu_res_start *amsdu;
992 u32 len;
993 u32 ampdu_status;
994 u32 rate_n_flags;
995
996 /**
997 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
998 * REPLY_RX: physical layer info is in this buffer
999 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1000 * command and cached in priv->last_phy_res
1001 *
1002 * Here we set up local variables depending on which command is
1003 * received.
1004 */
1005 if (pkt->hdr.cmd == REPLY_RX) {
1006 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1007 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1008 + phy_res->cfg_phy_cnt);
1009
1010 len = le16_to_cpu(phy_res->byte_count);
1011 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1012 phy_res->cfg_phy_cnt + len);
1013 ampdu_status = le32_to_cpu(rx_pkt_status);
1014 } else {
1015 if (!priv->_agn.last_phy_res_valid) {
1016 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1017 return;
1018 }
1019 phy_res = &priv->_agn.last_phy_res;
1020 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1021 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1022 len = le16_to_cpu(amsdu->byte_count);
1023 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1024 ampdu_status = iwlagn_translate_rx_status(priv,
1025 le32_to_cpu(rx_pkt_status));
1026 }
1027
1028 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1029 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1030 phy_res->cfg_phy_cnt);
1031 return;
1032 }
1033
1034 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1035 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1036 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1037 le32_to_cpu(rx_pkt_status));
1038 return;
1039 }
1040
1041 /* This will be used in several places later */
1042 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1043
1044 /* rx_status carries information about the packet to mac80211 */
1045 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1046 rx_status.freq =
1047 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
1048 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1049 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1050 rx_status.rate_idx =
1051 iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1052 rx_status.flag = 0;
1053
1054 /* TSF isn't reliable. In order to allow smooth user experience,
1055 * this W/A doesn't propagate it to the mac80211 */
1056 /*rx_status.flag |= RX_FLAG_TSFT;*/
1057
1058 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1059
1060 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1061 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1062
1063#ifdef CONFIG_IWLWIFI_DEBUG
1064 /* Set "1" to report good data frames in groups of 100 */
1065 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1066 iwlagn_dbg_report_frame(priv, phy_res, len, header, 1);
1067#endif
1068 iwl_dbg_log_rx_data_frame(priv, len, header);
1069 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1070 rx_status.signal, (unsigned long long)rx_status.mactime);
1071
1072 /*
1073 * "antenna number"
1074 *
1075 * It seems that the antenna field in the phy flags value
1076 * is actually a bit field. This is undefined by radiotap,
1077 * it wants an actual antenna number but I always get "7"
1078 * for most legacy frames I receive indicating that the
1079 * same frame was received on all three RX chains.
1080 *
1081 * I think this field should be removed in favor of a
1082 * new 802.11n radiotap field "RX chains" that is defined
1083 * as a bitmask.
1084 */
1085 rx_status.antenna =
1086 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1087 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1088
1089 /* set the preamble flag if appropriate */
1090 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1091 rx_status.flag |= RX_FLAG_SHORTPRE;
1092
1093 /* Set up the HT phy flags */
1094 if (rate_n_flags & RATE_MCS_HT_MSK)
1095 rx_status.flag |= RX_FLAG_HT;
1096 if (rate_n_flags & RATE_MCS_HT40_MSK)
1097 rx_status.flag |= RX_FLAG_40MHZ;
1098 if (rate_n_flags & RATE_MCS_SGI_MSK)
1099 rx_status.flag |= RX_FLAG_SHORT_GI;
1100
1101 iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1102 rxb, &rx_status);
1103}
1104
1105/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1106 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1107void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1108 struct iwl_rx_mem_buffer *rxb)
1109{
1110 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1111 priv->_agn.last_phy_res_valid = true;
1112 memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
1113 sizeof(struct iwl_rx_phy_res));
1114}
1115
1116static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1117 struct ieee80211_vif *vif,
1118 enum ieee80211_band band,
1119 struct iwl_scan_channel *scan_ch)
1120{
1121 const struct ieee80211_supported_band *sband;
1122 const struct iwl_channel_info *ch_info;
1123 u16 passive_dwell = 0;
1124 u16 active_dwell = 0;
1125 int i, added = 0;
1126 u16 channel = 0;
1127
1128 sband = iwl_get_hw_mode(priv, band);
1129 if (!sband) {
1130 IWL_ERR(priv, "invalid band\n");
1131 return added;
1132 }
1133
1134 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
1135 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1136
1137 if (passive_dwell <= active_dwell)
1138 passive_dwell = active_dwell + 1;
1139
1140 /* only scan single channel, good enough to reset the RF */
1141 /* pick the first valid not in-use channel */
1142 if (band == IEEE80211_BAND_5GHZ) {
1143 for (i = 14; i < priv->channel_count; i++) {
1144 if (priv->channel_info[i].channel !=
1145 le16_to_cpu(priv->staging_rxon.channel)) {
1146 channel = priv->channel_info[i].channel;
1147 ch_info = iwl_get_channel_info(priv,
1148 band, channel);
1149 if (is_channel_valid(ch_info))
1150 break;
1151 }
1152 }
1153 } else {
1154 for (i = 0; i < 14; i++) {
1155 if (priv->channel_info[i].channel !=
1156 le16_to_cpu(priv->staging_rxon.channel)) {
1157 channel =
1158 priv->channel_info[i].channel;
1159 ch_info = iwl_get_channel_info(priv,
1160 band, channel);
1161 if (is_channel_valid(ch_info))
1162 break;
1163 }
1164 }
1165 }
1166 if (channel) {
1167 scan_ch->channel = cpu_to_le16(channel);
1168 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
1169 scan_ch->active_dwell = cpu_to_le16(active_dwell);
1170 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
1171 /* Set txpower levels to defaults */
1172 scan_ch->dsp_atten = 110;
1173 if (band == IEEE80211_BAND_5GHZ)
1174 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
1175 else
1176 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
1177 added++;
1178 } else
1179 IWL_ERR(priv, "no valid channel found\n");
1180 return added;
1181}
1182
1183static int iwl_get_channels_for_scan(struct iwl_priv *priv,
1184 struct ieee80211_vif *vif,
1185 enum ieee80211_band band,
1186 u8 is_active, u8 n_probes,
1187 struct iwl_scan_channel *scan_ch)
1188{
1189 struct ieee80211_channel *chan;
1190 const struct ieee80211_supported_band *sband;
1191 const struct iwl_channel_info *ch_info;
1192 u16 passive_dwell = 0;
1193 u16 active_dwell = 0;
1194 int added, i;
1195 u16 channel;
1196
1197 sband = iwl_get_hw_mode(priv, band);
1198 if (!sband)
1199 return 0;
1200
1201 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1202 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1203
1204 if (passive_dwell <= active_dwell)
1205 passive_dwell = active_dwell + 1;
1206
1207 for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
1208 chan = priv->scan_request->channels[i];
1209
1210 if (chan->band != band)
1211 continue;
1212
1213 channel = ieee80211_frequency_to_channel(chan->center_freq);
1214 scan_ch->channel = cpu_to_le16(channel);
1215
1216 ch_info = iwl_get_channel_info(priv, band, channel);
1217 if (!is_channel_valid(ch_info)) {
1218 IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
1219 channel);
1220 continue;
1221 }
1222
1223 if (!is_active || is_channel_passive(ch_info) ||
1224 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
1225 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
1226 else
1227 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
1228
1229 if (n_probes)
1230 scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
1231
1232 scan_ch->active_dwell = cpu_to_le16(active_dwell);
1233 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
1234
1235 /* Set txpower levels to defaults */
1236 scan_ch->dsp_atten = 110;
1237
1238 /* NOTE: if we were doing 6Mb OFDM for scans we'd use
1239 * power level:
1240 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
1241 */
1242 if (band == IEEE80211_BAND_5GHZ)
1243 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
1244 else
1245 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
1246
1247 IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
1248 channel, le32_to_cpu(scan_ch->type),
1249 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
1250 "ACTIVE" : "PASSIVE",
1251 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
1252 active_dwell : passive_dwell);
1253
1254 scan_ch++;
1255 added++;
1256 }
1257
1258 IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
1259 return added;
1260}
1261
1262void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1263{
1264 struct iwl_host_cmd cmd = {
1265 .id = REPLY_SCAN_CMD,
1266 .len = sizeof(struct iwl_scan_cmd),
1267 .flags = CMD_SIZE_HUGE,
1268 };
1269 struct iwl_scan_cmd *scan;
1270 struct ieee80211_conf *conf = NULL;
1271 u32 rate_flags = 0;
1272 u16 cmd_len;
1273 u16 rx_chain = 0;
1274 enum ieee80211_band band;
1275 u8 n_probes = 0;
1276 u8 rx_ant = priv->hw_params.valid_rx_ant;
1277 u8 rate;
1278 bool is_active = false;
1279 int chan_mod;
1280 u8 active_chains;
1281
1282 conf = ieee80211_get_hw_conf(priv->hw);
1283
1284 cancel_delayed_work(&priv->scan_check);
1285
1286 if (!iwl_is_ready(priv)) {
1287 IWL_WARN(priv, "request scan called when driver not ready.\n");
1288 goto done;
1289 }
1290
1291 /* Make sure the scan wasn't canceled before this queued work
1292 * was given the chance to run... */
1293 if (!test_bit(STATUS_SCANNING, &priv->status))
1294 goto done;
1295
1296 /* This should never be called or scheduled if there is currently
1297 * a scan active in the hardware. */
1298 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
1299 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
1300 "Ignoring second request.\n");
1301 goto done;
1302 }
1303
1304 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1305 IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
1306 goto done;
1307 }
1308
1309 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
1310 IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
1311 goto done;
1312 }
1313
1314 if (iwl_is_rfkill(priv)) {
1315 IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
1316 goto done;
1317 }
1318
1319 if (!test_bit(STATUS_READY, &priv->status)) {
1320 IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
1321 goto done;
1322 }
1323
1324 if (!priv->scan_cmd) {
1325 priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
1326 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
1327 if (!priv->scan_cmd) {
1328 IWL_DEBUG_SCAN(priv,
1329 "fail to allocate memory for scan\n");
1330 goto done;
1331 }
1332 }
1333 scan = priv->scan_cmd;
1334 memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
1335
1336 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
1337 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
1338
1339 if (iwl_is_associated(priv)) {
1340 u16 interval = 0;
1341 u32 extra;
1342 u32 suspend_time = 100;
1343 u32 scan_suspend_time = 100;
1344 unsigned long flags;
1345
1346 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
1347 spin_lock_irqsave(&priv->lock, flags);
1348 interval = vif ? vif->bss_conf.beacon_int : 0;
1349 spin_unlock_irqrestore(&priv->lock, flags);
1350
1351 scan->suspend_time = 0;
1352 scan->max_out_time = cpu_to_le32(200 * 1024);
1353 if (!interval)
1354 interval = suspend_time;
1355
1356 extra = (suspend_time / interval) << 22;
1357 scan_suspend_time = (extra |
1358 ((suspend_time % interval) * 1024));
1359 scan->suspend_time = cpu_to_le32(scan_suspend_time);
1360 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
1361 scan_suspend_time, interval);
1362 }
1363
1364 if (priv->is_internal_short_scan) {
1365 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
1366 } else if (priv->scan_request->n_ssids) {
1367 int i, p = 0;
1368 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
1369 for (i = 0; i < priv->scan_request->n_ssids; i++) {
1370 /* always does wildcard anyway */
1371 if (!priv->scan_request->ssids[i].ssid_len)
1372 continue;
1373 scan->direct_scan[p].id = WLAN_EID_SSID;
1374 scan->direct_scan[p].len =
1375 priv->scan_request->ssids[i].ssid_len;
1376 memcpy(scan->direct_scan[p].ssid,
1377 priv->scan_request->ssids[i].ssid,
1378 priv->scan_request->ssids[i].ssid_len);
1379 n_probes++;
1380 p++;
1381 }
1382 is_active = true;
1383 } else
1384 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
1385
1386 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
1387 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
1388 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
1389
1390 switch (priv->scan_band) {
1391 case IEEE80211_BAND_2GHZ:
1392 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
1393 chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
1394 >> RXON_FLG_CHANNEL_MODE_POS;
1395 if (chan_mod == CHANNEL_MODE_PURE_40) {
1396 rate = IWL_RATE_6M_PLCP;
1397 } else {
1398 rate = IWL_RATE_1M_PLCP;
1399 rate_flags = RATE_MCS_CCK_MSK;
1400 }
1401 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
1402 break;
1403 case IEEE80211_BAND_5GHZ:
1404 rate = IWL_RATE_6M_PLCP;
1405 /*
1406 * If active scanning is requested but a certain channel is
1407 * marked passive, we can do active scanning if we detect
1408 * transmissions.
1409 *
1410 * There is an issue with some firmware versions that triggers
1411 * a sysassert on a "good CRC threshold" of zero (== disabled),
1412 * on a radar channel even though this means that we should NOT
1413 * send probes.
1414 *
1415 * The "good CRC threshold" is the number of frames that we
1416 * need to receive during our dwell time on a channel before
1417 * sending out probes -- setting this to a huge value will
1418 * mean we never reach it, but at the same time work around
1419 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
1420 * here instead of IWL_GOOD_CRC_TH_DISABLED.
1421 */
1422 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
1423 IWL_GOOD_CRC_TH_NEVER;
1424 break;
1425 default:
1426 IWL_WARN(priv, "Invalid scan band count\n");
1427 goto done;
1428 }
1429
1430 band = priv->scan_band;
1431
1432 if (priv->cfg->scan_antennas[band])
1433 rx_ant = priv->cfg->scan_antennas[band];
1434
1435 priv->scan_tx_ant[band] =
1436 iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
1437 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
1438 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
1439
1440 /* In power save mode use one chain, otherwise use all chains */
1441 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
1442 /* rx_ant has been set to all valid chains previously */
1443 active_chains = rx_ant &
1444 ((u8)(priv->chain_noise_data.active_chains));
1445 if (!active_chains)
1446 active_chains = rx_ant;
1447
1448 IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
1449 priv->chain_noise_data.active_chains);
1450
1451 rx_ant = first_antenna(active_chains);
1452 }
1453 /* MIMO is not used here, but value is required */
1454 rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
1455 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
1456 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
1457 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
1458 scan->rx_chain = cpu_to_le16(rx_chain);
1459 if (!priv->is_internal_short_scan) {
1460 cmd_len = iwl_fill_probe_req(priv,
1461 (struct ieee80211_mgmt *)scan->data,
1462 priv->scan_request->ie,
1463 priv->scan_request->ie_len,
1464 IWL_MAX_SCAN_SIZE - sizeof(*scan));
1465 } else {
1466 cmd_len = iwl_fill_probe_req(priv,
1467 (struct ieee80211_mgmt *)scan->data,
1468 NULL, 0,
1469 IWL_MAX_SCAN_SIZE - sizeof(*scan));
1470
1471 }
1472 scan->tx_cmd.len = cpu_to_le16(cmd_len);
1473
1474 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
1475 RXON_FILTER_BCON_AWARE_MSK);
1476
1477 if (priv->is_internal_short_scan) {
1478 scan->channel_count =
1479 iwl_get_single_channel_for_scan(priv, vif, band,
1480 (void *)&scan->data[le16_to_cpu(
1481 scan->tx_cmd.len)]);
1482 } else {
1483 scan->channel_count =
1484 iwl_get_channels_for_scan(priv, vif, band,
1485 is_active, n_probes,
1486 (void *)&scan->data[le16_to_cpu(
1487 scan->tx_cmd.len)]);
1488 }
1489 if (scan->channel_count == 0) {
1490 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
1491 goto done;
1492 }
1493
1494 cmd.len += le16_to_cpu(scan->tx_cmd.len) +
1495 scan->channel_count * sizeof(struct iwl_scan_channel);
1496 cmd.data = scan;
1497 scan->len = cpu_to_le16(cmd.len);
1498
1499 set_bit(STATUS_SCAN_HW, &priv->status);
1500 if (iwl_send_cmd_sync(priv, &cmd))
1501 goto done;
1502
1503 queue_delayed_work(priv->workqueue, &priv->scan_check,
1504 IWL_SCAN_CHECK_WATCHDOG);
1505
1506 return;
1507
1508 done:
1509 /* Cannot perform scan. Make sure we clear scanning
1510 * bits from status so next scan request can be performed.
1511 * If we don't clear scanning status bit here all next scan
1512 * will fail
1513 */
1514 clear_bit(STATUS_SCAN_HW, &priv->status);
1515 clear_bit(STATUS_SCANNING, &priv->status);
1516 /* inform mac80211 scan aborted */
1517 queue_work(priv->workqueue, &priv->scan_completed);
1518}
1519
1520int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1521 struct ieee80211_vif *vif, bool add)
1522{
1523 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1524
1525 if (add)
1526 return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true,
1527 &vif_priv->ibss_bssid_sta_id);
1528 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1529 vif->bss_conf.bssid);
1530}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 1460116d329f..cf4a95bae4ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -295,11 +295,11 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
295 return tl->total; 295 return tl->total;
296} 296}
297 297
298static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, 298static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
299 struct iwl_lq_sta *lq_data, u8 tid, 299 struct iwl_lq_sta *lq_data, u8 tid,
300 struct ieee80211_sta *sta) 300 struct ieee80211_sta *sta)
301{ 301{
302 int ret; 302 int ret = -EAGAIN;
303 303
304 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { 304 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
305 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 305 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
@@ -313,29 +313,29 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
313 */ 313 */
314 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", 314 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
315 tid); 315 tid);
316 ret = ieee80211_stop_tx_ba_session(sta, tid, 316 ieee80211_stop_tx_ba_session(sta, tid,
317 WLAN_BACK_INITIATOR); 317 WLAN_BACK_INITIATOR);
318 } 318 }
319 } 319 } else
320 IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid);
321 return ret;
320} 322}
321 323
322static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, 324static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
323 struct iwl_lq_sta *lq_data, 325 struct iwl_lq_sta *lq_data,
324 struct ieee80211_sta *sta) 326 struct ieee80211_sta *sta)
325{ 327{
326 if ((tid < TID_MAX_LOAD_COUNT)) 328 if ((tid < TID_MAX_LOAD_COUNT) &&
327 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); 329 !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) {
328 else if (tid == IWL_AGG_ALL_TID) 330 if (priv->cfg->use_rts_for_ht) {
329 for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) 331 /*
330 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); 332 * switch to RTS/CTS if it is the prefer protection
331 if (priv->cfg->use_rts_for_ht) { 333 * method for HT traffic
332 /* 334 */
333 * switch to RTS/CTS if it is the prefer protection method 335 IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
334 * for HT traffic 336 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
335 */ 337 iwlcore_commit_rxon(priv);
336 IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n"); 338 }
337 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
338 iwlcore_commit_rxon(priv);
339 } 339 }
340} 340}
341 341
@@ -611,10 +611,6 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
611 struct ieee80211_hdr *hdr, 611 struct ieee80211_hdr *hdr,
612 enum iwl_table_type rate_type) 612 enum iwl_table_type rate_type)
613{ 613{
614 if (hdr && is_multicast_ether_addr(hdr->addr1) &&
615 lq_sta->active_rate_basic)
616 return lq_sta->active_rate_basic;
617
618 if (is_legacy(rate_type)) { 614 if (is_legacy(rate_type)) {
619 return lq_sta->active_legacy_rate; 615 return lq_sta->active_legacy_rate;
620 } else { 616 } else {
@@ -775,6 +771,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
775 771
776 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 772 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
777 773
774 /* Treat uninitialized rate scaling data same as non-existing. */
775 if (!lq_sta) {
776 IWL_DEBUG_RATE(priv, "Station rate scaling not created yet.\n");
777 return;
778 } else if (!lq_sta->drv) {
779 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
780 return;
781 }
782
778 if (!ieee80211_is_data(hdr->frame_control) || 783 if (!ieee80211_is_data(hdr->frame_control) ||
779 info->flags & IEEE80211_TX_CTL_NO_ACK) 784 info->flags & IEEE80211_TX_CTL_NO_ACK)
780 return; 785 return;
@@ -784,10 +789,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
784 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 789 !(info->flags & IEEE80211_TX_STAT_AMPDU))
785 return; 790 return;
786 791
787 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
788 !lq_sta->ibss_sta_added)
789 return;
790
791 /* 792 /*
792 * Ignore this Tx frame response if its initial rate doesn't match 793 * Ignore this Tx frame response if its initial rate doesn't match
793 * that of latest Link Quality command. There may be stragglers 794 * that of latest Link Quality command. There may be stragglers
@@ -833,7 +834,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
833 lq_sta->missed_rate_counter++; 834 lq_sta->missed_rate_counter++;
834 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 835 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
835 lq_sta->missed_rate_counter = 0; 836 lq_sta->missed_rate_counter = 0;
836 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 837 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
837 } 838 }
838 /* Regardless, ignore this status info for outdated rate */ 839 /* Regardless, ignore this status info for outdated rate */
839 return; 840 return;
@@ -867,14 +868,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
867 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, 868 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
868 &rs_index); 869 &rs_index);
869 rs_collect_tx_data(curr_tbl, rs_index, 870 rs_collect_tx_data(curr_tbl, rs_index,
870 info->status.ampdu_ack_len, 871 info->status.ampdu_len,
871 info->status.ampdu_ack_map); 872 info->status.ampdu_ack_len);
872 873
873 /* Update success/fail counts if not searching for new mode */ 874 /* Update success/fail counts if not searching for new mode */
874 if (lq_sta->stay_in_tbl) { 875 if (lq_sta->stay_in_tbl) {
875 lq_sta->total_success += info->status.ampdu_ack_map; 876 lq_sta->total_success += info->status.ampdu_ack_len;
876 lq_sta->total_failed += (info->status.ampdu_ack_len - 877 lq_sta->total_failed += (info->status.ampdu_len -
877 info->status.ampdu_ack_map); 878 info->status.ampdu_ack_len);
878 } 879 }
879 } else { 880 } else {
880 /* 881 /*
@@ -1913,7 +1914,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
1913 /* Update uCode's rate table. */ 1914 /* Update uCode's rate table. */
1914 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 1915 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1915 rs_fill_link_cmd(priv, lq_sta, rate); 1916 rs_fill_link_cmd(priv, lq_sta, rate);
1916 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1917 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
1917 1918
1918 return rate; 1919 return rate;
1919} 1920}
@@ -2002,7 +2003,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2002 /* rates available for this association, and for modulation mode */ 2003 /* rates available for this association, and for modulation mode */
2003 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 2004 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
2004 2005
2005 IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask); 2006 IWL_DEBUG_RATE(priv, "mask 0x%04X\n", rate_mask);
2006 2007
2007 /* mask with station rate restriction */ 2008 /* mask with station rate restriction */
2008 if (is_legacy(tbl->lq_type)) { 2009 if (is_legacy(tbl->lq_type)) {
@@ -2077,10 +2078,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2077 } 2078 }
2078 /* Else we have enough samples; calculate estimate of 2079 /* Else we have enough samples; calculate estimate of
2079 * actual average throughput */ 2080 * actual average throughput */
2080 2081 if (window->average_tpt != ((window->success_ratio *
2081 /* Sanity-check TPT calculations */ 2082 tbl->expected_tpt[index] + 64) / 128)) {
2082 BUG_ON(window->average_tpt != ((window->success_ratio * 2083 IWL_ERR(priv, "expected_tpt should have been calculated by now\n");
2083 tbl->expected_tpt[index] + 64) / 128)); 2084 window->average_tpt = ((window->success_ratio *
2085 tbl->expected_tpt[index] + 64) / 128);
2086 }
2084 2087
2085 /* If we are searching for better modulation mode, check success. */ 2088 /* If we are searching for better modulation mode, check success. */
2086 if (lq_sta->search_better_tbl && 2089 if (lq_sta->search_better_tbl &&
@@ -2289,7 +2292,7 @@ lq_update:
2289 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", 2292 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
2290 tbl->current_rate, index); 2293 tbl->current_rate, index);
2291 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); 2294 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
2292 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2295 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
2293 } else 2296 } else
2294 done_search = 1; 2297 done_search = 1;
2295 } 2298 }
@@ -2334,11 +2337,22 @@ out:
2334 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2337 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2335 i = index; 2338 i = index;
2336 lq_sta->last_txrate_idx = i; 2339 lq_sta->last_txrate_idx = i;
2337
2338 return;
2339} 2340}
2340 2341
2341 2342/**
2343 * rs_initialize_lq - Initialize a station's hardware rate table
2344 *
2345 * The uCode's station table contains a table of fallback rates
2346 * for automatic fallback during transmission.
2347 *
2348 * NOTE: This sets up a default set of values. These will be replaced later
2349 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2350 * rc80211_simple.
2351 *
2352 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
2353 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
2354 * which requires station table entry to exist).
2355 */
2342static void rs_initialize_lq(struct iwl_priv *priv, 2356static void rs_initialize_lq(struct iwl_priv *priv,
2343 struct ieee80211_conf *conf, 2357 struct ieee80211_conf *conf,
2344 struct ieee80211_sta *sta, 2358 struct ieee80211_sta *sta,
@@ -2357,10 +2371,6 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2357 2371
2358 i = lq_sta->last_txrate_idx; 2372 i = lq_sta->last_txrate_idx;
2359 2373
2360 if ((lq_sta->lq.sta_id == 0xff) &&
2361 (priv->iw_mode == NL80211_IFTYPE_ADHOC))
2362 goto out;
2363
2364 valid_tx_ant = priv->hw_params.valid_tx_ant; 2374 valid_tx_ant = priv->hw_params.valid_tx_ant;
2365 2375
2366 if (!lq_sta->search_better_tbl) 2376 if (!lq_sta->search_better_tbl)
@@ -2388,7 +2398,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2388 tbl->current_rate = rate; 2398 tbl->current_rate = rate;
2389 rs_set_expected_tpt_table(lq_sta, tbl); 2399 rs_set_expected_tpt_table(lq_sta, tbl);
2390 rs_fill_link_cmd(NULL, lq_sta, rate); 2400 rs_fill_link_cmd(NULL, lq_sta, rate);
2391 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2401 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
2402 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true);
2392 out: 2403 out:
2393 return; 2404 return;
2394} 2405}
@@ -2399,10 +2410,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2399 2410
2400 struct sk_buff *skb = txrc->skb; 2411 struct sk_buff *skb = txrc->skb;
2401 struct ieee80211_supported_band *sband = txrc->sband; 2412 struct ieee80211_supported_band *sband = txrc->sband;
2402 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2413 struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r;
2403 struct ieee80211_conf *conf = &priv->hw->conf;
2404 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2405 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2406 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2414 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2407 struct iwl_lq_sta *lq_sta = priv_sta; 2415 struct iwl_lq_sta *lq_sta = priv_sta;
2408 int rate_idx; 2416 int rate_idx;
@@ -2420,30 +2428,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2420 lq_sta->max_rate_idx = -1; 2428 lq_sta->max_rate_idx = -1;
2421 } 2429 }
2422 2430
2431 /* Treat uninitialized rate scaling data same as non-existing. */
2432 if (lq_sta && !lq_sta->drv) {
2433 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
2434 priv_sta = NULL;
2435 }
2436
2423 /* Send management frames and NO_ACK data using lowest rate. */ 2437 /* Send management frames and NO_ACK data using lowest rate. */
2424 if (rate_control_send_low(sta, priv_sta, txrc)) 2438 if (rate_control_send_low(sta, priv_sta, txrc))
2425 return; 2439 return;
2426 2440
2427 rate_idx = lq_sta->last_txrate_idx; 2441 rate_idx = lq_sta->last_txrate_idx;
2428 2442
2429 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
2430 !lq_sta->ibss_sta_added) {
2431 u8 sta_id = iwl_find_station(priv, hdr->addr1);
2432
2433 if (sta_id == IWL_INVALID_STATION) {
2434 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2435 hdr->addr1);
2436 sta_id = iwl_add_station(priv, hdr->addr1,
2437 false, CMD_ASYNC, ht_cap);
2438 }
2439 if ((sta_id != IWL_INVALID_STATION)) {
2440 lq_sta->lq.sta_id = sta_id;
2441 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2442 lq_sta->ibss_sta_added = 1;
2443 rs_initialize_lq(priv, conf, sta, lq_sta);
2444 }
2445 }
2446
2447 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { 2443 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2448 rate_idx -= IWL_FIRST_OFDM_RATE; 2444 rate_idx -= IWL_FIRST_OFDM_RATE;
2449 /* 6M and 9M shared same MCS index */ 2445 /* 6M and 9M shared same MCS index */
@@ -2493,16 +2489,25 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2493 return lq_sta; 2489 return lq_sta;
2494} 2490}
2495 2491
2496static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 2492/*
2497 struct ieee80211_sta *sta, void *priv_sta) 2493 * Called after adding a new station to initialize rate scaling
2494 */
2495void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
2498{ 2496{
2499 int i, j; 2497 int i, j;
2500 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2498 struct ieee80211_hw *hw = priv->hw;
2501 struct ieee80211_conf *conf = &priv->hw->conf; 2499 struct ieee80211_conf *conf = &priv->hw->conf;
2502 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2500 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2503 struct iwl_lq_sta *lq_sta = priv_sta; 2501 struct iwl_station_priv *sta_priv;
2502 struct iwl_lq_sta *lq_sta;
2503 struct ieee80211_supported_band *sband;
2504
2505 sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2506 lq_sta = &sta_priv->lq_sta;
2507 sband = hw->wiphy->bands[conf->channel->band];
2504 2508
2505 lq_sta->lq.sta_id = 0xff; 2509
2510 lq_sta->lq.sta_id = sta_id;
2506 2511
2507 for (j = 0; j < LQ_SIZE; j++) 2512 for (j = 0; j < LQ_SIZE; j++)
2508 for (i = 0; i < IWL_RATE_COUNT; i++) 2513 for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -2514,39 +2519,18 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2514 for (i = 0; i < IWL_RATE_COUNT; i++) 2519 for (i = 0; i < IWL_RATE_COUNT; i++)
2515 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2520 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2516 2521
2517 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n"); 2522 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n",
2523 sta_id);
2518 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2524 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2519 * the lowest or the highest rate.. Could consider using RSSI from 2525 * the lowest or the highest rate.. Could consider using RSSI from
2520 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2526 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2521 * after assoc.. */ 2527 * after assoc.. */
2522 2528
2523 lq_sta->ibss_sta_added = 0;
2524 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2525 u8 sta_id = iwl_find_station(priv,
2526 sta->addr);
2527
2528 /* for IBSS the call are from tasklet */
2529 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2530
2531 if (sta_id == IWL_INVALID_STATION) {
2532 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2533 sta_id = iwl_add_station(priv, sta->addr, false,
2534 CMD_ASYNC, ht_cap);
2535 }
2536 if ((sta_id != IWL_INVALID_STATION)) {
2537 lq_sta->lq.sta_id = sta_id;
2538 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2539 }
2540 /* FIXME: this is w/a remove it later */
2541 priv->assoc_station_added = 1;
2542 }
2543
2544 lq_sta->is_dup = 0; 2529 lq_sta->is_dup = 0;
2545 lq_sta->max_rate_idx = -1; 2530 lq_sta->max_rate_idx = -1;
2546 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2531 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2547 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2532 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
2548 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2533 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2549 lq_sta->active_rate_basic = priv->active_rate_basic;
2550 lq_sta->band = priv->band; 2534 lq_sta->band = priv->band;
2551 /* 2535 /*
2552 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2536 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
@@ -2574,8 +2558,17 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2574 lq_sta->active_mimo3_rate); 2558 lq_sta->active_mimo3_rate);
2575 2559
2576 /* These values will be overridden later */ 2560 /* These values will be overridden later */
2577 lq_sta->lq.general_params.single_stream_ant_msk = ANT_A; 2561 lq_sta->lq.general_params.single_stream_ant_msk =
2578 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; 2562 first_antenna(priv->hw_params.valid_tx_ant);
2563 lq_sta->lq.general_params.dual_stream_ant_msk =
2564 priv->hw_params.valid_tx_ant &
2565 ~first_antenna(priv->hw_params.valid_tx_ant);
2566 if (!lq_sta->lq.general_params.dual_stream_ant_msk) {
2567 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
2568 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
2569 lq_sta->lq.general_params.dual_stream_ant_msk =
2570 priv->hw_params.valid_tx_ant;
2571 }
2579 2572
2580 /* as default allow aggregation for all tids */ 2573 /* as default allow aggregation for all tids */
2581 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2574 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
@@ -2794,7 +2787,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2794 2787
2795 if (lq_sta->dbg_fixed_rate) { 2788 if (lq_sta->dbg_fixed_rate) {
2796 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); 2789 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2797 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2790 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
2798 } 2791 }
2799 2792
2800 return count; 2793 return count;
@@ -2950,12 +2943,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2950 desc += sprintf(buff+desc, 2943 desc += sprintf(buff+desc,
2951 "Bit Rate= %d Mb/s\n", 2944 "Bit Rate= %d Mb/s\n",
2952 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); 2945 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
2953 desc += sprintf(buff+desc,
2954 "Signal Level= %d dBm\tNoise Level= %d dBm\n",
2955 priv->last_rx_rssi, priv->last_rx_noise);
2956 desc += sprintf(buff+desc,
2957 "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
2958 priv->last_tsf, priv->last_beacon_time);
2959 2946
2960 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2947 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2961 return ret; 2948 return ret;
@@ -2995,12 +2982,21 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
2995} 2982}
2996#endif 2983#endif
2997 2984
2985/*
2986 * Initialization of rate scaling information is done by driver after
2987 * the station is added. Since mac80211 calls this function before a
2988 * station is added we ignore it.
2989 */
2990static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
2991 struct ieee80211_sta *sta, void *priv_sta)
2992{
2993}
2998static struct rate_control_ops rs_ops = { 2994static struct rate_control_ops rs_ops = {
2999 .module = NULL, 2995 .module = NULL,
3000 .name = RS_NAME, 2996 .name = RS_NAME,
3001 .tx_status = rs_tx_status, 2997 .tx_status = rs_tx_status,
3002 .get_rate = rs_get_rate, 2998 .get_rate = rs_get_rate,
3003 .rate_init = rs_rate_init, 2999 .rate_init = rs_rate_init_stub,
3004 .alloc = rs_alloc, 3000 .alloc = rs_alloc,
3005 .free = rs_free, 3001 .free = rs_free,
3006 .alloc_sta = rs_alloc_sta, 3002 .alloc_sta = rs_alloc_sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index e71923961e69..8292f6d48ec6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -403,7 +403,6 @@ struct iwl_lq_sta {
403 u8 is_green; 403 u8 is_green;
404 u8 is_dup; 404 u8 is_dup;
405 enum ieee80211_band band; 405 enum ieee80211_band band;
406 u8 ibss_sta_added;
407 406
408 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 407 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
409 u32 supp_rates; 408 u32 supp_rates;
@@ -411,7 +410,6 @@ struct iwl_lq_sta {
411 u16 active_siso_rate; 410 u16 active_siso_rate;
412 u16 active_mimo2_rate; 411 u16 active_mimo2_rate;
413 u16 active_mimo3_rate; 412 u16 active_mimo3_rate;
414 u16 active_rate_basic;
415 s8 max_rate_idx; /* Max rate set by user */ 413 s8 max_rate_idx; /* Max rate set by user */
416 u8 missed_rate_counter; 414 u8 missed_rate_counter;
417 415
@@ -479,6 +477,12 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
479 */ 477 */
480extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); 478extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
481 479
480/* Initialize station's rate scaling information after adding station */
481extern void iwl_rs_rate_init(struct iwl_priv *priv,
482 struct ieee80211_sta *sta, u8 sta_id);
483extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
484 struct ieee80211_sta *sta, u8 sta_id);
485
482/** 486/**
483 * iwl_rate_control_register - Register the rate control algorithm callbacks 487 * iwl_rate_control_register - Register the rate control algorithm callbacks
484 * 488 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
new file mode 100644
index 000000000000..c402bfc83f36
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -0,0 +1,1340 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-sta.h"
38#include "iwl-io.h"
39#include "iwl-helpers.h"
40#include "iwl-agn-hw.h"
41#include "iwl-agn.h"
42
43/*
44 * mac80211 queues, ACs, hardware queues, FIFOs.
45 *
46 * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
47 *
48 * Mac80211 uses the following numbers, which we get as from it
49 * by way of skb_get_queue_mapping(skb):
50 *
51 * VO 0
52 * VI 1
53 * BE 2
54 * BK 3
55 *
56 *
57 * Regular (not A-MPDU) frames are put into hardware queues corresponding
58 * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
59 * own queue per aggregation session (RA/TID combination), such queues are
60 * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
61 * order to map frames to the right queue, we also need an AC->hw queue
62 * mapping. This is implemented here.
63 *
64 * Due to the way hw queues are set up (by the hw specific modules like
65 * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity
66 * mapping.
67 */
68
69static const u8 tid_to_ac[] = {
70 /* this matches the mac80211 numbers */
71 2, 3, 3, 2, 1, 1, 0, 0
72};
73
74static const u8 ac_to_fifo[] = {
75 IWL_TX_FIFO_VO,
76 IWL_TX_FIFO_VI,
77 IWL_TX_FIFO_BE,
78 IWL_TX_FIFO_BK,
79};
80
81static inline int get_fifo_from_ac(u8 ac)
82{
83 return ac_to_fifo[ac];
84}
85
86static inline int get_ac_from_tid(u16 tid)
87{
88 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
89 return tid_to_ac[tid];
90
91 /* no support for TIDs 8-15 yet */
92 return -EINVAL;
93}
94
95static inline int get_fifo_from_tid(u16 tid)
96{
97 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
98 return get_fifo_from_ac(tid_to_ac[tid]);
99
100 /* no support for TIDs 8-15 yet */
101 return -EINVAL;
102}
103
104/**
105 * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
106 */
107void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
108 struct iwl_tx_queue *txq,
109 u16 byte_cnt)
110{
111 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
112 int write_ptr = txq->q.write_ptr;
113 int txq_id = txq->q.id;
114 u8 sec_ctl = 0;
115 u8 sta_id = 0;
116 u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
117 __le16 bc_ent;
118
119 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
120
121 if (txq_id != IWL_CMD_QUEUE_NUM) {
122 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
123 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
124
125 switch (sec_ctl & TX_CMD_SEC_MSK) {
126 case TX_CMD_SEC_CCM:
127 len += CCMP_MIC_LEN;
128 break;
129 case TX_CMD_SEC_TKIP:
130 len += TKIP_ICV_LEN;
131 break;
132 case TX_CMD_SEC_WEP:
133 len += WEP_IV_LEN + WEP_ICV_LEN;
134 break;
135 }
136 }
137
138 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
139
140 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
141
142 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
143 scd_bc_tbl[txq_id].
144 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
145}
146
147void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
148 struct iwl_tx_queue *txq)
149{
150 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
151 int txq_id = txq->q.id;
152 int read_ptr = txq->q.read_ptr;
153 u8 sta_id = 0;
154 __le16 bc_ent;
155
156 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
157
158 if (txq_id != IWL_CMD_QUEUE_NUM)
159 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
160
161 bc_ent = cpu_to_le16(1 | (sta_id << 12));
162 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
163
164 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
165 scd_bc_tbl[txq_id].
166 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
167}
168
169static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
170 u16 txq_id)
171{
172 u32 tbl_dw_addr;
173 u32 tbl_dw;
174 u16 scd_q2ratid;
175
176 scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
177
178 tbl_dw_addr = priv->scd_base_addr +
179 IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
180
181 tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
182
183 if (txq_id & 0x1)
184 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
185 else
186 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
187
188 iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
189
190 return 0;
191}
192
193static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
194{
195 /* Simply stop the queue, but don't change any configuration;
196 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
197 iwl_write_prph(priv,
198 IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
199 (0 << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
200 (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
201}
202
203void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
204 int txq_id, u32 index)
205{
206 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
207 (index & 0xff) | (txq_id << 8));
208 iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(txq_id), index);
209}
210
211void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
212 struct iwl_tx_queue *txq,
213 int tx_fifo_id, int scd_retry)
214{
215 int txq_id = txq->q.id;
216 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
217
218 iwl_write_prph(priv, IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
219 (active << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
220 (tx_fifo_id << IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF) |
221 (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL) |
222 IWLAGN_SCD_QUEUE_STTS_REG_MSK);
223
224 txq->sched_retry = scd_retry;
225
226 IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n",
227 active ? "Activate" : "Deactivate",
228 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
229}
230
231int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
232 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
233{
234 unsigned long flags;
235 u16 ra_tid;
236
237 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
238 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
239 <= txq_id)) {
240 IWL_WARN(priv,
241 "queue number out of range: %d, must be %d to %d\n",
242 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
243 IWLAGN_FIRST_AMPDU_QUEUE +
244 priv->cfg->num_of_ampdu_queues - 1);
245 return -EINVAL;
246 }
247
248 ra_tid = BUILD_RAxTID(sta_id, tid);
249
250 /* Modify device's station table to Tx this TID */
251 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
252
253 spin_lock_irqsave(&priv->lock, flags);
254
255 /* Stop this Tx queue before configuring it */
256 iwlagn_tx_queue_stop_scheduler(priv, txq_id);
257
258 /* Map receiver-address / traffic-ID to this queue */
259 iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
260
261 /* Set this queue as a chain-building queue */
262 iwl_set_bits_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, (1<<txq_id));
263
264 /* enable aggregations for the queue */
265 iwl_set_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1<<txq_id));
266
267 /* Place first TFD at index corresponding to start sequence number.
268 * Assumes that ssn_idx is valid (!= 0xFFF) */
269 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
270 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
271 iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
272
273 /* Set up Tx window size and frame limit for this queue */
274 iwl_write_targ_mem(priv, priv->scd_base_addr +
275 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
276 sizeof(u32),
277 ((SCD_WIN_SIZE <<
278 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
279 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
280 ((SCD_FRAME_LIMIT <<
281 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
282 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
283
284 iwl_set_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
285
286 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
287 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
288
289 spin_unlock_irqrestore(&priv->lock, flags);
290
291 return 0;
292}
293
294int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
295 u16 ssn_idx, u8 tx_fifo)
296{
297 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
298 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
299 <= txq_id)) {
300 IWL_ERR(priv,
301 "queue number out of range: %d, must be %d to %d\n",
302 txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
303 IWLAGN_FIRST_AMPDU_QUEUE +
304 priv->cfg->num_of_ampdu_queues - 1);
305 return -EINVAL;
306 }
307
308 iwlagn_tx_queue_stop_scheduler(priv, txq_id);
309
310 iwl_clear_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1 << txq_id));
311
312 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
313 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
314 /* supposes that ssn_idx is valid (!= 0xFFF) */
315 iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
316
317 iwl_clear_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
318 iwl_txq_ctx_deactivate(priv, txq_id);
319 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
320
321 return 0;
322}
323
324/*
325 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
326 * must be called under priv->lock and mac access
327 */
328void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
329{
330 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
331}
332
333static inline int get_queue_from_ac(u16 ac)
334{
335 return ac;
336}
337
338/*
339 * handle build REPLY_TX command notification.
340 */
341static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
342 struct iwl_tx_cmd *tx_cmd,
343 struct ieee80211_tx_info *info,
344 struct ieee80211_hdr *hdr,
345 u8 std_id)
346{
347 __le16 fc = hdr->frame_control;
348 __le32 tx_flags = tx_cmd->tx_flags;
349
350 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
351 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
352 tx_flags |= TX_CMD_FLG_ACK_MSK;
353 if (ieee80211_is_mgmt(fc))
354 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
355 if (ieee80211_is_probe_resp(fc) &&
356 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
357 tx_flags |= TX_CMD_FLG_TSF_MSK;
358 } else {
359 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
360 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
361 }
362
363 if (ieee80211_is_back_req(fc))
364 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
365
366
367 tx_cmd->sta_id = std_id;
368 if (ieee80211_has_morefrags(fc))
369 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
370
371 if (ieee80211_is_data_qos(fc)) {
372 u8 *qc = ieee80211_get_qos_ctl(hdr);
373 tx_cmd->tid_tspec = qc[0] & 0xf;
374 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
375 } else {
376 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
377 }
378
379 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
380
381 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
382 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
383
384 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
385 if (ieee80211_is_mgmt(fc)) {
386 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
387 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
388 else
389 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
390 } else {
391 tx_cmd->timeout.pm_frame_timeout = 0;
392 }
393
394 tx_cmd->driver_txop = 0;
395 tx_cmd->tx_flags = tx_flags;
396 tx_cmd->next_frame_len = 0;
397}
398
399#define RTS_DFAULT_RETRY_LIMIT 60
400
401static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
402 struct iwl_tx_cmd *tx_cmd,
403 struct ieee80211_tx_info *info,
404 __le16 fc)
405{
406 u32 rate_flags;
407 int rate_idx;
408 u8 rts_retry_limit;
409 u8 data_retry_limit;
410 u8 rate_plcp;
411
412 /* Set retry limit on DATA packets and Probe Responses*/
413 if (ieee80211_is_probe_resp(fc))
414 data_retry_limit = 3;
415 else
416 data_retry_limit = IWLAGN_DEFAULT_TX_RETRY;
417 tx_cmd->data_retry_limit = data_retry_limit;
418
419 /* Set retry limit on RTS packets */
420 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT;
421 if (data_retry_limit < rts_retry_limit)
422 rts_retry_limit = data_retry_limit;
423 tx_cmd->rts_retry_limit = rts_retry_limit;
424
425 /* DATA packets will use the uCode station table for rate/antenna
426 * selection */
427 if (ieee80211_is_data(fc)) {
428 tx_cmd->initial_rate_index = 0;
429 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
430 return;
431 }
432
433 /**
434 * If the current TX rate stored in mac80211 has the MCS bit set, it's
435 * not really a TX rate. Thus, we use the lowest supported rate for
436 * this band. Also use the lowest supported rate if the stored rate
437 * index is invalid.
438 */
439 rate_idx = info->control.rates[0].idx;
440 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
441 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
442 rate_idx = rate_lowest_index(&priv->bands[info->band],
443 info->control.sta);
444 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
445 if (info->band == IEEE80211_BAND_5GHZ)
446 rate_idx += IWL_FIRST_OFDM_RATE;
447 /* Get PLCP rate for tx_cmd->rate_n_flags */
448 rate_plcp = iwl_rates[rate_idx].plcp;
449 /* Zero out flags for this packet */
450 rate_flags = 0;
451
452 /* Set CCK flag as needed */
453 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
454 rate_flags |= RATE_MCS_CCK_MSK;
455
456 /* Set up RTS and CTS flags for certain packets */
457 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
458 case cpu_to_le16(IEEE80211_STYPE_AUTH):
459 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
460 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
461 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
462 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
463 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
464 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
465 }
466 break;
467 default:
468 break;
469 }
470
471 /* Set up antennas */
472 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
473 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
474
475 /* Set the rate in the TX cmd */
476 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
477}
478
479static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
480 struct ieee80211_tx_info *info,
481 struct iwl_tx_cmd *tx_cmd,
482 struct sk_buff *skb_frag,
483 int sta_id)
484{
485 struct ieee80211_key_conf *keyconf = info->control.hw_key;
486
487 switch (keyconf->alg) {
488 case ALG_CCMP:
489 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
490 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
491 if (info->flags & IEEE80211_TX_CTL_AMPDU)
492 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
493 IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
494 break;
495
496 case ALG_TKIP:
497 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
498 ieee80211_get_tkip_key(keyconf, skb_frag,
499 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
500 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
501 break;
502
503 case ALG_WEP:
504 tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
505 (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
506
507 if (keyconf->keylen == WEP_KEY_LEN_128)
508 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
509
510 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
511
512 IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
513 "with key %d\n", keyconf->keyidx);
514 break;
515
516 default:
517 IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
518 break;
519 }
520}
521
522/*
523 * start REPLY_TX command process
524 */
525int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
526{
527 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
528 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
529 struct ieee80211_sta *sta = info->control.sta;
530 struct iwl_station_priv *sta_priv = NULL;
531 struct iwl_tx_queue *txq;
532 struct iwl_queue *q;
533 struct iwl_device_cmd *out_cmd;
534 struct iwl_cmd_meta *out_meta;
535 struct iwl_tx_cmd *tx_cmd;
536 int swq_id, txq_id;
537 dma_addr_t phys_addr;
538 dma_addr_t txcmd_phys;
539 dma_addr_t scratch_phys;
540 u16 len, len_org, firstlen, secondlen;
541 u16 seq_number = 0;
542 __le16 fc;
543 u8 hdr_len;
544 u8 sta_id;
545 u8 wait_write_ptr = 0;
546 u8 tid = 0;
547 u8 *qc = NULL;
548 unsigned long flags;
549
550 spin_lock_irqsave(&priv->lock, flags);
551 if (iwl_is_rfkill(priv)) {
552 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
553 goto drop_unlock;
554 }
555
556 fc = hdr->frame_control;
557
558#ifdef CONFIG_IWLWIFI_DEBUG
559 if (ieee80211_is_auth(fc))
560 IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
561 else if (ieee80211_is_assoc_req(fc))
562 IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
563 else if (ieee80211_is_reassoc_req(fc))
564 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
565#endif
566
567 hdr_len = ieee80211_hdrlen(fc);
568
569 /* Find index into station table for destination station */
570 if (!info->control.sta)
571 sta_id = priv->hw_params.bcast_sta_id;
572 else
573 sta_id = iwl_sta_id(info->control.sta);
574 if (sta_id == IWL_INVALID_STATION) {
575 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
576 hdr->addr1);
577 goto drop_unlock;
578 }
579
580 IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
581
582 if (sta)
583 sta_priv = (void *)sta->drv_priv;
584
585 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
586 sta_priv->asleep) {
587 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
588 /*
589 * This sends an asynchronous command to the device,
590 * but we can rely on it being processed before the
591 * next frame is processed -- and the next frame to
592 * this station is the one that will consume this
593 * counter.
594 * For now set the counter to just 1 since we do not
595 * support uAPSD yet.
596 */
597 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
598 }
599
600 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
601 if (ieee80211_is_data_qos(fc)) {
602 qc = ieee80211_get_qos_ctl(hdr);
603 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
604 if (unlikely(tid >= MAX_TID_COUNT))
605 goto drop_unlock;
606 seq_number = priv->stations[sta_id].tid[tid].seq_number;
607 seq_number &= IEEE80211_SCTL_SEQ;
608 hdr->seq_ctrl = hdr->seq_ctrl &
609 cpu_to_le16(IEEE80211_SCTL_FRAG);
610 hdr->seq_ctrl |= cpu_to_le16(seq_number);
611 seq_number += 0x10;
612 /* aggregation is on for this <sta,tid> */
613 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
614 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
615 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
616 }
617 }
618
619 txq = &priv->txq[txq_id];
620 swq_id = txq->swq_id;
621 q = &txq->q;
622
623 if (unlikely(iwl_queue_space(q) < q->high_mark))
624 goto drop_unlock;
625
626 if (ieee80211_is_data_qos(fc))
627 priv->stations[sta_id].tid[tid].tfds_in_queue++;
628
629 /* Set up driver data for this TFD */
630 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
631 txq->txb[q->write_ptr].skb[0] = skb;
632
633 /* Set up first empty entry in queue's array of Tx/cmd buffers */
634 out_cmd = txq->cmd[q->write_ptr];
635 out_meta = &txq->meta[q->write_ptr];
636 tx_cmd = &out_cmd->cmd.tx;
637 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
638 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
639
640 /*
641 * Set up the Tx-command (not MAC!) header.
642 * Store the chosen Tx queue and TFD index within the sequence field;
643 * after Tx, uCode's Tx response will return this value so driver can
644 * locate the frame within the tx queue and do post-tx processing.
645 */
646 out_cmd->hdr.cmd = REPLY_TX;
647 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
648 INDEX_TO_SEQ(q->write_ptr)));
649
650 /* Copy MAC header from skb into command buffer */
651 memcpy(tx_cmd->hdr, hdr, hdr_len);
652
653
654 /* Total # bytes to be transmitted */
655 len = (u16)skb->len;
656 tx_cmd->len = cpu_to_le16(len);
657
658 if (info->control.hw_key)
659 iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
660
661 /* TODO need this for burst mode later on */
662 iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
663 iwl_dbg_log_tx_data_frame(priv, len, hdr);
664
665 iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
666
667 iwl_update_stats(priv, true, fc, len);
668 /*
669 * Use the first empty entry in this queue's command buffer array
670 * to contain the Tx command and MAC header concatenated together
671 * (payload data will be in another buffer).
672 * Size of this varies, due to varying MAC header length.
673 * If end is not dword aligned, we'll have 2 extra bytes at the end
674 * of the MAC header (device reads on dword boundaries).
675 * We'll tell device about this padding later.
676 */
677 len = sizeof(struct iwl_tx_cmd) +
678 sizeof(struct iwl_cmd_header) + hdr_len;
679
680 len_org = len;
681 firstlen = len = (len + 3) & ~3;
682
683 if (len_org != len)
684 len_org = 1;
685 else
686 len_org = 0;
687
688 /* Tell NIC about any 2-byte padding after MAC header */
689 if (len_org)
690 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
691
692 /* Physical address of this Tx command's header (not MAC header!),
693 * within command buffer array. */
694 txcmd_phys = pci_map_single(priv->pci_dev,
695 &out_cmd->hdr, len,
696 PCI_DMA_BIDIRECTIONAL);
697 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
698 pci_unmap_len_set(out_meta, len, len);
699 /* Add buffer containing Tx command and MAC(!) header to TFD's
700 * first entry */
701 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
702 txcmd_phys, len, 1, 0);
703
704 if (!ieee80211_has_morefrags(hdr->frame_control)) {
705 txq->need_update = 1;
706 if (qc)
707 priv->stations[sta_id].tid[tid].seq_number = seq_number;
708 } else {
709 wait_write_ptr = 1;
710 txq->need_update = 0;
711 }
712
713 /* Set up TFD's 2nd entry to point directly to remainder of skb,
714 * if any (802.11 null frames have no payload). */
715 secondlen = len = skb->len - hdr_len;
716 if (len) {
717 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
718 len, PCI_DMA_TODEVICE);
719 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
720 phys_addr, len,
721 0, 0);
722 }
723
724 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
725 offsetof(struct iwl_tx_cmd, scratch);
726
727 len = sizeof(struct iwl_tx_cmd) +
728 sizeof(struct iwl_cmd_header) + hdr_len;
729 /* take back ownership of DMA buffer to enable update */
730 pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
731 len, PCI_DMA_BIDIRECTIONAL);
732 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
733 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
734
735 IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
736 le16_to_cpu(out_cmd->hdr.sequence));
737 IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
738 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
739 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
740
741 /* Set up entry for this TFD in Tx byte-count array */
742 if (info->flags & IEEE80211_TX_CTL_AMPDU)
743 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
744 le16_to_cpu(tx_cmd->len));
745
746 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
747 len, PCI_DMA_BIDIRECTIONAL);
748
749 trace_iwlwifi_dev_tx(priv,
750 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
751 sizeof(struct iwl_tfd),
752 &out_cmd->hdr, firstlen,
753 skb->data + hdr_len, secondlen);
754
755 /* Tell device the write index *just past* this latest filled TFD */
756 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
757 iwl_txq_update_write_ptr(priv, txq);
758 spin_unlock_irqrestore(&priv->lock, flags);
759
760 /*
761 * At this point the frame is "transmitted" successfully
762 * and we will get a TX status notification eventually,
763 * regardless of the value of ret. "ret" only indicates
764 * whether or not we should update the write pointer.
765 */
766
767 /* avoid atomic ops if it isn't an associated client */
768 if (sta_priv && sta_priv->client)
769 atomic_inc(&sta_priv->pending_frames);
770
771 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
772 if (wait_write_ptr) {
773 spin_lock_irqsave(&priv->lock, flags);
774 txq->need_update = 1;
775 iwl_txq_update_write_ptr(priv, txq);
776 spin_unlock_irqrestore(&priv->lock, flags);
777 } else {
778 iwl_stop_queue(priv, txq->swq_id);
779 }
780 }
781
782 return 0;
783
784drop_unlock:
785 spin_unlock_irqrestore(&priv->lock, flags);
786 return -1;
787}
788
789static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
790 struct iwl_dma_ptr *ptr, size_t size)
791{
792 ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
793 GFP_KERNEL);
794 if (!ptr->addr)
795 return -ENOMEM;
796 ptr->size = size;
797 return 0;
798}
799
800static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
801 struct iwl_dma_ptr *ptr)
802{
803 if (unlikely(!ptr->addr))
804 return;
805
806 dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
807 memset(ptr, 0, sizeof(*ptr));
808}
809
810/**
811 * iwlagn_hw_txq_ctx_free - Free TXQ Context
812 *
813 * Destroy all TX DMA queues and structures
814 */
815void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
816{
817 int txq_id;
818
819 /* Tx queues */
820 if (priv->txq) {
821 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
822 if (txq_id == IWL_CMD_QUEUE_NUM)
823 iwl_cmd_queue_free(priv);
824 else
825 iwl_tx_queue_free(priv, txq_id);
826 }
827 iwlagn_free_dma_ptr(priv, &priv->kw);
828
829 iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
830
831 /* free tx queue structure */
832 iwl_free_txq_mem(priv);
833}
834
835/**
836 * iwlagn_txq_ctx_alloc - allocate TX queue context
837 * Allocate all Tx DMA structures and initialize them
838 *
839 * @param priv
840 * @return error code
841 */
842int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
843{
844 int ret;
845 int txq_id, slots_num;
846 unsigned long flags;
847
848 /* Free all tx/cmd queues and keep-warm buffer */
849 iwlagn_hw_txq_ctx_free(priv);
850
851 ret = iwlagn_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
852 priv->hw_params.scd_bc_tbls_size);
853 if (ret) {
854 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
855 goto error_bc_tbls;
856 }
857 /* Alloc keep-warm buffer */
858 ret = iwlagn_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
859 if (ret) {
860 IWL_ERR(priv, "Keep Warm allocation failed\n");
861 goto error_kw;
862 }
863
864 /* allocate tx queue structure */
865 ret = iwl_alloc_txq_mem(priv);
866 if (ret)
867 goto error;
868
869 spin_lock_irqsave(&priv->lock, flags);
870
871 /* Turn off all Tx DMA fifos */
872 priv->cfg->ops->lib->txq_set_sched(priv, 0);
873
874 /* Tell NIC where to find the "keep warm" buffer */
875 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
876
877 spin_unlock_irqrestore(&priv->lock, flags);
878
879 /* Alloc and init all Tx queues, including the command queue (#4) */
880 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
881 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
882 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
883 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
884 txq_id);
885 if (ret) {
886 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
887 goto error;
888 }
889 }
890
891 return ret;
892
893 error:
894 iwlagn_hw_txq_ctx_free(priv);
895 iwlagn_free_dma_ptr(priv, &priv->kw);
896 error_kw:
897 iwlagn_free_dma_ptr(priv, &priv->scd_bc_tbls);
898 error_bc_tbls:
899 return ret;
900}
901
902void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
903{
904 int txq_id, slots_num;
905 unsigned long flags;
906
907 spin_lock_irqsave(&priv->lock, flags);
908
909 /* Turn off all Tx DMA fifos */
910 priv->cfg->ops->lib->txq_set_sched(priv, 0);
911
912 /* Tell NIC where to find the "keep warm" buffer */
913 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
914
915 spin_unlock_irqrestore(&priv->lock, flags);
916
917 /* Alloc and init all Tx queues, including the command queue (#4) */
918 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
919 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
920 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
921 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
922 }
923}
924
925/**
926 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
927 */
928void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
929{
930 int ch;
931 unsigned long flags;
932
933 /* Turn off all Tx DMA fifos */
934 spin_lock_irqsave(&priv->lock, flags);
935
936 priv->cfg->ops->lib->txq_set_sched(priv, 0);
937
938 /* Stop each Tx DMA channel, and wait for it to be idle */
939 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
940 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
941 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
942 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
943 1000);
944 }
945 spin_unlock_irqrestore(&priv->lock, flags);
946}
947
948/*
949 * Find first available (lowest unused) Tx Queue, mark it "active".
950 * Called only when finding queue for aggregation.
951 * Should never return anything < 7, because they should already
952 * be in use as EDCA AC (0-3), Command (4), reserved (5, 6)
953 */
954static int iwlagn_txq_ctx_activate_free(struct iwl_priv *priv)
955{
956 int txq_id;
957
958 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
959 if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
960 return txq_id;
961 return -1;
962}
963
964int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
965 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
966{
967 int sta_id;
968 int tx_fifo;
969 int txq_id;
970 int ret;
971 unsigned long flags;
972 struct iwl_tid_data *tid_data;
973
974 tx_fifo = get_fifo_from_tid(tid);
975 if (unlikely(tx_fifo < 0))
976 return tx_fifo;
977
978 IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
979 __func__, sta->addr, tid);
980
981 sta_id = iwl_sta_id(sta);
982 if (sta_id == IWL_INVALID_STATION) {
983 IWL_ERR(priv, "Start AGG on invalid station\n");
984 return -ENXIO;
985 }
986 if (unlikely(tid >= MAX_TID_COUNT))
987 return -EINVAL;
988
989 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
990 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
991 return -ENXIO;
992 }
993
994 txq_id = iwlagn_txq_ctx_activate_free(priv);
995 if (txq_id == -1) {
996 IWL_ERR(priv, "No free aggregation queue available\n");
997 return -ENXIO;
998 }
999
1000 spin_lock_irqsave(&priv->sta_lock, flags);
1001 tid_data = &priv->stations[sta_id].tid[tid];
1002 *ssn = SEQ_TO_SN(tid_data->seq_number);
1003 tid_data->agg.txq_id = txq_id;
1004 priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id);
1005 spin_unlock_irqrestore(&priv->sta_lock, flags);
1006
1007 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
1008 sta_id, tid, *ssn);
1009 if (ret)
1010 return ret;
1011
1012 if (tid_data->tfds_in_queue == 0) {
1013 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1014 tid_data->agg.state = IWL_AGG_ON;
1015 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1016 } else {
1017 IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
1018 tid_data->tfds_in_queue);
1019 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1020 }
1021 return ret;
1022}
1023
1024int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1025 struct ieee80211_sta *sta, u16 tid)
1026{
1027 int tx_fifo_id, txq_id, sta_id, ssn = -1;
1028 struct iwl_tid_data *tid_data;
1029 int write_ptr, read_ptr;
1030 unsigned long flags;
1031
1032 tx_fifo_id = get_fifo_from_tid(tid);
1033 if (unlikely(tx_fifo_id < 0))
1034 return tx_fifo_id;
1035
1036 sta_id = iwl_sta_id(sta);
1037
1038 if (sta_id == IWL_INVALID_STATION) {
1039 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1040 return -ENXIO;
1041 }
1042
1043 if (priv->stations[sta_id].tid[tid].agg.state ==
1044 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1045 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1046 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1047 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1048 return 0;
1049 }
1050
1051 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1052 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1053
1054 tid_data = &priv->stations[sta_id].tid[tid];
1055 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1056 txq_id = tid_data->agg.txq_id;
1057 write_ptr = priv->txq[txq_id].q.write_ptr;
1058 read_ptr = priv->txq[txq_id].q.read_ptr;
1059
1060 /* The queue is not empty */
1061 if (write_ptr != read_ptr) {
1062 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1063 priv->stations[sta_id].tid[tid].agg.state =
1064 IWL_EMPTYING_HW_QUEUE_DELBA;
1065 return 0;
1066 }
1067
1068 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1069 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1070
1071 spin_lock_irqsave(&priv->lock, flags);
1072 /*
1073 * the only reason this call can fail is queue number out of range,
1074 * which can happen if uCode is reloaded and all the station
1075 * information are lost. if it is outside the range, there is no need
1076 * to deactivate the uCode queue, just return "success" to allow
1077 * mac80211 to clean up it own data.
1078 */
1079 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
1080 tx_fifo_id);
1081 spin_unlock_irqrestore(&priv->lock, flags);
1082
1083 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1084
1085 return 0;
1086}
1087
1088int iwlagn_txq_check_empty(struct iwl_priv *priv,
1089 int sta_id, u8 tid, int txq_id)
1090{
1091 struct iwl_queue *q = &priv->txq[txq_id].q;
1092 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1093 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1094
1095 switch (priv->stations[sta_id].tid[tid].agg.state) {
1096 case IWL_EMPTYING_HW_QUEUE_DELBA:
1097 /* We are reclaiming the last packet of the */
1098 /* aggregated HW queue */
1099 if ((txq_id == tid_data->agg.txq_id) &&
1100 (q->read_ptr == q->write_ptr)) {
1101 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1102 int tx_fifo = get_fifo_from_tid(tid);
1103 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1104 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1105 ssn, tx_fifo);
1106 tid_data->agg.state = IWL_AGG_OFF;
1107 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1108 }
1109 break;
1110 case IWL_EMPTYING_HW_QUEUE_ADDBA:
1111 /* We are reclaiming the last packet of the queue */
1112 if (tid_data->tfds_in_queue == 0) {
1113 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
1114 tid_data->agg.state = IWL_AGG_ON;
1115 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1116 }
1117 break;
1118 }
1119 return 0;
1120}
1121
1122static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
1123{
1124 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1125 struct ieee80211_sta *sta;
1126 struct iwl_station_priv *sta_priv;
1127
1128 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
1129 if (sta) {
1130 sta_priv = (void *)sta->drv_priv;
1131 /* avoid atomic ops if this isn't a client */
1132 if (sta_priv->client &&
1133 atomic_dec_return(&sta_priv->pending_frames) == 0)
1134 ieee80211_sta_block_awake(priv->hw, sta, false);
1135 }
1136
1137 ieee80211_tx_status_irqsafe(priv->hw, skb);
1138}
1139
1140int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1141{
1142 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1143 struct iwl_queue *q = &txq->q;
1144 struct iwl_tx_info *tx_info;
1145 int nfreed = 0;
1146 struct ieee80211_hdr *hdr;
1147
1148 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1149 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
1150 "is out of range [0-%d] %d %d.\n", txq_id,
1151 index, q->n_bd, q->write_ptr, q->read_ptr);
1152 return 0;
1153 }
1154
1155 for (index = iwl_queue_inc_wrap(index, q->n_bd);
1156 q->read_ptr != index;
1157 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1158
1159 tx_info = &txq->txb[txq->q.read_ptr];
1160 iwlagn_tx_status(priv, tx_info->skb[0]);
1161
1162 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
1163 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1164 nfreed++;
1165 tx_info->skb[0] = NULL;
1166
1167 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1168 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1169
1170 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1171 }
1172 return nfreed;
1173}
1174
1175/**
1176 * iwlagn_tx_status_reply_compressed_ba - Update tx status from block-ack
1177 *
1178 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1179 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1180 */
1181static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1182 struct iwl_ht_agg *agg,
1183 struct iwl_compressed_ba_resp *ba_resp)
1184
1185{
1186 int i, sh, ack;
1187 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1188 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1189 u64 bitmap;
1190 int successes = 0;
1191 struct ieee80211_tx_info *info;
1192
1193 if (unlikely(!agg->wait_for_ba)) {
1194 IWL_ERR(priv, "Received BA when not expected\n");
1195 return -EINVAL;
1196 }
1197
1198 /* Mark that the expected block-ack response arrived */
1199 agg->wait_for_ba = 0;
1200 IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1201
1202 /* Calculate shift to align block-ack bits with our Tx window bits */
1203 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1204 if (sh < 0) /* tbw something is wrong with indices */
1205 sh += 0x100;
1206
1207 /* don't use 64-bit values for now */
1208 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1209
1210 if (agg->frame_count > (64 - sh)) {
1211 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1212 return -1;
1213 }
1214
1215 /* check for success or failure according to the
1216 * transmitted bitmap and block-ack bitmap */
1217 bitmap &= agg->bitmap;
1218
1219 /* For each frame attempted in aggregation,
1220 * update driver's record of tx frame's status. */
1221 for (i = 0; i < agg->frame_count ; i++) {
1222 ack = bitmap & (1ULL << i);
1223 successes += !!ack;
1224 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1225 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
1226 agg->start_idx + i);
1227 }
1228
1229 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1230 memset(&info->status, 0, sizeof(info->status));
1231 info->flags |= IEEE80211_TX_STAT_ACK;
1232 info->flags |= IEEE80211_TX_STAT_AMPDU;
1233 info->status.ampdu_ack_len = successes;
1234 info->status.ampdu_ack_map = bitmap;
1235 info->status.ampdu_len = agg->frame_count;
1236 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1237
1238 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1239
1240 return 0;
1241}
1242
1243/**
1244 * translate ucode response to mac80211 tx status control values
1245 */
1246void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
1247 struct ieee80211_tx_info *info)
1248{
1249 struct ieee80211_tx_rate *r = &info->control.rates[0];
1250
1251 info->antenna_sel_tx =
1252 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
1253 if (rate_n_flags & RATE_MCS_HT_MSK)
1254 r->flags |= IEEE80211_TX_RC_MCS;
1255 if (rate_n_flags & RATE_MCS_GF_MSK)
1256 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
1257 if (rate_n_flags & RATE_MCS_HT40_MSK)
1258 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
1259 if (rate_n_flags & RATE_MCS_DUP_MSK)
1260 r->flags |= IEEE80211_TX_RC_DUP_DATA;
1261 if (rate_n_flags & RATE_MCS_SGI_MSK)
1262 r->flags |= IEEE80211_TX_RC_SHORT_GI;
1263 r->idx = iwlagn_hwrate_to_mac80211_idx(rate_n_flags, info->band);
1264}
1265
1266/**
1267 * iwlagn_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1268 *
1269 * Handles block-acknowledge notification from device, which reports success
1270 * of frames sent via aggregation.
1271 */
1272void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1273 struct iwl_rx_mem_buffer *rxb)
1274{
1275 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1276 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1277 struct iwl_tx_queue *txq = NULL;
1278 struct iwl_ht_agg *agg;
1279 int index;
1280 int sta_id;
1281 int tid;
1282
1283 /* "flow" corresponds to Tx queue */
1284 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1285
1286 /* "ssn" is start of block-ack Tx window, corresponds to index
1287 * (in Tx queue's circular buffer) of first TFD/frame in window */
1288 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1289
1290 if (scd_flow >= priv->hw_params.max_txq_num) {
1291 IWL_ERR(priv,
1292 "BUG_ON scd_flow is bigger than number of queues\n");
1293 return;
1294 }
1295
1296 txq = &priv->txq[scd_flow];
1297 sta_id = ba_resp->sta_id;
1298 tid = ba_resp->tid;
1299 agg = &priv->stations[sta_id].tid[tid].agg;
1300
1301 /* Find index just before block-ack window */
1302 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1303
1304 /* TODO: Need to get this copy more safely - now good for debug */
1305
1306 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1307 "sta_id = %d\n",
1308 agg->wait_for_ba,
1309 (u8 *) &ba_resp->sta_addr_lo32,
1310 ba_resp->sta_id);
1311 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
1312 "%d, scd_ssn = %d\n",
1313 ba_resp->tid,
1314 ba_resp->seq_ctl,
1315 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1316 ba_resp->scd_flow,
1317 ba_resp->scd_ssn);
1318 IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx\n",
1319 agg->start_idx,
1320 (unsigned long long)agg->bitmap);
1321
1322 /* Update driver's record of ACK vs. not for each frame in window */
1323 iwlagn_tx_status_reply_compressed_ba(priv, agg, ba_resp);
1324
1325 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1326 * block-ack window (we assume that they've been successfully
1327 * transmitted ... if not, it's too late anyway). */
1328 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1329 /* calculate mac80211 ampdu sw queue to wake */
1330 int freed = iwlagn_tx_queue_reclaim(priv, scd_flow, index);
1331 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1332
1333 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1334 priv->mac80211_registered &&
1335 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1336 iwl_wake_queue(priv, txq->swq_id);
1337
1338 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1339 }
1340}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
new file mode 100644
index 000000000000..637286c396fe
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -0,0 +1,425 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h"
40#include "iwl-agn.h"
41
42static const s8 iwlagn_default_queue_to_tx_fifo[] = {
43 IWL_TX_FIFO_VO,
44 IWL_TX_FIFO_VI,
45 IWL_TX_FIFO_BE,
46 IWL_TX_FIFO_BK,
47 IWLAGN_CMD_FIFO_NUM,
48 IWL_TX_FIFO_UNUSED,
49 IWL_TX_FIFO_UNUSED,
50 IWL_TX_FIFO_UNUSED,
51 IWL_TX_FIFO_UNUSED,
52 IWL_TX_FIFO_UNUSED,
53};
54
55static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
56 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
57 0, COEX_UNASSOC_IDLE_FLAGS},
58 {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
59 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
60 {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
61 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
62 {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
63 0, COEX_CALIBRATION_FLAGS},
64 {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
65 0, COEX_PERIODIC_CALIBRATION_FLAGS},
66 {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
67 0, COEX_CONNECTION_ESTAB_FLAGS},
68 {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
69 0, COEX_ASSOCIATED_IDLE_FLAGS},
70 {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
71 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
72 {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
73 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
74 {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
75 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
76 {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
77 {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
78 {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
79 0, COEX_STAND_ALONE_DEBUG_FLAGS},
80 {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
81 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
82 {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
83 {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
84};
85
86/*
87 * ucode
88 */
89static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
90 struct fw_desc *image, u32 dst_addr)
91{
92 dma_addr_t phy_addr = image->p_addr;
93 u32 byte_cnt = image->len;
94 int ret;
95
96 priv->ucode_write_complete = 0;
97
98 iwl_write_direct32(priv,
99 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
100 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
101
102 iwl_write_direct32(priv,
103 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
104
105 iwl_write_direct32(priv,
106 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
107 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
108
109 iwl_write_direct32(priv,
110 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
111 (iwl_get_dma_hi_addr(phy_addr)
112 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
113
114 iwl_write_direct32(priv,
115 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
116 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
117 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
118 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
119
120 iwl_write_direct32(priv,
121 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
122 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
123 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
124 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
125
126 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
127 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
128 priv->ucode_write_complete, 5 * HZ);
129 if (ret == -ERESTARTSYS) {
130 IWL_ERR(priv, "Could not load the %s uCode section due "
131 "to interrupt\n", name);
132 return ret;
133 }
134 if (!ret) {
135 IWL_ERR(priv, "Could not load the %s uCode section\n",
136 name);
137 return -ETIMEDOUT;
138 }
139
140 return 0;
141}
142
143static int iwlagn_load_given_ucode(struct iwl_priv *priv,
144 struct fw_desc *inst_image,
145 struct fw_desc *data_image)
146{
147 int ret = 0;
148
149 ret = iwlagn_load_section(priv, "INST", inst_image,
150 IWLAGN_RTC_INST_LOWER_BOUND);
151 if (ret)
152 return ret;
153
154 return iwlagn_load_section(priv, "DATA", data_image,
155 IWLAGN_RTC_DATA_LOWER_BOUND);
156}
157
158int iwlagn_load_ucode(struct iwl_priv *priv)
159{
160 int ret = 0;
161
162 /* check whether init ucode should be loaded, or rather runtime ucode */
163 if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
164 IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
165 ret = iwlagn_load_given_ucode(priv,
166 &priv->ucode_init, &priv->ucode_init_data);
167 if (!ret) {
168 IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
169 priv->ucode_type = UCODE_INIT;
170 }
171 } else {
172 IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
173 "Loading runtime ucode...\n");
174 ret = iwlagn_load_given_ucode(priv,
175 &priv->ucode_code, &priv->ucode_data);
176 if (!ret) {
177 IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
178 priv->ucode_type = UCODE_RT;
179 }
180 }
181
182 return ret;
183}
184
185/*
186 * Calibration
187 */
188static int iwlagn_set_Xtal_calib(struct iwl_priv *priv)
189{
190 struct iwl_calib_xtal_freq_cmd cmd;
191 __le16 *xtal_calib =
192 (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
193
194 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
195 cmd.hdr.first_group = 0;
196 cmd.hdr.groups_num = 1;
197 cmd.hdr.data_valid = 1;
198 cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
199 cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
200 return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
201 (u8 *)&cmd, sizeof(cmd));
202}
203
204static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
205{
206 struct iwl_calib_cfg_cmd calib_cfg_cmd;
207 struct iwl_host_cmd cmd = {
208 .id = CALIBRATION_CFG_CMD,
209 .len = sizeof(struct iwl_calib_cfg_cmd),
210 .data = &calib_cfg_cmd,
211 };
212
213 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
214 calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
215 calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
216 calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
217 calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
218
219 return iwl_send_cmd(priv, &cmd);
220}
221
222void iwlagn_rx_calib_result(struct iwl_priv *priv,
223 struct iwl_rx_mem_buffer *rxb)
224{
225 struct iwl_rx_packet *pkt = rxb_addr(rxb);
226 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
227 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
228 int index;
229
230 /* reduce the size of the length field itself */
231 len -= 4;
232
233 /* Define the order in which the results will be sent to the runtime
234 * uCode. iwl_send_calib_results sends them in a row according to
235 * their index. We sort them here
236 */
237 switch (hdr->op_code) {
238 case IWL_PHY_CALIBRATE_DC_CMD:
239 index = IWL_CALIB_DC;
240 break;
241 case IWL_PHY_CALIBRATE_LO_CMD:
242 index = IWL_CALIB_LO;
243 break;
244 case IWL_PHY_CALIBRATE_TX_IQ_CMD:
245 index = IWL_CALIB_TX_IQ;
246 break;
247 case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
248 index = IWL_CALIB_TX_IQ_PERD;
249 break;
250 case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
251 index = IWL_CALIB_BASE_BAND;
252 break;
253 default:
254 IWL_ERR(priv, "Unknown calibration notification %d\n",
255 hdr->op_code);
256 return;
257 }
258 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
259}
260
261void iwlagn_rx_calib_complete(struct iwl_priv *priv,
262 struct iwl_rx_mem_buffer *rxb)
263{
264 IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
265 queue_work(priv->workqueue, &priv->restart);
266}
267
268void iwlagn_init_alive_start(struct iwl_priv *priv)
269{
270 int ret = 0;
271
272 /* Check alive response for "valid" sign from uCode */
273 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
274 /* We had an error bringing up the hardware, so take it
275 * all the way back down so we can try again */
276 IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
277 goto restart;
278 }
279
280 /* initialize uCode was loaded... verify inst image.
281 * This is a paranoid check, because we would not have gotten the
282 * "initialize" alive if code weren't properly loaded. */
283 if (iwl_verify_ucode(priv)) {
284 /* Runtime instruction load was bad;
285 * take it all the way back down so we can try again */
286 IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
287 goto restart;
288 }
289
290 ret = priv->cfg->ops->lib->alive_notify(priv);
291 if (ret) {
292 IWL_WARN(priv,
293 "Could not complete ALIVE transition: %d\n", ret);
294 goto restart;
295 }
296
297 iwlagn_send_calib_cfg(priv);
298 return;
299
300restart:
301 /* real restart (first load init_ucode) */
302 queue_work(priv->workqueue, &priv->restart);
303}
304
305static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
306{
307 struct iwl_wimax_coex_cmd coex_cmd;
308
309 if (priv->cfg->support_wimax_coexist) {
310 /* UnMask wake up src at associated sleep */
311 coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
312
313 /* UnMask wake up src at unassociated sleep */
314 coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
315 memcpy(coex_cmd.sta_prio, cu_priorities,
316 sizeof(struct iwl_wimax_coex_event_entry) *
317 COEX_NUM_OF_EVENTS);
318
319 /* enabling the coexistence feature */
320 coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
321
322 /* enabling the priorities tables */
323 coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
324 } else {
325 /* coexistence is disabled */
326 memset(&coex_cmd, 0, sizeof(coex_cmd));
327 }
328 return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
329 sizeof(coex_cmd), &coex_cmd);
330}
331
332int iwlagn_alive_notify(struct iwl_priv *priv)
333{
334 u32 a;
335 unsigned long flags;
336 int i, chan;
337 u32 reg_val;
338
339 spin_lock_irqsave(&priv->lock, flags);
340
341 priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR);
342 a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_DATA_OFFSET;
343 for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_BITMAP_OFFSET;
344 a += 4)
345 iwl_write_targ_mem(priv, a, 0);
346 for (; a < priv->scd_base_addr + IWLAGN_SCD_TRANSLATE_TBL_OFFSET;
347 a += 4)
348 iwl_write_targ_mem(priv, a, 0);
349 for (; a < priv->scd_base_addr +
350 IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
351 iwl_write_targ_mem(priv, a, 0);
352
353 iwl_write_prph(priv, IWLAGN_SCD_DRAM_BASE_ADDR,
354 priv->scd_bc_tbls.dma >> 10);
355
356 /* Enable DMA channel */
357 for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
358 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
359 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
360 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
361
362 /* Update FH chicken bits */
363 reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
364 iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
365 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
366
367 iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
368 IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
369 iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
370
371 /* initiate the queues */
372 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
373 iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(i), 0);
374 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
375 iwl_write_targ_mem(priv, priv->scd_base_addr +
376 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
377 iwl_write_targ_mem(priv, priv->scd_base_addr +
378 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i) +
379 sizeof(u32),
380 ((SCD_WIN_SIZE <<
381 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
382 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
383 ((SCD_FRAME_LIMIT <<
384 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
385 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
386 }
387
388 iwl_write_prph(priv, IWLAGN_SCD_INTERRUPT_MASK,
389 IWL_MASK(0, priv->hw_params.max_txq_num));
390
391 /* Activate all Tx DMA/FIFO channels */
392 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
393
394 iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
395
396 /* make sure all queue are not stopped */
397 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
398 for (i = 0; i < 4; i++)
399 atomic_set(&priv->queue_stop_count[i], 0);
400
401 /* reset to 0 to enable all the queue first */
402 priv->txq_ctx_active_msk = 0;
403 /* map qos queues to fifos one-to-one */
404 BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
405
406 for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) {
407 int ac = iwlagn_default_queue_to_tx_fifo[i];
408
409 iwl_txq_ctx_activate(priv, i);
410
411 if (ac == IWL_TX_FIFO_UNUSED)
412 continue;
413
414 iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
415 }
416
417 spin_unlock_irqrestore(&priv->lock, flags);
418
419 iwlagn_send_wimax_coex(priv);
420
421 iwlagn_set_Xtal_calib(priv);
422 iwl_send_calib_results(priv);
423
424 return 0;
425}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index bdff56583e11..aef4f71f1981 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -55,6 +55,7 @@
55#include "iwl-helpers.h" 55#include "iwl-helpers.h"
56#include "iwl-sta.h" 56#include "iwl-sta.h"
57#include "iwl-calib.h" 57#include "iwl-calib.h"
58#include "iwl-agn.h"
58 59
59 60
60/****************************************************************************** 61/******************************************************************************
@@ -83,13 +84,6 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
83MODULE_LICENSE("GPL"); 84MODULE_LICENSE("GPL");
84MODULE_ALIAS("iwl4965"); 85MODULE_ALIAS("iwl4965");
85 86
86/*************** STATION TABLE MANAGEMENT ****
87 * mac80211 should be examined to determine if sta_info is duplicating
88 * the functionality provided here
89 */
90
91/**************************************************************/
92
93/** 87/**
94 * iwl_commit_rxon - commit staging_rxon to hardware 88 * iwl_commit_rxon - commit staging_rxon to hardware
95 * 89 *
@@ -144,9 +138,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
144 return 0; 138 return 0;
145 } 139 }
146 140
147 /* station table will be cleared */
148 priv->assoc_station_added = 0;
149
150 /* If we are currently associated and the new config requires 141 /* If we are currently associated and the new config requires
151 * an RXON_ASSOC and the new config wants the associated mask enabled, 142 * an RXON_ASSOC and the new config wants the associated mask enabled,
152 * we must clear the associated from the active configuration 143 * we must clear the associated from the active configuration
@@ -166,6 +157,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
166 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); 157 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
167 return ret; 158 return ret;
168 } 159 }
160 iwl_clear_ucode_stations(priv);
161 iwl_restore_stations(priv);
162 ret = iwl_restore_default_wep_keys(priv);
163 if (ret) {
164 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
165 return ret;
166 }
169 } 167 }
170 168
171 IWL_DEBUG_INFO(priv, "Sending RXON\n" 169 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -179,9 +177,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
179 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); 177 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
180 178
181 /* Apply the new configuration 179 /* Apply the new configuration
182 * RXON unassoc clears the station table in uCode, send it before 180 * RXON unassoc clears the station table in uCode so restoration of
183 * we add the bcast station. If assoc bit is set, we will send RXON 181 * stations is needed after it (the RXON command) completes
184 * after having added the bcast and bssid station.
185 */ 182 */
186 if (!new_assoc) { 183 if (!new_assoc) {
187 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 184 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -190,35 +187,19 @@ int iwl_commit_rxon(struct iwl_priv *priv)
190 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 187 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
191 return ret; 188 return ret;
192 } 189 }
190 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
193 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 191 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
192 iwl_clear_ucode_stations(priv);
193 iwl_restore_stations(priv);
194 ret = iwl_restore_default_wep_keys(priv);
195 if (ret) {
196 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
197 return ret;
198 }
194 } 199 }
195 200
196 iwl_clear_stations_table(priv);
197
198 priv->start_calib = 0; 201 priv->start_calib = 0;
199
200 /* Add the broadcast address so we can send broadcast frames */
201 priv->cfg->ops->lib->add_bcast_station(priv);
202
203
204 /* If we have set the ASSOC_MSK and we are in BSS mode then
205 * add the IWL_AP_ID to the station rate table */
206 if (new_assoc) { 202 if (new_assoc) {
207 if (priv->iw_mode == NL80211_IFTYPE_STATION) {
208 ret = iwl_rxon_add_station(priv,
209 priv->active_rxon.bssid_addr, 1);
210 if (ret == IWL_INVALID_STATION) {
211 IWL_ERR(priv,
212 "Error adding AP address for TX.\n");
213 return -EIO;
214 }
215 priv->assoc_station_added = 1;
216 if (priv->default_wep_key &&
217 iwl_send_static_wepkey_cmd(priv, 0))
218 IWL_ERR(priv,
219 "Could not send WEP static key.\n");
220 }
221
222 /* 203 /*
223 * allow CTS-to-self if possible for new association. 204 * allow CTS-to-self if possible for new association.
224 * this is relevant only for 5000 series and up, 205 * this is relevant only for 5000 series and up,
@@ -907,10 +888,10 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
907 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = 888 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
908 iwl_rx_missed_beacon_notif; 889 iwl_rx_missed_beacon_notif;
909 /* Rx handlers */ 890 /* Rx handlers */
910 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; 891 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy;
911 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; 892 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx;
912 /* block ack */ 893 /* block ack */
913 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba; 894 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba;
914 /* Set up hardware specific Rx handlers */ 895 /* Set up hardware specific Rx handlers */
915 priv->cfg->ops->lib->rx_handler_setup(priv); 896 priv->cfg->ops->lib->rx_handler_setup(priv);
916} 897}
@@ -1038,7 +1019,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
1038 count++; 1019 count++;
1039 if (count >= 8) { 1020 if (count >= 8) {
1040 rxq->read = i; 1021 rxq->read = i;
1041 iwl_rx_replenish_now(priv); 1022 iwlagn_rx_replenish_now(priv);
1042 count = 0; 1023 count = 0;
1043 } 1024 }
1044 } 1025 }
@@ -1047,9 +1028,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
1047 /* Backtrack one entry */ 1028 /* Backtrack one entry */
1048 rxq->read = i; 1029 rxq->read = i;
1049 if (fill_rx) 1030 if (fill_rx)
1050 iwl_rx_replenish_now(priv); 1031 iwlagn_rx_replenish_now(priv);
1051 else 1032 else
1052 iwl_rx_queue_restock(priv); 1033 iwlagn_rx_queue_restock(priv);
1053} 1034}
1054 1035
1055/* call this function to flush any scheduled tasklet */ 1036/* call this function to flush any scheduled tasklet */
@@ -1267,9 +1248,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1267 * hardware bugs here by ACKing all the possible interrupts so that 1248 * hardware bugs here by ACKing all the possible interrupts so that
1268 * interrupt coalescing can still be achieved. 1249 * interrupt coalescing can still be achieved.
1269 */ 1250 */
1270 iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask); 1251 iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask);
1271 1252
1272 inta = priv->inta; 1253 inta = priv->_agn.inta;
1273 1254
1274#ifdef CONFIG_IWLWIFI_DEBUG 1255#ifdef CONFIG_IWLWIFI_DEBUG
1275 if (iwl_get_debug_level(priv) & IWL_DL_ISR) { 1256 if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
@@ -1282,8 +1263,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1282 1263
1283 spin_unlock_irqrestore(&priv->lock, flags); 1264 spin_unlock_irqrestore(&priv->lock, flags);
1284 1265
1285 /* saved interrupt in inta variable now we can reset priv->inta */ 1266 /* saved interrupt in inta variable now we can reset priv->_agn.inta */
1286 priv->inta = 0; 1267 priv->_agn.inta = 0;
1287 1268
1288 /* Now service all interrupt bits discovered above. */ 1269 /* Now service all interrupt bits discovered above. */
1289 if (inta & CSR_INT_BIT_HW_ERR) { 1270 if (inta & CSR_INT_BIT_HW_ERR) {
@@ -1448,6 +1429,60 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1448 iwl_enable_interrupts(priv); 1429 iwl_enable_interrupts(priv);
1449} 1430}
1450 1431
1432/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
1433#define ACK_CNT_RATIO (50)
1434#define BA_TIMEOUT_CNT (5)
1435#define BA_TIMEOUT_MAX (16)
1436
1437/**
1438 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
1439 *
1440 * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
1441 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
1442 * operation state.
1443 */
1444bool iwl_good_ack_health(struct iwl_priv *priv,
1445 struct iwl_rx_packet *pkt)
1446{
1447 bool rc = true;
1448 int actual_ack_cnt_delta, expected_ack_cnt_delta;
1449 int ba_timeout_delta;
1450
1451 actual_ack_cnt_delta =
1452 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
1453 le32_to_cpu(priv->statistics.tx.actual_ack_cnt);
1454 expected_ack_cnt_delta =
1455 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
1456 le32_to_cpu(priv->statistics.tx.expected_ack_cnt);
1457 ba_timeout_delta =
1458 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
1459 le32_to_cpu(priv->statistics.tx.agg.ba_timeout);
1460 if ((priv->_agn.agg_tids_count > 0) &&
1461 (expected_ack_cnt_delta > 0) &&
1462 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
1463 < ACK_CNT_RATIO) &&
1464 (ba_timeout_delta > BA_TIMEOUT_CNT)) {
1465 IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d,"
1466 " expected_ack_cnt = %d\n",
1467 actual_ack_cnt_delta, expected_ack_cnt_delta);
1468
1469#ifdef CONFIG_IWLWIFI_DEBUG
1470 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
1471 priv->delta_statistics.tx.rx_detected_cnt);
1472 IWL_DEBUG_RADIO(priv,
1473 "ack_or_ba_timeout_collision delta = %d\n",
1474 priv->delta_statistics.tx.
1475 ack_or_ba_timeout_collision);
1476#endif
1477 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
1478 ba_timeout_delta);
1479 if (!actual_ack_cnt_delta &&
1480 (ba_timeout_delta >= BA_TIMEOUT_MAX))
1481 rc = false;
1482 }
1483 return rc;
1484}
1485
1451 1486
1452/****************************************************************************** 1487/******************************************************************************
1453 * 1488 *
@@ -1471,9 +1506,13 @@ static void iwl_nic_start(struct iwl_priv *priv)
1471 iwl_write32(priv, CSR_RESET, 0); 1506 iwl_write32(priv, CSR_RESET, 0);
1472} 1507}
1473 1508
1509struct iwlagn_ucode_capabilities {
1510 u32 max_probe_length;
1511};
1474 1512
1475static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); 1513static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
1476static int iwl_mac_setup_register(struct iwl_priv *priv); 1514static int iwl_mac_setup_register(struct iwl_priv *priv,
1515 struct iwlagn_ucode_capabilities *capa);
1477 1516
1478static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) 1517static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
1479{ 1518{
@@ -1500,6 +1539,199 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
1500 iwl_ucode_callback); 1539 iwl_ucode_callback);
1501} 1540}
1502 1541
1542struct iwlagn_firmware_pieces {
1543 const void *inst, *data, *init, *init_data, *boot;
1544 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1545
1546 u32 build;
1547};
1548
1549static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
1550 const struct firmware *ucode_raw,
1551 struct iwlagn_firmware_pieces *pieces)
1552{
1553 struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
1554 u32 api_ver, hdr_size;
1555 const u8 *src;
1556
1557 priv->ucode_ver = le32_to_cpu(ucode->ver);
1558 api_ver = IWL_UCODE_API(priv->ucode_ver);
1559
1560 switch (api_ver) {
1561 default:
1562 /*
1563 * 4965 doesn't revision the firmware file format
1564 * along with the API version, it always uses v1
1565 * file format.
1566 */
1567 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
1568 CSR_HW_REV_TYPE_4965) {
1569 hdr_size = 28;
1570 if (ucode_raw->size < hdr_size) {
1571 IWL_ERR(priv, "File size too small!\n");
1572 return -EINVAL;
1573 }
1574 pieces->build = le32_to_cpu(ucode->u.v2.build);
1575 pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
1576 pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
1577 pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
1578 pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
1579 pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
1580 src = ucode->u.v2.data;
1581 break;
1582 }
1583 /* fall through for 4965 */
1584 case 0:
1585 case 1:
1586 case 2:
1587 hdr_size = 24;
1588 if (ucode_raw->size < hdr_size) {
1589 IWL_ERR(priv, "File size too small!\n");
1590 return -EINVAL;
1591 }
1592 pieces->build = 0;
1593 pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
1594 pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
1595 pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
1596 pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
1597 pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
1598 src = ucode->u.v1.data;
1599 break;
1600 }
1601
1602 /* Verify size of file vs. image size info in file's header */
1603 if (ucode_raw->size != hdr_size + pieces->inst_size +
1604 pieces->data_size + pieces->init_size +
1605 pieces->init_data_size + pieces->boot_size) {
1606
1607 IWL_ERR(priv,
1608 "uCode file size %d does not match expected size\n",
1609 (int)ucode_raw->size);
1610 return -EINVAL;
1611 }
1612
1613 pieces->inst = src;
1614 src += pieces->inst_size;
1615 pieces->data = src;
1616 src += pieces->data_size;
1617 pieces->init = src;
1618 src += pieces->init_size;
1619 pieces->init_data = src;
1620 src += pieces->init_data_size;
1621 pieces->boot = src;
1622 src += pieces->boot_size;
1623
1624 return 0;
1625}
1626
1627static int iwlagn_wanted_ucode_alternative = 1;
1628
1629static int iwlagn_load_firmware(struct iwl_priv *priv,
1630 const struct firmware *ucode_raw,
1631 struct iwlagn_firmware_pieces *pieces,
1632 struct iwlagn_ucode_capabilities *capa)
1633{
1634 struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
1635 struct iwl_ucode_tlv *tlv;
1636 size_t len = ucode_raw->size;
1637 const u8 *data;
1638 int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
1639 u64 alternatives;
1640
1641 if (len < sizeof(*ucode))
1642 return -EINVAL;
1643
1644 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC))
1645 return -EINVAL;
1646
1647 /*
1648 * Check which alternatives are present, and "downgrade"
1649 * when the chosen alternative is not present, warning
1650 * the user when that happens. Some files may not have
1651 * any alternatives, so don't warn in that case.
1652 */
1653 alternatives = le64_to_cpu(ucode->alternatives);
1654 tmp = wanted_alternative;
1655 if (wanted_alternative > 63)
1656 wanted_alternative = 63;
1657 while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
1658 wanted_alternative--;
1659 if (wanted_alternative && wanted_alternative != tmp)
1660 IWL_WARN(priv,
1661 "uCode alternative %d not available, choosing %d\n",
1662 tmp, wanted_alternative);
1663
1664 priv->ucode_ver = le32_to_cpu(ucode->ver);
1665 pieces->build = le32_to_cpu(ucode->build);
1666 data = ucode->data;
1667
1668 len -= sizeof(*ucode);
1669
1670 while (len >= sizeof(*tlv)) {
1671 u32 tlv_len;
1672 enum iwl_ucode_tlv_type tlv_type;
1673 u16 tlv_alt;
1674 const u8 *tlv_data;
1675
1676 len -= sizeof(*tlv);
1677 tlv = (void *)data;
1678
1679 tlv_len = le32_to_cpu(tlv->length);
1680 tlv_type = le16_to_cpu(tlv->type);
1681 tlv_alt = le16_to_cpu(tlv->alternative);
1682 tlv_data = tlv->data;
1683
1684 if (len < tlv_len)
1685 return -EINVAL;
1686 len -= ALIGN(tlv_len, 4);
1687 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
1688
1689 /*
1690 * Alternative 0 is always valid.
1691 *
1692 * Skip alternative TLVs that are not selected.
1693 */
1694 if (tlv_alt != 0 && tlv_alt != wanted_alternative)
1695 continue;
1696
1697 switch (tlv_type) {
1698 case IWL_UCODE_TLV_INST:
1699 pieces->inst = tlv_data;
1700 pieces->inst_size = tlv_len;
1701 break;
1702 case IWL_UCODE_TLV_DATA:
1703 pieces->data = tlv_data;
1704 pieces->data_size = tlv_len;
1705 break;
1706 case IWL_UCODE_TLV_INIT:
1707 pieces->init = tlv_data;
1708 pieces->init_size = tlv_len;
1709 break;
1710 case IWL_UCODE_TLV_INIT_DATA:
1711 pieces->init_data = tlv_data;
1712 pieces->init_data_size = tlv_len;
1713 break;
1714 case IWL_UCODE_TLV_BOOT:
1715 pieces->boot = tlv_data;
1716 pieces->boot_size = tlv_len;
1717 break;
1718 case IWL_UCODE_TLV_PROBE_MAX_LEN:
1719 if (tlv_len != 4)
1720 return -EINVAL;
1721 capa->max_probe_length =
1722 le32_to_cpup((__le32 *)tlv_data);
1723 break;
1724 default:
1725 break;
1726 }
1727 }
1728
1729 if (len)
1730 return -EINVAL;
1731
1732 return 0;
1733}
1734
1503/** 1735/**
1504 * iwl_ucode_callback - callback when firmware was loaded 1736 * iwl_ucode_callback - callback when firmware was loaded
1505 * 1737 *
@@ -1510,14 +1742,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1510{ 1742{
1511 struct iwl_priv *priv = context; 1743 struct iwl_priv *priv = context;
1512 struct iwl_ucode_header *ucode; 1744 struct iwl_ucode_header *ucode;
1745 int err;
1746 struct iwlagn_firmware_pieces pieces;
1513 const unsigned int api_max = priv->cfg->ucode_api_max; 1747 const unsigned int api_max = priv->cfg->ucode_api_max;
1514 const unsigned int api_min = priv->cfg->ucode_api_min; 1748 const unsigned int api_min = priv->cfg->ucode_api_min;
1515 u8 *src; 1749 u32 api_ver;
1516 size_t len; 1750 char buildstr[25];
1517 u32 api_ver, build; 1751 u32 build;
1518 u32 inst_size, data_size, init_size, init_data_size, boot_size; 1752 struct iwlagn_ucode_capabilities ucode_capa = {
1519 int err; 1753 .max_probe_length = 200,
1520 u16 eeprom_ver; 1754 };
1755
1756 memset(&pieces, 0, sizeof(pieces));
1521 1757
1522 if (!ucode_raw) { 1758 if (!ucode_raw) {
1523 IWL_ERR(priv, "request for firmware file '%s' failed.\n", 1759 IWL_ERR(priv, "request for firmware file '%s' failed.\n",
@@ -1528,8 +1764,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1528 IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", 1764 IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
1529 priv->firmware_name, ucode_raw->size); 1765 priv->firmware_name, ucode_raw->size);
1530 1766
1531 /* Make sure that we got at least the v1 header! */ 1767 /* Make sure that we got at least the API version number */
1532 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { 1768 if (ucode_raw->size < 4) {
1533 IWL_ERR(priv, "File size way too small!\n"); 1769 IWL_ERR(priv, "File size way too small!\n");
1534 goto try_again; 1770 goto try_again;
1535 } 1771 }
@@ -1537,21 +1773,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1537 /* Data from ucode file: header followed by uCode images */ 1773 /* Data from ucode file: header followed by uCode images */
1538 ucode = (struct iwl_ucode_header *)ucode_raw->data; 1774 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1539 1775
1540 priv->ucode_ver = le32_to_cpu(ucode->ver); 1776 if (ucode->ver)
1777 err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
1778 else
1779 err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
1780 &ucode_capa);
1781
1782 if (err)
1783 goto try_again;
1784
1541 api_ver = IWL_UCODE_API(priv->ucode_ver); 1785 api_ver = IWL_UCODE_API(priv->ucode_ver);
1542 build = priv->cfg->ops->ucode->get_build(ucode, api_ver); 1786 build = pieces.build;
1543 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
1544 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
1545 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
1546 init_data_size =
1547 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
1548 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
1549 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
1550
1551 /* api_ver should match the api version forming part of the
1552 * firmware filename ... but we don't check for that and only rely
1553 * on the API version read from firmware header from here on forward */
1554 1787
1788 /*
1789 * api_ver should match the api version forming part of the
1790 * firmware filename ... but we don't check for that and only rely
1791 * on the API version read from firmware header from here on forward
1792 */
1555 if (api_ver < api_min || api_ver > api_max) { 1793 if (api_ver < api_min || api_ver > api_max) {
1556 IWL_ERR(priv, "Driver unable to support your firmware API. " 1794 IWL_ERR(priv, "Driver unable to support your firmware API. "
1557 "Driver supports v%u, firmware is v%u.\n", 1795 "Driver supports v%u, firmware is v%u.\n",
@@ -1565,40 +1803,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1565 "from http://www.intellinuxwireless.org.\n", 1803 "from http://www.intellinuxwireless.org.\n",
1566 api_max, api_ver); 1804 api_max, api_ver);
1567 1805
1568 IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", 1806 if (build)
1569 IWL_UCODE_MAJOR(priv->ucode_ver), 1807 sprintf(buildstr, " build %u", build);
1570 IWL_UCODE_MINOR(priv->ucode_ver), 1808 else
1571 IWL_UCODE_API(priv->ucode_ver), 1809 buildstr[0] = '\0';
1572 IWL_UCODE_SERIAL(priv->ucode_ver)); 1810
1811 IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
1812 IWL_UCODE_MAJOR(priv->ucode_ver),
1813 IWL_UCODE_MINOR(priv->ucode_ver),
1814 IWL_UCODE_API(priv->ucode_ver),
1815 IWL_UCODE_SERIAL(priv->ucode_ver),
1816 buildstr);
1573 1817
1574 snprintf(priv->hw->wiphy->fw_version, 1818 snprintf(priv->hw->wiphy->fw_version,
1575 sizeof(priv->hw->wiphy->fw_version), 1819 sizeof(priv->hw->wiphy->fw_version),
1576 "%u.%u.%u.%u", 1820 "%u.%u.%u.%u%s",
1577 IWL_UCODE_MAJOR(priv->ucode_ver), 1821 IWL_UCODE_MAJOR(priv->ucode_ver),
1578 IWL_UCODE_MINOR(priv->ucode_ver), 1822 IWL_UCODE_MINOR(priv->ucode_ver),
1579 IWL_UCODE_API(priv->ucode_ver), 1823 IWL_UCODE_API(priv->ucode_ver),
1580 IWL_UCODE_SERIAL(priv->ucode_ver)); 1824 IWL_UCODE_SERIAL(priv->ucode_ver),
1581 1825 buildstr);
1582 if (build)
1583 IWL_DEBUG_INFO(priv, "Build %u\n", build);
1584
1585 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
1586 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
1587 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
1588 ? "OTP" : "EEPROM", eeprom_ver);
1589
1590 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1591 priv->ucode_ver);
1592 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
1593 inst_size);
1594 IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
1595 data_size);
1596 IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
1597 init_size);
1598 IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
1599 init_data_size);
1600 IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
1601 boot_size);
1602 1826
1603 /* 1827 /*
1604 * For any of the failures below (before allocating pci memory) 1828 * For any of the failures below (before allocating pci memory)
@@ -1606,43 +1830,47 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1606 * user just got a corrupted version of the latest API. 1830 * user just got a corrupted version of the latest API.
1607 */ 1831 */
1608 1832
1609 /* Verify size of file vs. image size info in file's header */ 1833 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1610 if (ucode_raw->size != 1834 priv->ucode_ver);
1611 priv->cfg->ops->ucode->get_header_size(api_ver) + 1835 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
1612 inst_size + data_size + init_size + 1836 pieces.inst_size);
1613 init_data_size + boot_size) { 1837 IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
1614 1838 pieces.data_size);
1615 IWL_DEBUG_INFO(priv, 1839 IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
1616 "uCode file size %d does not match expected size\n", 1840 pieces.init_size);
1617 (int)ucode_raw->size); 1841 IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
1618 goto try_again; 1842 pieces.init_data_size);
1619 } 1843 IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
1844 pieces.boot_size);
1620 1845
1621 /* Verify that uCode images will fit in card's SRAM */ 1846 /* Verify that uCode images will fit in card's SRAM */
1622 if (inst_size > priv->hw_params.max_inst_size) { 1847 if (pieces.inst_size > priv->hw_params.max_inst_size) {
1623 IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", 1848 IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
1624 inst_size); 1849 pieces.inst_size);
1625 goto try_again; 1850 goto try_again;
1626 } 1851 }
1627 1852
1628 if (data_size > priv->hw_params.max_data_size) { 1853 if (pieces.data_size > priv->hw_params.max_data_size) {
1629 IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", 1854 IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
1630 data_size); 1855 pieces.data_size);
1631 goto try_again; 1856 goto try_again;
1632 } 1857 }
1633 if (init_size > priv->hw_params.max_inst_size) { 1858
1634 IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", 1859 if (pieces.init_size > priv->hw_params.max_inst_size) {
1635 init_size); 1860 IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
1861 pieces.init_size);
1636 goto try_again; 1862 goto try_again;
1637 } 1863 }
1638 if (init_data_size > priv->hw_params.max_data_size) { 1864
1639 IWL_INFO(priv, "uCode init data len %d too large to fit in\n", 1865 if (pieces.init_data_size > priv->hw_params.max_data_size) {
1640 init_data_size); 1866 IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
1867 pieces.init_data_size);
1641 goto try_again; 1868 goto try_again;
1642 } 1869 }
1643 if (boot_size > priv->hw_params.max_bsm_size) { 1870
1644 IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", 1871 if (pieces.boot_size > priv->hw_params.max_bsm_size) {
1645 boot_size); 1872 IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
1873 pieces.boot_size);
1646 goto try_again; 1874 goto try_again;
1647 } 1875 }
1648 1876
@@ -1651,13 +1879,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1651 /* Runtime instructions and 2 copies of data: 1879 /* Runtime instructions and 2 copies of data:
1652 * 1) unmodified from disk 1880 * 1) unmodified from disk
1653 * 2) backup cache for save/restore during power-downs */ 1881 * 2) backup cache for save/restore during power-downs */
1654 priv->ucode_code.len = inst_size; 1882 priv->ucode_code.len = pieces.inst_size;
1655 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); 1883 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
1656 1884
1657 priv->ucode_data.len = data_size; 1885 priv->ucode_data.len = pieces.data_size;
1658 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); 1886 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
1659 1887
1660 priv->ucode_data_backup.len = data_size; 1888 priv->ucode_data_backup.len = pieces.data_size;
1661 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); 1889 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
1662 1890
1663 if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || 1891 if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
@@ -1665,11 +1893,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1665 goto err_pci_alloc; 1893 goto err_pci_alloc;
1666 1894
1667 /* Initialization instructions and data */ 1895 /* Initialization instructions and data */
1668 if (init_size && init_data_size) { 1896 if (pieces.init_size && pieces.init_data_size) {
1669 priv->ucode_init.len = init_size; 1897 priv->ucode_init.len = pieces.init_size;
1670 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); 1898 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
1671 1899
1672 priv->ucode_init_data.len = init_data_size; 1900 priv->ucode_init_data.len = pieces.init_data_size;
1673 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); 1901 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
1674 1902
1675 if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) 1903 if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
@@ -1677,8 +1905,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1677 } 1905 }
1678 1906
1679 /* Bootstrap (instructions only, no data) */ 1907 /* Bootstrap (instructions only, no data) */
1680 if (boot_size) { 1908 if (pieces.boot_size) {
1681 priv->ucode_boot.len = boot_size; 1909 priv->ucode_boot.len = pieces.boot_size;
1682 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); 1910 iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
1683 1911
1684 if (!priv->ucode_boot.v_addr) 1912 if (!priv->ucode_boot.v_addr)
@@ -1688,51 +1916,48 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1688 /* Copy images into buffers for card's bus-master reads ... */ 1916 /* Copy images into buffers for card's bus-master reads ... */
1689 1917
1690 /* Runtime instructions (first block of data in file) */ 1918 /* Runtime instructions (first block of data in file) */
1691 len = inst_size; 1919 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
1692 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len); 1920 pieces.inst_size);
1693 memcpy(priv->ucode_code.v_addr, src, len); 1921 memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
1694 src += len;
1695 1922
1696 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", 1923 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
1697 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); 1924 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
1698 1925
1699 /* Runtime data (2nd block) 1926 /*
1700 * NOTE: Copy into backup buffer will be done in iwl_up() */ 1927 * Runtime data
1701 len = data_size; 1928 * NOTE: Copy into backup buffer will be done in iwl_up()
1702 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len); 1929 */
1703 memcpy(priv->ucode_data.v_addr, src, len); 1930 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
1704 memcpy(priv->ucode_data_backup.v_addr, src, len); 1931 pieces.data_size);
1705 src += len; 1932 memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
1706 1933 memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
1707 /* Initialization instructions (3rd block) */ 1934
1708 if (init_size) { 1935 /* Initialization instructions */
1709 len = init_size; 1936 if (pieces.init_size) {
1710 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", 1937 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
1711 len); 1938 pieces.init_size);
1712 memcpy(priv->ucode_init.v_addr, src, len); 1939 memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
1713 src += len;
1714 } 1940 }
1715 1941
1716 /* Initialization data (4th block) */ 1942 /* Initialization data */
1717 if (init_data_size) { 1943 if (pieces.init_data_size) {
1718 len = init_data_size;
1719 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", 1944 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
1720 len); 1945 pieces.init_data_size);
1721 memcpy(priv->ucode_init_data.v_addr, src, len); 1946 memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
1722 src += len; 1947 pieces.init_data_size);
1723 } 1948 }
1724 1949
1725 /* Bootstrap instructions (5th block) */ 1950 /* Bootstrap instructions */
1726 len = boot_size; 1951 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
1727 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); 1952 pieces.boot_size);
1728 memcpy(priv->ucode_boot.v_addr, src, len); 1953 memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
1729 1954
1730 /************************************************** 1955 /**************************************************
1731 * This is still part of probe() in a sense... 1956 * This is still part of probe() in a sense...
1732 * 1957 *
1733 * 9. Setup and register with mac80211 and debugfs 1958 * 9. Setup and register with mac80211 and debugfs
1734 **************************************************/ 1959 **************************************************/
1735 err = iwl_mac_setup_register(priv); 1960 err = iwl_mac_setup_register(priv, &ucode_capa);
1736 if (err) 1961 if (err)
1737 goto out_unbind; 1962 goto out_unbind;
1738 1963
@@ -1742,6 +1967,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1742 1967
1743 /* We have our copies now, allow OS release its copies */ 1968 /* We have our copies now, allow OS release its copies */
1744 release_firmware(ucode_raw); 1969 release_firmware(ucode_raw);
1970 complete(&priv->_agn.firmware_loading_complete);
1745 return; 1971 return;
1746 1972
1747 try_again: 1973 try_again:
@@ -1755,6 +1981,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1755 IWL_ERR(priv, "failed to allocate pci memory\n"); 1981 IWL_ERR(priv, "failed to allocate pci memory\n");
1756 iwl_dealloc_ucode_pci(priv); 1982 iwl_dealloc_ucode_pci(priv);
1757 out_unbind: 1983 out_unbind:
1984 complete(&priv->_agn.firmware_loading_complete);
1758 device_release_driver(&priv->pci_dev->dev); 1985 device_release_driver(&priv->pci_dev->dev);
1759 release_firmware(ucode_raw); 1986 release_firmware(ucode_raw);
1760} 1987}
@@ -1809,6 +2036,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1809 u32 data2, line; 2036 u32 data2, line;
1810 u32 desc, time, count, base, data1; 2037 u32 desc, time, count, base, data1;
1811 u32 blink1, blink2, ilink1, ilink2; 2038 u32 blink1, blink2, ilink1, ilink2;
2039 u32 pc, hcmd;
1812 2040
1813 if (priv->ucode_type == UCODE_INIT) 2041 if (priv->ucode_type == UCODE_INIT)
1814 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); 2042 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
@@ -1831,6 +2059,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1831 } 2059 }
1832 2060
1833 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); 2061 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
2062 pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
1834 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); 2063 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
1835 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); 2064 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
1836 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32)); 2065 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
@@ -1839,6 +2068,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1839 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32)); 2068 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
1840 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); 2069 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
1841 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); 2070 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
2071 hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32));
1842 2072
1843 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, 2073 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
1844 blink1, blink2, ilink1, ilink2); 2074 blink1, blink2, ilink1, ilink2);
@@ -1847,10 +2077,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1847 "data1 data2 line\n"); 2077 "data1 data2 line\n");
1848 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", 2078 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
1849 desc_lookup(desc), desc, time, data1, data2, line); 2079 desc_lookup(desc), desc, time, data1, data2, line);
1850 IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n"); 2080 IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n");
1851 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2, 2081 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
1852 ilink1, ilink2); 2082 pc, blink1, blink2, ilink1, ilink2, hcmd);
1853
1854} 2083}
1855 2084
1856#define EVENT_START_OFFSET (4 * sizeof(u32)) 2085#define EVENT_START_OFFSET (4 * sizeof(u32))
@@ -1966,9 +2195,6 @@ static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1966 return pos; 2195 return pos;
1967} 2196}
1968 2197
1969/* For sanity check only. Actual size is determined by uCode, typ. 512 */
1970#define MAX_EVENT_LOG_SIZE (512)
1971
1972#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) 2198#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1973 2199
1974int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, 2200int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
@@ -2001,16 +2227,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2001 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 2227 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
2002 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 2228 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
2003 2229
2004 if (capacity > MAX_EVENT_LOG_SIZE) { 2230 if (capacity > priv->cfg->max_event_log_size) {
2005 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 2231 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
2006 capacity, MAX_EVENT_LOG_SIZE); 2232 capacity, priv->cfg->max_event_log_size);
2007 capacity = MAX_EVENT_LOG_SIZE; 2233 capacity = priv->cfg->max_event_log_size;
2008 } 2234 }
2009 2235
2010 if (next_entry > MAX_EVENT_LOG_SIZE) { 2236 if (next_entry > priv->cfg->max_event_log_size) {
2011 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 2237 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
2012 next_entry, MAX_EVENT_LOG_SIZE); 2238 next_entry, priv->cfg->max_event_log_size);
2013 next_entry = MAX_EVENT_LOG_SIZE; 2239 next_entry = priv->cfg->max_event_log_size;
2014 } 2240 }
2015 2241
2016 size = num_wraps ? capacity : next_entry; 2242 size = num_wraps ? capacity : next_entry;
@@ -2095,7 +2321,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2095 goto restart; 2321 goto restart;
2096 } 2322 }
2097 2323
2098 iwl_clear_stations_table(priv);
2099 ret = priv->cfg->ops->lib->alive_notify(priv); 2324 ret = priv->cfg->ops->lib->alive_notify(priv);
2100 if (ret) { 2325 if (ret) {
2101 IWL_WARN(priv, 2326 IWL_WARN(priv,
@@ -2106,13 +2331,19 @@ static void iwl_alive_start(struct iwl_priv *priv)
2106 /* After the ALIVE response, we can send host commands to the uCode */ 2331 /* After the ALIVE response, we can send host commands to the uCode */
2107 set_bit(STATUS_ALIVE, &priv->status); 2332 set_bit(STATUS_ALIVE, &priv->status);
2108 2333
2334 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2335 /* Enable timer to monitor the driver queues */
2336 mod_timer(&priv->monitor_recover,
2337 jiffies +
2338 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2339 }
2340
2109 if (iwl_is_rfkill(priv)) 2341 if (iwl_is_rfkill(priv))
2110 return; 2342 return;
2111 2343
2112 ieee80211_wake_queues(priv->hw); 2344 ieee80211_wake_queues(priv->hw);
2113 2345
2114 priv->active_rate = priv->rates_mask; 2346 priv->active_rate = IWL_RATES_MASK;
2115 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
2116 2347
2117 /* Configure Tx antenna selection based on H/W config */ 2348 /* Configure Tx antenna selection based on H/W config */
2118 if (priv->cfg->ops->hcmd->set_tx_ant) 2349 if (priv->cfg->ops->hcmd->set_tx_ant)
@@ -2126,7 +2357,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2126 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2357 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2127 } else { 2358 } else {
2128 /* Initialize our rx_config data */ 2359 /* Initialize our rx_config data */
2129 iwl_connection_init_rx_config(priv, priv->iw_mode); 2360 iwl_connection_init_rx_config(priv, NULL);
2130 2361
2131 if (priv->cfg->ops->hcmd->set_rxon_chain) 2362 if (priv->cfg->ops->hcmd->set_rxon_chain)
2132 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2363 priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2135,7 +2366,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2135 } 2366 }
2136 2367
2137 /* Configure Bluetooth device coexistence support */ 2368 /* Configure Bluetooth device coexistence support */
2138 iwl_send_bt_config(priv); 2369 priv->cfg->ops->hcmd->send_bt_config(priv);
2139 2370
2140 iwl_reset_run_time_calib(priv); 2371 iwl_reset_run_time_calib(priv);
2141 2372
@@ -2152,18 +2383,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
2152 wake_up_interruptible(&priv->wait_command_queue); 2383 wake_up_interruptible(&priv->wait_command_queue);
2153 2384
2154 iwl_power_update_mode(priv, true); 2385 iwl_power_update_mode(priv, true);
2386 IWL_DEBUG_INFO(priv, "Updated power mode\n");
2155 2387
2156 /* reassociate for ADHOC mode */
2157 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
2158 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
2159 priv->vif);
2160 if (beacon)
2161 iwl_mac_beacon_update(priv->hw, beacon);
2162 }
2163
2164
2165 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2166 iwl_set_mode(priv, priv->iw_mode);
2167 2388
2168 return; 2389 return;
2169 2390
@@ -2183,7 +2404,9 @@ static void __iwl_down(struct iwl_priv *priv)
2183 if (!exit_pending) 2404 if (!exit_pending)
2184 set_bit(STATUS_EXIT_PENDING, &priv->status); 2405 set_bit(STATUS_EXIT_PENDING, &priv->status);
2185 2406
2186 iwl_clear_stations_table(priv); 2407 iwl_clear_ucode_stations(priv);
2408 iwl_dealloc_bcast_station(priv);
2409 iwl_clear_driver_stations(priv);
2187 2410
2188 /* Unblock any waiting calls */ 2411 /* Unblock any waiting calls */
2189 wake_up_interruptible_all(&priv->wait_command_queue); 2412 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2231,8 +2454,8 @@ static void __iwl_down(struct iwl_priv *priv)
2231 /* device going down, Stop using ICT table */ 2454 /* device going down, Stop using ICT table */
2232 iwl_disable_ict(priv); 2455 iwl_disable_ict(priv);
2233 2456
2234 iwl_txq_ctx_stop(priv); 2457 iwlagn_txq_ctx_stop(priv);
2235 iwl_rxq_stop(priv); 2458 iwlagn_rxq_stop(priv);
2236 2459
2237 /* Power-down device's busmaster DMA clocks */ 2460 /* Power-down device's busmaster DMA clocks */
2238 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); 2461 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
@@ -2292,7 +2515,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
2292{ 2515{
2293 int ret = 0; 2516 int ret = 0;
2294 2517
2295 IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n"); 2518 IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
2296 2519
2297 ret = iwl_set_hw_ready(priv); 2520 ret = iwl_set_hw_ready(priv);
2298 if (priv->hw_ready) 2521 if (priv->hw_ready)
@@ -2330,6 +2553,10 @@ static int __iwl_up(struct iwl_priv *priv)
2330 return -EIO; 2553 return -EIO;
2331 } 2554 }
2332 2555
2556 ret = iwl_alloc_bcast_station(priv, true);
2557 if (ret)
2558 return ret;
2559
2333 iwl_prepare_card_hw(priv); 2560 iwl_prepare_card_hw(priv);
2334 2561
2335 if (!priv->hw_ready) { 2562 if (!priv->hw_ready) {
@@ -2353,7 +2580,7 @@ static int __iwl_up(struct iwl_priv *priv)
2353 2580
2354 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2581 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2355 2582
2356 ret = iwl_hw_nic_init(priv); 2583 ret = iwlagn_hw_nic_init(priv);
2357 if (ret) { 2584 if (ret) {
2358 IWL_ERR(priv, "Unable to init nic\n"); 2585 IWL_ERR(priv, "Unable to init nic\n");
2359 return ret; 2586 return ret;
@@ -2380,8 +2607,6 @@ static int __iwl_up(struct iwl_priv *priv)
2380 2607
2381 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2608 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2382 2609
2383 iwl_clear_stations_table(priv);
2384
2385 /* load bootstrap state machine, 2610 /* load bootstrap state machine,
2386 * load bootstrap program into processor's memory, 2611 * load bootstrap program into processor's memory,
2387 * prepare to load the "initialize" uCode */ 2612 * prepare to load the "initialize" uCode */
@@ -2467,7 +2692,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2467 } 2692 }
2468 2693
2469 mutex_unlock(&priv->mutex); 2694 mutex_unlock(&priv->mutex);
2470 return;
2471} 2695}
2472 2696
2473static void iwl_bg_restart(struct work_struct *data) 2697static void iwl_bg_restart(struct work_struct *data)
@@ -2505,34 +2729,28 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
2505 return; 2729 return;
2506 2730
2507 mutex_lock(&priv->mutex); 2731 mutex_lock(&priv->mutex);
2508 iwl_rx_replenish(priv); 2732 iwlagn_rx_replenish(priv);
2509 mutex_unlock(&priv->mutex); 2733 mutex_unlock(&priv->mutex);
2510} 2734}
2511 2735
2512#define IWL_DELAY_NEXT_SCAN (HZ*2) 2736#define IWL_DELAY_NEXT_SCAN (HZ*2)
2513 2737
2514void iwl_post_associate(struct iwl_priv *priv) 2738void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
2515{ 2739{
2516 struct ieee80211_conf *conf = NULL; 2740 struct ieee80211_conf *conf = NULL;
2517 int ret = 0; 2741 int ret = 0;
2518 unsigned long flags;
2519 2742
2520 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2743 if (!vif || !priv->is_open)
2744 return;
2745
2746 if (vif->type == NL80211_IFTYPE_AP) {
2521 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 2747 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2522 return; 2748 return;
2523 } 2749 }
2524 2750
2525 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2526 priv->assoc_id, priv->active_rxon.bssid_addr);
2527
2528
2529 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2751 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2530 return; 2752 return;
2531 2753
2532
2533 if (!priv->vif || !priv->is_open)
2534 return;
2535
2536 iwl_scan_cancel_timeout(priv, 200); 2754 iwl_scan_cancel_timeout(priv, 200);
2537 2755
2538 conf = ieee80211_get_hw_conf(priv->hw); 2756 conf = ieee80211_get_hw_conf(priv->hw);
@@ -2540,7 +2758,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2540 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2758 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2541 iwlcore_commit_rxon(priv); 2759 iwlcore_commit_rxon(priv);
2542 2760
2543 iwl_setup_rxon_timing(priv); 2761 iwl_setup_rxon_timing(priv, vif);
2544 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 2762 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
2545 sizeof(priv->rxon_timing), &priv->rxon_timing); 2763 sizeof(priv->rxon_timing), &priv->rxon_timing);
2546 if (ret) 2764 if (ret)
@@ -2554,56 +2772,44 @@ void iwl_post_associate(struct iwl_priv *priv)
2554 if (priv->cfg->ops->hcmd->set_rxon_chain) 2772 if (priv->cfg->ops->hcmd->set_rxon_chain)
2555 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2773 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2556 2774
2557 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 2775 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
2558 2776
2559 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 2777 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2560 priv->assoc_id, priv->beacon_int); 2778 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2561 2779
2562 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 2780 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2563 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 2781 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2564 else 2782 else
2565 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 2783 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2566 2784
2567 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 2785 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
2568 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 2786 if (vif->bss_conf.assoc_capability &
2787 WLAN_CAPABILITY_SHORT_SLOT_TIME)
2569 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 2788 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2570 else 2789 else
2571 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 2790 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2572 2791
2573 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 2792 if (vif->type == NL80211_IFTYPE_ADHOC)
2574 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 2793 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2575
2576 } 2794 }
2577 2795
2578 iwlcore_commit_rxon(priv); 2796 iwlcore_commit_rxon(priv);
2579 2797
2580 switch (priv->iw_mode) { 2798 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2799 vif->bss_conf.aid, priv->active_rxon.bssid_addr);
2800
2801 switch (vif->type) {
2581 case NL80211_IFTYPE_STATION: 2802 case NL80211_IFTYPE_STATION:
2582 break; 2803 break;
2583
2584 case NL80211_IFTYPE_ADHOC: 2804 case NL80211_IFTYPE_ADHOC:
2585
2586 /* assume default assoc id */
2587 priv->assoc_id = 1;
2588
2589 iwl_rxon_add_station(priv, priv->bssid, 0);
2590 iwl_send_beacon_cmd(priv); 2805 iwl_send_beacon_cmd(priv);
2591
2592 break; 2806 break;
2593
2594 default: 2807 default:
2595 IWL_ERR(priv, "%s Should not be called in %d mode\n", 2808 IWL_ERR(priv, "%s Should not be called in %d mode\n",
2596 __func__, priv->iw_mode); 2809 __func__, vif->type);
2597 break; 2810 break;
2598 } 2811 }
2599 2812
2600 if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
2601 priv->assoc_station_added = 1;
2602
2603 spin_lock_irqsave(&priv->lock, flags);
2604 iwl_activate_qos(priv, 0);
2605 spin_unlock_irqrestore(&priv->lock, flags);
2606
2607 /* the chain noise calibration will enabled PM upon completion 2813 /* the chain noise calibration will enabled PM upon completion
2608 * If chain noise has already been run, then we need to enable 2814 * If chain noise has already been run, then we need to enable
2609 * power management here */ 2815 * power management here */
@@ -2628,7 +2834,8 @@ void iwl_post_associate(struct iwl_priv *priv)
2628 * Not a mac80211 entry point function, but it fits in with all the 2834 * Not a mac80211 entry point function, but it fits in with all the
2629 * other mac80211 functions grouped here. 2835 * other mac80211 functions grouped here.
2630 */ 2836 */
2631static int iwl_mac_setup_register(struct iwl_priv *priv) 2837static int iwl_mac_setup_register(struct iwl_priv *priv,
2838 struct iwlagn_ucode_capabilities *capa)
2632{ 2839{
2633 int ret; 2840 int ret;
2634 struct ieee80211_hw *hw = priv->hw; 2841 struct ieee80211_hw *hw = priv->hw;
@@ -2636,7 +2843,6 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2636 2843
2637 /* Tell mac80211 our characteristics */ 2844 /* Tell mac80211 our characteristics */
2638 hw->flags = IEEE80211_HW_SIGNAL_DBM | 2845 hw->flags = IEEE80211_HW_SIGNAL_DBM |
2639 IEEE80211_HW_NOISE_DBM |
2640 IEEE80211_HW_AMPDU_AGGREGATION | 2846 IEEE80211_HW_AMPDU_AGGREGATION |
2641 IEEE80211_HW_SPECTRUM_MGMT; 2847 IEEE80211_HW_SPECTRUM_MGMT;
2642 2848
@@ -2649,6 +2855,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2649 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 2855 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2650 2856
2651 hw->sta_data_size = sizeof(struct iwl_station_priv); 2857 hw->sta_data_size = sizeof(struct iwl_station_priv);
2858 hw->vif_data_size = sizeof(struct iwl_vif_priv);
2859
2652 hw->wiphy->interface_modes = 2860 hw->wiphy->interface_modes =
2653 BIT(NL80211_IFTYPE_STATION) | 2861 BIT(NL80211_IFTYPE_STATION) |
2654 BIT(NL80211_IFTYPE_ADHOC); 2862 BIT(NL80211_IFTYPE_ADHOC);
@@ -2664,7 +2872,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)
2664 2872
2665 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 2873 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
2666 /* we create the 802.11 header and a zero-length SSID element */ 2874 /* we create the 802.11 header and a zero-length SSID element */
2667 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 2875 hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2;
2668 2876
2669 /* Default value; 4 EDCA QOS priorities */ 2877 /* Default value; 4 EDCA QOS priorities */
2670 hw->queues = 4; 2878 hw->queues = 4;
@@ -2770,17 +2978,16 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2770 IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, 2978 IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
2771 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); 2979 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
2772 2980
2773 if (iwl_tx_skb(priv, skb)) 2981 if (iwlagn_tx_skb(priv, skb))
2774 dev_kfree_skb_any(skb); 2982 dev_kfree_skb_any(skb);
2775 2983
2776 IWL_DEBUG_MACDUMP(priv, "leave\n"); 2984 IWL_DEBUG_MACDUMP(priv, "leave\n");
2777 return NETDEV_TX_OK; 2985 return NETDEV_TX_OK;
2778} 2986}
2779 2987
2780void iwl_config_ap(struct iwl_priv *priv) 2988void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
2781{ 2989{
2782 int ret = 0; 2990 int ret = 0;
2783 unsigned long flags;
2784 2991
2785 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2992 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2786 return; 2993 return;
@@ -2793,7 +3000,7 @@ void iwl_config_ap(struct iwl_priv *priv)
2793 iwlcore_commit_rxon(priv); 3000 iwlcore_commit_rxon(priv);
2794 3001
2795 /* RXON Timing */ 3002 /* RXON Timing */
2796 iwl_setup_rxon_timing(priv); 3003 iwl_setup_rxon_timing(priv, vif);
2797 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3004 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
2798 sizeof(priv->rxon_timing), &priv->rxon_timing); 3005 sizeof(priv->rxon_timing), &priv->rxon_timing);
2799 if (ret) 3006 if (ret)
@@ -2807,9 +3014,10 @@ void iwl_config_ap(struct iwl_priv *priv)
2807 if (priv->cfg->ops->hcmd->set_rxon_chain) 3014 if (priv->cfg->ops->hcmd->set_rxon_chain)
2808 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3015 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2809 3016
2810 /* FIXME: what should be the assoc_id for AP? */ 3017 priv->staging_rxon.assoc_id = 0;
2811 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3018
2812 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3019 if (vif->bss_conf.assoc_capability &
3020 WLAN_CAPABILITY_SHORT_PREAMBLE)
2813 priv->staging_rxon.flags |= 3021 priv->staging_rxon.flags |=
2814 RXON_FLG_SHORT_PREAMBLE_MSK; 3022 RXON_FLG_SHORT_PREAMBLE_MSK;
2815 else 3023 else
@@ -2817,26 +3025,21 @@ void iwl_config_ap(struct iwl_priv *priv)
2817 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3025 ~RXON_FLG_SHORT_PREAMBLE_MSK;
2818 3026
2819 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3027 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
2820 if (priv->assoc_capability & 3028 if (vif->bss_conf.assoc_capability &
2821 WLAN_CAPABILITY_SHORT_SLOT_TIME) 3029 WLAN_CAPABILITY_SHORT_SLOT_TIME)
2822 priv->staging_rxon.flags |= 3030 priv->staging_rxon.flags |=
2823 RXON_FLG_SHORT_SLOT_MSK; 3031 RXON_FLG_SHORT_SLOT_MSK;
2824 else 3032 else
2825 priv->staging_rxon.flags &= 3033 priv->staging_rxon.flags &=
2826 ~RXON_FLG_SHORT_SLOT_MSK; 3034 ~RXON_FLG_SHORT_SLOT_MSK;
2827 3035
2828 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3036 if (vif->type == NL80211_IFTYPE_ADHOC)
2829 priv->staging_rxon.flags &= 3037 priv->staging_rxon.flags &=
2830 ~RXON_FLG_SHORT_SLOT_MSK; 3038 ~RXON_FLG_SHORT_SLOT_MSK;
2831 } 3039 }
2832 /* restore RXON assoc */ 3040 /* restore RXON assoc */
2833 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3041 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2834 iwlcore_commit_rxon(priv); 3042 iwlcore_commit_rxon(priv);
2835 iwl_reset_qos(priv);
2836 spin_lock_irqsave(&priv->lock, flags);
2837 iwl_activate_qos(priv, 1);
2838 spin_unlock_irqrestore(&priv->lock, flags);
2839 iwl_add_bcast_station(priv);
2840 } 3043 }
2841 iwl_send_beacon_cmd(priv); 3044 iwl_send_beacon_cmd(priv);
2842 3045
@@ -2855,8 +3058,7 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2855 struct iwl_priv *priv = hw->priv; 3058 struct iwl_priv *priv = hw->priv;
2856 IWL_DEBUG_MAC80211(priv, "enter\n"); 3059 IWL_DEBUG_MAC80211(priv, "enter\n");
2857 3060
2858 iwl_update_tkip_key(priv, keyconf, 3061 iwl_update_tkip_key(priv, keyconf, sta,
2859 sta ? sta->addr : iwl_bcast_addr,
2860 iv32, phase1key); 3062 iv32, phase1key);
2861 3063
2862 IWL_DEBUG_MAC80211(priv, "leave\n"); 3064 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2868,7 +3070,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2868 struct ieee80211_key_conf *key) 3070 struct ieee80211_key_conf *key)
2869{ 3071{
2870 struct iwl_priv *priv = hw->priv; 3072 struct iwl_priv *priv = hw->priv;
2871 const u8 *addr;
2872 int ret; 3073 int ret;
2873 u8 sta_id; 3074 u8 sta_id;
2874 bool is_default_wep_key = false; 3075 bool is_default_wep_key = false;
@@ -2879,25 +3080,29 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2879 IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); 3080 IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
2880 return -EOPNOTSUPP; 3081 return -EOPNOTSUPP;
2881 } 3082 }
2882 addr = sta ? sta->addr : iwl_bcast_addr;
2883 sta_id = iwl_find_station(priv, addr);
2884 if (sta_id == IWL_INVALID_STATION) {
2885 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
2886 addr);
2887 return -EINVAL;
2888 3083
3084 if (sta) {
3085 sta_id = iwl_sta_id(sta);
3086
3087 if (sta_id == IWL_INVALID_STATION) {
3088 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3089 sta->addr);
3090 return -EINVAL;
3091 }
3092 } else {
3093 sta_id = priv->hw_params.bcast_sta_id;
2889 } 3094 }
2890 3095
2891 mutex_lock(&priv->mutex); 3096 mutex_lock(&priv->mutex);
2892 iwl_scan_cancel_timeout(priv, 100); 3097 iwl_scan_cancel_timeout(priv, 100);
2893 mutex_unlock(&priv->mutex);
2894 3098
2895 /* If we are getting WEP group key and we didn't receive any key mapping 3099 /*
3100 * If we are getting WEP group key and we didn't receive any key mapping
2896 * so far, we are in legacy wep mode (group key only), otherwise we are 3101 * so far, we are in legacy wep mode (group key only), otherwise we are
2897 * in 1X mode. 3102 * in 1X mode.
2898 * In legacy wep mode, we use another host command to the uCode */ 3103 * In legacy wep mode, we use another host command to the uCode.
2899 if (key->alg == ALG_WEP && sta_id == priv->hw_params.bcast_sta_id && 3104 */
2900 priv->iw_mode != NL80211_IFTYPE_AP) { 3105 if (key->alg == ALG_WEP && !sta && vif->type != NL80211_IFTYPE_AP) {
2901 if (cmd == SET_KEY) 3106 if (cmd == SET_KEY)
2902 is_default_wep_key = !priv->key_mapping_key; 3107 is_default_wep_key = !priv->key_mapping_key;
2903 else 3108 else
@@ -2926,6 +3131,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2926 ret = -EINVAL; 3131 ret = -EINVAL;
2927 } 3132 }
2928 3133
3134 mutex_unlock(&priv->mutex);
2929 IWL_DEBUG_MAC80211(priv, "leave\n"); 3135 IWL_DEBUG_MAC80211(priv, "leave\n");
2930 3136
2931 return ret; 3137 return ret;
@@ -2933,8 +3139,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2933 3139
2934static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 3140static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2935 struct ieee80211_vif *vif, 3141 struct ieee80211_vif *vif,
2936 enum ieee80211_ampdu_mlme_action action, 3142 enum ieee80211_ampdu_mlme_action action,
2937 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3143 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2938{ 3144{
2939 struct iwl_priv *priv = hw->priv; 3145 struct iwl_priv *priv = hw->priv;
2940 int ret; 3146 int ret;
@@ -2948,20 +3154,31 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2948 switch (action) { 3154 switch (action) {
2949 case IEEE80211_AMPDU_RX_START: 3155 case IEEE80211_AMPDU_RX_START:
2950 IWL_DEBUG_HT(priv, "start Rx\n"); 3156 IWL_DEBUG_HT(priv, "start Rx\n");
2951 return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn); 3157 return iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
2952 case IEEE80211_AMPDU_RX_STOP: 3158 case IEEE80211_AMPDU_RX_STOP:
2953 IWL_DEBUG_HT(priv, "stop Rx\n"); 3159 IWL_DEBUG_HT(priv, "stop Rx\n");
2954 ret = iwl_sta_rx_agg_stop(priv, sta->addr, tid); 3160 ret = iwl_sta_rx_agg_stop(priv, sta, tid);
2955 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3161 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2956 return 0; 3162 return 0;
2957 else 3163 else
2958 return ret; 3164 return ret;
2959 case IEEE80211_AMPDU_TX_START: 3165 case IEEE80211_AMPDU_TX_START:
2960 IWL_DEBUG_HT(priv, "start Tx\n"); 3166 IWL_DEBUG_HT(priv, "start Tx\n");
2961 return iwl_tx_agg_start(priv, sta->addr, tid, ssn); 3167 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
3168 if (ret == 0) {
3169 priv->_agn.agg_tids_count++;
3170 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
3171 priv->_agn.agg_tids_count);
3172 }
3173 return ret;
2962 case IEEE80211_AMPDU_TX_STOP: 3174 case IEEE80211_AMPDU_TX_STOP:
2963 IWL_DEBUG_HT(priv, "stop Tx\n"); 3175 IWL_DEBUG_HT(priv, "stop Tx\n");
2964 ret = iwl_tx_agg_stop(priv, sta->addr, tid); 3176 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
3177 if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
3178 priv->_agn.agg_tids_count--;
3179 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
3180 priv->_agn.agg_tids_count);
3181 }
2965 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3182 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2966 return 0; 3183 return 0;
2967 else 3184 else
@@ -2977,18 +3194,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2977 return 0; 3194 return 0;
2978} 3195}
2979 3196
2980static int iwl_mac_get_stats(struct ieee80211_hw *hw,
2981 struct ieee80211_low_level_stats *stats)
2982{
2983 struct iwl_priv *priv = hw->priv;
2984
2985 priv = hw->priv;
2986 IWL_DEBUG_MAC80211(priv, "enter\n");
2987 IWL_DEBUG_MAC80211(priv, "leave\n");
2988
2989 return 0;
2990}
2991
2992static void iwl_mac_sta_notify(struct ieee80211_hw *hw, 3197static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2993 struct ieee80211_vif *vif, 3198 struct ieee80211_vif *vif,
2994 enum sta_notify_cmd cmd, 3199 enum sta_notify_cmd cmd,
@@ -2998,18 +3203,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2998 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3203 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2999 int sta_id; 3204 int sta_id;
3000 3205
3001 /*
3002 * TODO: We really should use this callback to
3003 * actually maintain the station table in
3004 * the device.
3005 */
3006
3007 switch (cmd) { 3206 switch (cmd) {
3008 case STA_NOTIFY_ADD:
3009 atomic_set(&sta_priv->pending_frames, 0);
3010 if (vif->type == NL80211_IFTYPE_AP)
3011 sta_priv->client = true;
3012 break;
3013 case STA_NOTIFY_SLEEP: 3207 case STA_NOTIFY_SLEEP:
3014 WARN_ON(!sta_priv->client); 3208 WARN_ON(!sta_priv->client);
3015 sta_priv->asleep = true; 3209 sta_priv->asleep = true;
@@ -3021,7 +3215,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3021 if (!sta_priv->asleep) 3215 if (!sta_priv->asleep)
3022 break; 3216 break;
3023 sta_priv->asleep = false; 3217 sta_priv->asleep = false;
3024 sta_id = iwl_find_station(priv, sta->addr); 3218 sta_id = iwl_sta_id(sta);
3025 if (sta_id != IWL_INVALID_STATION) 3219 if (sta_id != IWL_INVALID_STATION)
3026 iwl_sta_modify_ps_wake(priv, sta_id); 3220 iwl_sta_modify_ps_wake(priv, sta_id);
3027 break; 3221 break;
@@ -3030,6 +3224,44 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3030 } 3224 }
3031} 3225}
3032 3226
3227static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3228 struct ieee80211_vif *vif,
3229 struct ieee80211_sta *sta)
3230{
3231 struct iwl_priv *priv = hw->priv;
3232 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
3233 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
3234 int ret;
3235 u8 sta_id;
3236
3237 sta_priv->common.sta_id = IWL_INVALID_STATION;
3238
3239 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3240 sta->addr);
3241
3242 atomic_set(&sta_priv->pending_frames, 0);
3243 if (vif->type == NL80211_IFTYPE_AP)
3244 sta_priv->client = true;
3245
3246 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3247 &sta_id);
3248 if (ret) {
3249 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3250 sta->addr, ret);
3251 /* Should we return success if return code is EEXIST ? */
3252 return ret;
3253 }
3254
3255 sta_priv->common.sta_id = sta_id;
3256
3257 /* Initialize rate scaling */
3258 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
3259 sta->addr);
3260 iwl_rs_rate_init(priv, sta, sta_id);
3261
3262 return 0;
3263}
3264
3033/***************************************************************************** 3265/*****************************************************************************
3034 * 3266 *
3035 * sysfs attributes 3267 * sysfs attributes
@@ -3130,125 +3362,6 @@ static ssize_t store_tx_power(struct device *d,
3130 3362
3131static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); 3363static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
3132 3364
3133static ssize_t show_flags(struct device *d,
3134 struct device_attribute *attr, char *buf)
3135{
3136 struct iwl_priv *priv = dev_get_drvdata(d);
3137
3138 return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
3139}
3140
3141static ssize_t store_flags(struct device *d,
3142 struct device_attribute *attr,
3143 const char *buf, size_t count)
3144{
3145 struct iwl_priv *priv = dev_get_drvdata(d);
3146 unsigned long val;
3147 u32 flags;
3148 int ret = strict_strtoul(buf, 0, &val);
3149 if (ret)
3150 return ret;
3151 flags = (u32)val;
3152
3153 mutex_lock(&priv->mutex);
3154 if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
3155 /* Cancel any currently running scans... */
3156 if (iwl_scan_cancel_timeout(priv, 100))
3157 IWL_WARN(priv, "Could not cancel scan.\n");
3158 else {
3159 IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
3160 priv->staging_rxon.flags = cpu_to_le32(flags);
3161 iwlcore_commit_rxon(priv);
3162 }
3163 }
3164 mutex_unlock(&priv->mutex);
3165
3166 return count;
3167}
3168
3169static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
3170
3171static ssize_t show_filter_flags(struct device *d,
3172 struct device_attribute *attr, char *buf)
3173{
3174 struct iwl_priv *priv = dev_get_drvdata(d);
3175
3176 return sprintf(buf, "0x%04X\n",
3177 le32_to_cpu(priv->active_rxon.filter_flags));
3178}
3179
3180static ssize_t store_filter_flags(struct device *d,
3181 struct device_attribute *attr,
3182 const char *buf, size_t count)
3183{
3184 struct iwl_priv *priv = dev_get_drvdata(d);
3185 unsigned long val;
3186 u32 filter_flags;
3187 int ret = strict_strtoul(buf, 0, &val);
3188 if (ret)
3189 return ret;
3190 filter_flags = (u32)val;
3191
3192 mutex_lock(&priv->mutex);
3193 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
3194 /* Cancel any currently running scans... */
3195 if (iwl_scan_cancel_timeout(priv, 100))
3196 IWL_WARN(priv, "Could not cancel scan.\n");
3197 else {
3198 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
3199 "0x%04X\n", filter_flags);
3200 priv->staging_rxon.filter_flags =
3201 cpu_to_le32(filter_flags);
3202 iwlcore_commit_rxon(priv);
3203 }
3204 }
3205 mutex_unlock(&priv->mutex);
3206
3207 return count;
3208}
3209
3210static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3211 store_filter_flags);
3212
3213
3214static ssize_t show_statistics(struct device *d,
3215 struct device_attribute *attr, char *buf)
3216{
3217 struct iwl_priv *priv = dev_get_drvdata(d);
3218 u32 size = sizeof(struct iwl_notif_statistics);
3219 u32 len = 0, ofs = 0;
3220 u8 *data = (u8 *)&priv->statistics;
3221 int rc = 0;
3222
3223 if (!iwl_is_alive(priv))
3224 return -EAGAIN;
3225
3226 mutex_lock(&priv->mutex);
3227 rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
3228 mutex_unlock(&priv->mutex);
3229
3230 if (rc) {
3231 len = sprintf(buf,
3232 "Error sending statistics request: 0x%08X\n", rc);
3233 return len;
3234 }
3235
3236 while (size && (PAGE_SIZE - len)) {
3237 hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
3238 PAGE_SIZE - len, 1);
3239 len = strlen(buf);
3240 if (PAGE_SIZE - len)
3241 buf[len++] = '\n';
3242
3243 ofs += 16;
3244 size -= min(size, 16U);
3245 }
3246
3247 return len;
3248}
3249
3250static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
3251
3252static ssize_t show_rts_ht_protection(struct device *d, 3365static ssize_t show_rts_ht_protection(struct device *d,
3253 struct device_attribute *attr, char *buf) 3366 struct device_attribute *attr, char *buf)
3254{ 3367{
@@ -3316,6 +3429,13 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3316 priv->ucode_trace.data = (unsigned long)priv; 3429 priv->ucode_trace.data = (unsigned long)priv;
3317 priv->ucode_trace.function = iwl_bg_ucode_trace; 3430 priv->ucode_trace.function = iwl_bg_ucode_trace;
3318 3431
3432 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3433 init_timer(&priv->monitor_recover);
3434 priv->monitor_recover.data = (unsigned long)priv;
3435 priv->monitor_recover.function =
3436 priv->cfg->ops->lib->recover_from_tx_stall;
3437 }
3438
3319 if (!priv->cfg->use_isr_legacy) 3439 if (!priv->cfg->use_isr_legacy)
3320 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3440 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3321 iwl_irq_tasklet, (unsigned long)priv); 3441 iwl_irq_tasklet, (unsigned long)priv);
@@ -3336,6 +3456,8 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3336 cancel_work_sync(&priv->beacon_update); 3456 cancel_work_sync(&priv->beacon_update);
3337 del_timer_sync(&priv->statistics_periodic); 3457 del_timer_sync(&priv->statistics_periodic);
3338 del_timer_sync(&priv->ucode_trace); 3458 del_timer_sync(&priv->ucode_trace);
3459 if (priv->cfg->ops->lib->recover_from_tx_stall)
3460 del_timer_sync(&priv->monitor_recover);
3339} 3461}
3340 3462
3341static void iwl_init_hw_rates(struct iwl_priv *priv, 3463static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3373,9 +3495,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3373 mutex_init(&priv->mutex); 3495 mutex_init(&priv->mutex);
3374 mutex_init(&priv->sync_cmd_mutex); 3496 mutex_init(&priv->sync_cmd_mutex);
3375 3497
3376 /* Clear the driver's (not device's) station table */
3377 iwl_clear_stations_table(priv);
3378
3379 priv->ieee_channels = NULL; 3498 priv->ieee_channels = NULL;
3380 priv->ieee_rates = NULL; 3499 priv->ieee_rates = NULL;
3381 priv->band = IEEE80211_BAND_2GHZ; 3500 priv->band = IEEE80211_BAND_2GHZ;
@@ -3383,6 +3502,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3383 priv->iw_mode = NL80211_IFTYPE_STATION; 3502 priv->iw_mode = NL80211_IFTYPE_STATION;
3384 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 3503 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3385 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3504 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3505 priv->_agn.agg_tids_count = 0;
3386 3506
3387 /* initialize force reset */ 3507 /* initialize force reset */
3388 priv->force_reset[IWL_RF_RESET].reset_duration = 3508 priv->force_reset[IWL_RF_RESET].reset_duration =
@@ -3396,16 +3516,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
3396 3516
3397 iwl_init_scan_params(priv); 3517 iwl_init_scan_params(priv);
3398 3518
3399 iwl_reset_qos(priv);
3400
3401 priv->qos_data.qos_active = 0;
3402 priv->qos_data.qos_cap.val = 0;
3403
3404 priv->rates_mask = IWL_RATES_MASK;
3405 /* Set the tx_power_user_lmt to the lowest power level 3519 /* Set the tx_power_user_lmt to the lowest power level
3406 * this value will get overwritten by channel max power avg 3520 * this value will get overwritten by channel max power avg
3407 * from eeprom */ 3521 * from eeprom */
3408 priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN; 3522 priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
3409 3523
3410 ret = iwl_init_channel_map(priv); 3524 ret = iwl_init_channel_map(priv);
3411 if (ret) { 3525 if (ret) {
@@ -3433,13 +3547,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
3433 iwl_calib_free_results(priv); 3547 iwl_calib_free_results(priv);
3434 iwlcore_free_geos(priv); 3548 iwlcore_free_geos(priv);
3435 iwl_free_channel_map(priv); 3549 iwl_free_channel_map(priv);
3436 kfree(priv->scan); 3550 kfree(priv->scan_cmd);
3437} 3551}
3438 3552
3439static struct attribute *iwl_sysfs_entries[] = { 3553static struct attribute *iwl_sysfs_entries[] = {
3440 &dev_attr_flags.attr,
3441 &dev_attr_filter_flags.attr,
3442 &dev_attr_statistics.attr,
3443 &dev_attr_temperature.attr, 3554 &dev_attr_temperature.attr,
3444 &dev_attr_tx_power.attr, 3555 &dev_attr_tx_power.attr,
3445 &dev_attr_rts_ht_protection.attr, 3556 &dev_attr_rts_ht_protection.attr,
@@ -3464,13 +3575,14 @@ static struct ieee80211_ops iwl_hw_ops = {
3464 .configure_filter = iwl_configure_filter, 3575 .configure_filter = iwl_configure_filter,
3465 .set_key = iwl_mac_set_key, 3576 .set_key = iwl_mac_set_key,
3466 .update_tkip_key = iwl_mac_update_tkip_key, 3577 .update_tkip_key = iwl_mac_update_tkip_key,
3467 .get_stats = iwl_mac_get_stats,
3468 .conf_tx = iwl_mac_conf_tx, 3578 .conf_tx = iwl_mac_conf_tx,
3469 .reset_tsf = iwl_mac_reset_tsf, 3579 .reset_tsf = iwl_mac_reset_tsf,
3470 .bss_info_changed = iwl_bss_info_changed, 3580 .bss_info_changed = iwl_bss_info_changed,
3471 .ampdu_action = iwl_mac_ampdu_action, 3581 .ampdu_action = iwl_mac_ampdu_action,
3472 .hw_scan = iwl_mac_hw_scan, 3582 .hw_scan = iwl_mac_hw_scan,
3473 .sta_notify = iwl_mac_sta_notify, 3583 .sta_notify = iwl_mac_sta_notify,
3584 .sta_add = iwlagn_mac_sta_add,
3585 .sta_remove = iwl_mac_sta_remove,
3474}; 3586};
3475 3587
3476static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3588static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -3574,7 +3686,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3574 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 3686 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
3575 3687
3576 iwl_hw_detect(priv); 3688 iwl_hw_detect(priv);
3577 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", 3689 IWL_INFO(priv, "Detected %s, REV=0x%X\n",
3578 priv->cfg->name, priv->hw_rev); 3690 priv->cfg->name, priv->hw_rev);
3579 3691
3580 /* We disable the RETRY_TIMEOUT register (0x41) to keep 3692 /* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3672,6 +3784,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3672 iwl_power_initialize(priv); 3784 iwl_power_initialize(priv);
3673 iwl_tt_initialize(priv); 3785 iwl_tt_initialize(priv);
3674 3786
3787 init_completion(&priv->_agn.firmware_loading_complete);
3788
3675 err = iwl_request_firmware(priv, true); 3789 err = iwl_request_firmware(priv, true);
3676 if (err) 3790 if (err)
3677 goto out_remove_sysfs; 3791 goto out_remove_sysfs;
@@ -3712,6 +3826,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3712 if (!priv) 3826 if (!priv)
3713 return; 3827 return;
3714 3828
3829 wait_for_completion(&priv->_agn.firmware_loading_complete);
3830
3715 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); 3831 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
3716 3832
3717 iwl_dbgfs_unregister(priv); 3833 iwl_dbgfs_unregister(priv);
@@ -3752,10 +3868,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3752 iwl_dealloc_ucode_pci(priv); 3868 iwl_dealloc_ucode_pci(priv);
3753 3869
3754 if (priv->rxq.bd) 3870 if (priv->rxq.bd)
3755 iwl_rx_queue_free(priv, &priv->rxq); 3871 iwlagn_rx_queue_free(priv, &priv->rxq);
3756 iwl_hw_txq_ctx_free(priv); 3872 iwlagn_hw_txq_ctx_free(priv);
3757 3873
3758 iwl_clear_stations_table(priv);
3759 iwl_eeprom_free(priv); 3874 iwl_eeprom_free(priv);
3760 3875
3761 3876
@@ -3870,6 +3985,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
3870 {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, 3985 {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
3871 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, 3986 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
3872 3987
3988/* 6x00 Series Gen2a */
3989 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
3990 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
3991 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
3992
3873/* 6x50 WiFi/WiMax Series */ 3993/* 6x50 WiFi/WiMax Series */
3874 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, 3994 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
3875 {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, 3995 {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)},
@@ -3951,3 +4071,38 @@ module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
3951MODULE_PARM_DESC(debug, "debug output mask"); 4071MODULE_PARM_DESC(debug, "debug output mask");
3952#endif 4072#endif
3953 4073
4074module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
4075MODULE_PARM_DESC(swcrypto50,
4076 "using crypto in software (default 0 [hardware]) (deprecated)");
4077module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
4078MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
4079module_param_named(queues_num50,
4080 iwlagn_mod_params.num_of_queues, int, S_IRUGO);
4081MODULE_PARM_DESC(queues_num50,
4082 "number of hw queues in 50xx series (deprecated)");
4083module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
4084MODULE_PARM_DESC(queues_num, "number of hw queues.");
4085module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
4086MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
4087module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
4088MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
4089module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
4090 int, S_IRUGO);
4091MODULE_PARM_DESC(amsdu_size_8K50,
4092 "enable 8K amsdu size in 50XX series (deprecated)");
4093module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
4094 int, S_IRUGO);
4095MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
4096module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
4097MODULE_PARM_DESC(fw_restart50,
4098 "restart firmware in case of error (deprecated)");
4099module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
4100MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
4101module_param_named(
4102 disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
4103MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
4104
4105module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
4106 S_IRUGO);
4107MODULE_PARM_DESC(ucode_alternative,
4108 "specify ucode alternative to use from ucode file");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
new file mode 100644
index 000000000000..2d748053358e
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -0,0 +1,181 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_agn_h__
64#define __iwl_agn_h__
65
66#include "iwl-dev.h"
67
68extern struct iwl_mod_params iwlagn_mod_params;
69extern struct iwl_hcmd_ops iwlagn_hcmd;
70extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
71
72int iwl_reset_ict(struct iwl_priv *priv);
73void iwl_disable_ict(struct iwl_priv *priv);
74int iwl_alloc_isr_ict(struct iwl_priv *priv);
75void iwl_free_isr_ict(struct iwl_priv *priv);
76irqreturn_t iwl_isr_ict(int irq, void *data);
77bool iwl_good_ack_health(struct iwl_priv *priv,
78 struct iwl_rx_packet *pkt);
79
80/* tx queue */
81void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
82 int txq_id, u32 index);
83void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
84 struct iwl_tx_queue *txq,
85 int tx_fifo_id, int scd_retry);
86void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
87 struct iwl_tx_queue *txq,
88 u16 byte_cnt);
89void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
90 struct iwl_tx_queue *txq);
91int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
92 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
93int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
94 u16 ssn_idx, u8 tx_fifo);
95void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
96
97/* uCode */
98int iwlagn_load_ucode(struct iwl_priv *priv);
99void iwlagn_rx_calib_result(struct iwl_priv *priv,
100 struct iwl_rx_mem_buffer *rxb);
101void iwlagn_rx_calib_complete(struct iwl_priv *priv,
102 struct iwl_rx_mem_buffer *rxb);
103void iwlagn_init_alive_start(struct iwl_priv *priv);
104int iwlagn_alive_notify(struct iwl_priv *priv);
105
106/* lib */
107void iwl_check_abort_status(struct iwl_priv *priv,
108 u8 frame_count, u32 status);
109void iwlagn_rx_handler_setup(struct iwl_priv *priv);
110void iwlagn_setup_deferred_work(struct iwl_priv *priv);
111int iwlagn_hw_valid_rtc_data_addr(u32 addr);
112int iwlagn_send_tx_power(struct iwl_priv *priv);
113void iwlagn_temperature(struct iwl_priv *priv);
114u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
115const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
116 size_t offset);
117void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
118int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
119int iwlagn_hw_nic_init(struct iwl_priv *priv);
120
121/* rx */
122void iwlagn_rx_queue_restock(struct iwl_priv *priv);
123void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
124void iwlagn_rx_replenish(struct iwl_priv *priv);
125void iwlagn_rx_replenish_now(struct iwl_priv *priv);
126void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
127int iwlagn_rxq_stop(struct iwl_priv *priv);
128int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
129void iwlagn_rx_reply_rx(struct iwl_priv *priv,
130 struct iwl_rx_mem_buffer *rxb);
131void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
132 struct iwl_rx_mem_buffer *rxb);
133
134/* tx */
135void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
136 struct ieee80211_tx_info *info);
137int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
138int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
139 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
140int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
141 struct ieee80211_sta *sta, u16 tid);
142int iwlagn_txq_check_empty(struct iwl_priv *priv,
143 int sta_id, u8 tid, int txq_id);
144void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
145 struct iwl_rx_mem_buffer *rxb);
146int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
147void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
148int iwlagn_txq_ctx_alloc(struct iwl_priv *priv);
149void iwlagn_txq_ctx_reset(struct iwl_priv *priv);
150void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
151
152static inline u32 iwl_tx_status_to_mac80211(u32 status)
153{
154 status &= TX_STATUS_MSK;
155
156 switch (status) {
157 case TX_STATUS_SUCCESS:
158 case TX_STATUS_DIRECT_DONE:
159 return IEEE80211_TX_STAT_ACK;
160 case TX_STATUS_FAIL_DEST_PS:
161 return IEEE80211_TX_STAT_TX_FILTERED;
162 default:
163 return 0;
164 }
165}
166
167static inline bool iwl_is_tx_success(u32 status)
168{
169 status &= TX_STATUS_MSK;
170 return (status == TX_STATUS_SUCCESS) ||
171 (status == TX_STATUS_DIRECT_DONE);
172}
173
174/* scan */
175void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
176
177/* station mgmt */
178int iwlagn_manage_ibss_station(struct iwl_priv *priv,
179 struct ieee80211_vif *vif, bool add);
180
181#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 8b516c5ff0bb..7e8227773213 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -593,7 +593,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
593 IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); 593 IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
594 594
595 if (!rx_enable_time) { 595 if (!rx_enable_time) {
596 IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0! \n"); 596 IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0!\n");
597 return; 597 return;
598 } 598 }
599 599
@@ -638,8 +638,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
638 iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); 638 iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
639 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); 639 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
640 iwl_sensitivity_write(priv); 640 iwl_sensitivity_write(priv);
641
642 return;
643} 641}
644EXPORT_SYMBOL(iwl_sensitivity_calibration); 642EXPORT_SYMBOL(iwl_sensitivity_calibration);
645 643
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index f4e59ae07f8e..9aab020c474b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -106,7 +106,7 @@ enum {
106 REPLY_TX = 0x1c, 106 REPLY_TX = 0x1c,
107 REPLY_RATE_SCALE = 0x47, /* 3945 only */ 107 REPLY_RATE_SCALE = 0x47, /* 3945 only */
108 REPLY_LEDS_CMD = 0x48, 108 REPLY_LEDS_CMD = 0x48,
109 REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ 109 REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */
110 110
111 /* WiMAX coexistence */ 111 /* WiMAX coexistence */
112 COEX_PRIORITY_TABLE_CMD = 0x5a, /* for 5000 series and up */ 112 COEX_PRIORITY_TABLE_CMD = 0x5a, /* for 5000 series and up */
@@ -512,8 +512,9 @@ struct iwl_init_alive_resp {
512 * 512 *
513 * Entries without timestamps contain only event_id and data. 513 * Entries without timestamps contain only event_id and data.
514 * 514 *
515 *
515 * 2) error_event_table_ptr indicates base of the error log. This contains 516 * 2) error_event_table_ptr indicates base of the error log. This contains
516 * information about any uCode error that occurs. For 4965, the format 517 * information about any uCode error that occurs. For agn, the format
517 * of the error log is: 518 * of the error log is:
518 * 519 *
519 * __le32 valid; (nonzero) valid, (0) log is empty 520 * __le32 valid; (nonzero) valid, (0) log is empty
@@ -529,6 +530,30 @@ struct iwl_init_alive_resp {
529 * __le32 bcon_time; beacon timer 530 * __le32 bcon_time; beacon timer
530 * __le32 tsf_low; network timestamp function timer 531 * __le32 tsf_low; network timestamp function timer
531 * __le32 tsf_hi; network timestamp function timer 532 * __le32 tsf_hi; network timestamp function timer
533 * __le32 gp1; GP1 timer register
534 * __le32 gp2; GP2 timer register
535 * __le32 gp3; GP3 timer register
536 * __le32 ucode_ver; uCode version
537 * __le32 hw_ver; HW Silicon version
538 * __le32 brd_ver; HW board version
539 * __le32 log_pc; log program counter
540 * __le32 frame_ptr; frame pointer
541 * __le32 stack_ptr; stack pointer
542 * __le32 hcmd; last host command
543 * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag
544 * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag
545 * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag
546 * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag
547 * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt
548 * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT
549 * __le32 wait_event; wait event() caller address
550 * __le32 l2p_control; L2pControlField
551 * __le32 l2p_duration; L2pDurationField
552 * __le32 l2p_mhvalid; L2pMhValidBits
553 * __le32 l2p_addr_match; L2pAddrMatchStat
554 * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
555 * __le32 u_timestamp; indicate when the date and time of the compilation
556 * __le32 reserved;
532 * 557 *
533 * The Linux driver can print both logs to the system log when a uCode error 558 * The Linux driver can print both logs to the system log when a uCode error
534 * occurs. 559 * occurs.
@@ -1418,7 +1443,7 @@ struct iwl4965_rx_mpdu_res_start {
1418 1443
1419/* 1: Ignore Bluetooth priority for this frame. 1444/* 1: Ignore Bluetooth priority for this frame.
1420 * 0: Delay Tx until Bluetooth device is done (normal usage). */ 1445 * 0: Delay Tx until Bluetooth device is done (normal usage). */
1421#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12) 1446#define TX_CMD_FLG_IGNORE_BT cpu_to_le32(1 << 12)
1422 1447
1423/* 1: uCode overrides sequence control field in MAC header. 1448/* 1: uCode overrides sequence control field in MAC header.
1424 * 0: Driver provides sequence control field in MAC header. 1449 * 0: Driver provides sequence control field in MAC header.
@@ -1637,7 +1662,7 @@ struct iwl_tx_cmd {
1637 struct ieee80211_hdr hdr[0]; 1662 struct ieee80211_hdr hdr[0];
1638} __attribute__ ((packed)); 1663} __attribute__ ((packed));
1639 1664
1640/* TX command response is sent after *all* transmission attempts. 1665/* TX command response is sent after *3945* transmission attempts.
1641 * 1666 *
1642 * NOTES: 1667 * NOTES:
1643 * 1668 *
@@ -1665,24 +1690,65 @@ struct iwl_tx_cmd {
1665 * control line. Receiving is still allowed in this case. 1690 * control line. Receiving is still allowed in this case.
1666 */ 1691 */
1667enum { 1692enum {
1693 TX_3945_STATUS_SUCCESS = 0x01,
1694 TX_3945_STATUS_DIRECT_DONE = 0x02,
1695 TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82,
1696 TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83,
1697 TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
1698 TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85,
1699 TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86,
1700 TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87,
1701 TX_3945_STATUS_FAIL_DEST_PS = 0x88,
1702 TX_3945_STATUS_FAIL_ABORTED = 0x89,
1703 TX_3945_STATUS_FAIL_BT_RETRY = 0x8a,
1704 TX_3945_STATUS_FAIL_STA_INVALID = 0x8b,
1705 TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c,
1706 TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d,
1707 TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
1708 TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
1709 TX_3945_STATUS_FAIL_TX_LOCKED = 0x90,
1710 TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
1711};
1712
1713/*
1714 * TX command response is sent after *agn* transmission attempts.
1715 *
1716 * both postpone and abort status are expected behavior from uCode. there is
1717 * no special operation required from driver; except for RFKILL_FLUSH,
1718 * which required tx flush host command to flush all the tx frames in queues
1719 */
1720enum {
1668 TX_STATUS_SUCCESS = 0x01, 1721 TX_STATUS_SUCCESS = 0x01,
1669 TX_STATUS_DIRECT_DONE = 0x02, 1722 TX_STATUS_DIRECT_DONE = 0x02,
1723 /* postpone TX */
1724 TX_STATUS_POSTPONE_DELAY = 0x40,
1725 TX_STATUS_POSTPONE_FEW_BYTES = 0x41,
1726 TX_STATUS_POSTPONE_BT_PRIO = 0x42,
1727 TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43,
1728 TX_STATUS_POSTPONE_CALC_TTAK = 0x44,
1729 /* abort TX */
1730 TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81,
1670 TX_STATUS_FAIL_SHORT_LIMIT = 0x82, 1731 TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
1671 TX_STATUS_FAIL_LONG_LIMIT = 0x83, 1732 TX_STATUS_FAIL_LONG_LIMIT = 0x83,
1672 TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, 1733 TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
1673 TX_STATUS_FAIL_MGMNT_ABORT = 0x85, 1734 TX_STATUS_FAIL_DRAIN_FLOW = 0x85,
1674 TX_STATUS_FAIL_NEXT_FRAG = 0x86, 1735 TX_STATUS_FAIL_RFKILL_FLUSH = 0x86,
1675 TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, 1736 TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
1676 TX_STATUS_FAIL_DEST_PS = 0x88, 1737 TX_STATUS_FAIL_DEST_PS = 0x88,
1677 TX_STATUS_FAIL_ABORTED = 0x89, 1738 TX_STATUS_FAIL_HOST_ABORTED = 0x89,
1678 TX_STATUS_FAIL_BT_RETRY = 0x8a, 1739 TX_STATUS_FAIL_BT_RETRY = 0x8a,
1679 TX_STATUS_FAIL_STA_INVALID = 0x8b, 1740 TX_STATUS_FAIL_STA_INVALID = 0x8b,
1680 TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, 1741 TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
1681 TX_STATUS_FAIL_TID_DISABLE = 0x8d, 1742 TX_STATUS_FAIL_TID_DISABLE = 0x8d,
1682 TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, 1743 TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e,
1683 TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, 1744 TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
1684 TX_STATUS_FAIL_TX_LOCKED = 0x90, 1745 /* uCode drop due to FW drop request */
1685 TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, 1746 TX_STATUS_FAIL_FW_DROP = 0x90,
1747 /*
1748 * uCode drop due to station color mismatch
1749 * between tx command and station table
1750 */
1751 TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP = 0x91,
1686}; 1752};
1687 1753
1688#define TX_PACKET_MODE_REGULAR 0x0000 1754#define TX_PACKET_MODE_REGULAR 0x0000
@@ -1704,30 +1770,6 @@ enum {
1704 TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ 1770 TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
1705}; 1771};
1706 1772
1707static inline u32 iwl_tx_status_to_mac80211(u32 status)
1708{
1709 status &= TX_STATUS_MSK;
1710
1711 switch (status) {
1712 case TX_STATUS_SUCCESS:
1713 case TX_STATUS_DIRECT_DONE:
1714 return IEEE80211_TX_STAT_ACK;
1715 case TX_STATUS_FAIL_DEST_PS:
1716 return IEEE80211_TX_STAT_TX_FILTERED;
1717 default:
1718 return 0;
1719 }
1720}
1721
1722static inline bool iwl_is_tx_success(u32 status)
1723{
1724 status &= TX_STATUS_MSK;
1725 return (status == TX_STATUS_SUCCESS) ||
1726 (status == TX_STATUS_DIRECT_DONE);
1727}
1728
1729
1730
1731/* ******************************* 1773/* *******************************
1732 * TX aggregation status 1774 * TX aggregation status
1733 ******************************* */ 1775 ******************************* */
@@ -2626,7 +2668,6 @@ struct iwl_ssid_ie {
2626#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) 2668#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff)
2627#define IWL_MAX_SCAN_SIZE 1024 2669#define IWL_MAX_SCAN_SIZE 1024
2628#define IWL_MAX_CMD_SIZE 4096 2670#define IWL_MAX_CMD_SIZE 4096
2629#define IWL_MAX_PROBE_REQUEST 200
2630 2671
2631/* 2672/*
2632 * REPLY_SCAN_CMD = 0x80 (command) 2673 * REPLY_SCAN_CMD = 0x80 (command)
@@ -3086,6 +3127,11 @@ struct statistics_tx {
3086 __le32 cts_timeout_collision; 3127 __le32 cts_timeout_collision;
3087 __le32 ack_or_ba_timeout_collision; 3128 __le32 ack_or_ba_timeout_collision;
3088 struct statistics_tx_non_phy_agg agg; 3129 struct statistics_tx_non_phy_agg agg;
3130 /*
3131 * "tx_power" are optional parameters provided by uCode,
3132 * 6000 series is the only device provide the information,
3133 * Those are reserved fields for all the other devices
3134 */
3089 struct statistics_tx_power tx_power; 3135 struct statistics_tx_power tx_power;
3090 __le32 reserved1; 3136 __le32 reserved1;
3091} __attribute__ ((packed)); 3137} __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 049b652bcb5e..5a7eca8fb789 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -66,38 +66,7 @@ MODULE_LICENSE("GPL");
66 */ 66 */
67static bool bt_coex_active = true; 67static bool bt_coex_active = true;
68module_param(bt_coex_active, bool, S_IRUGO); 68module_param(bt_coex_active, bool, S_IRUGO);
69MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n"); 69MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
70
71static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
72 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
73 0, COEX_UNASSOC_IDLE_FLAGS},
74 {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
75 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
76 {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
77 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
78 {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
79 0, COEX_CALIBRATION_FLAGS},
80 {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
81 0, COEX_PERIODIC_CALIBRATION_FLAGS},
82 {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
83 0, COEX_CONNECTION_ESTAB_FLAGS},
84 {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
85 0, COEX_ASSOCIATED_IDLE_FLAGS},
86 {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
87 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
88 {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
89 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
90 {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
91 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
92 {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
93 {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
94 {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
95 0, COEX_STAND_ALONE_DEBUG_FLAGS},
96 {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
97 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
98 {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
99 {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
100};
101 70
102#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ 71#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
103 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 72 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -115,8 +84,6 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
115u32 iwl_debug_level; 84u32 iwl_debug_level;
116EXPORT_SYMBOL(iwl_debug_level); 85EXPORT_SYMBOL(iwl_debug_level);
117 86
118static irqreturn_t iwl_isr(int irq, void *data);
119
120/* 87/*
121 * Parameter order: 88 * Parameter order:
122 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate 89 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
@@ -143,30 +110,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
143}; 110};
144EXPORT_SYMBOL(iwl_rates); 111EXPORT_SYMBOL(iwl_rates);
145 112
146/**
147 * translate ucode response to mac80211 tx status control values
148 */
149void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
150 struct ieee80211_tx_info *info)
151{
152 struct ieee80211_tx_rate *r = &info->control.rates[0];
153
154 info->antenna_sel_tx =
155 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
156 if (rate_n_flags & RATE_MCS_HT_MSK)
157 r->flags |= IEEE80211_TX_RC_MCS;
158 if (rate_n_flags & RATE_MCS_GF_MSK)
159 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
160 if (rate_n_flags & RATE_MCS_HT40_MSK)
161 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
162 if (rate_n_flags & RATE_MCS_DUP_MSK)
163 r->flags |= IEEE80211_TX_RC_DUP_DATA;
164 if (rate_n_flags & RATE_MCS_SGI_MSK)
165 r->flags |= IEEE80211_TX_RC_SHORT_GI;
166 r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band);
167}
168EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
169
170int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) 113int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
171{ 114{
172 int idx = 0; 115 int idx = 0;
@@ -198,27 +141,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
198} 141}
199EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 142EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
200 143
201int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
202{
203 int idx = 0;
204 int band_offset = 0;
205
206 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
207 if (rate_n_flags & RATE_MCS_HT_MSK) {
208 idx = (rate_n_flags & 0xff);
209 return idx;
210 /* Legacy rate format, search for match in table */
211 } else {
212 if (band == IEEE80211_BAND_5GHZ)
213 band_offset = IWL_FIRST_OFDM_RATE;
214 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
215 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
216 return idx - band_offset;
217 }
218
219 return -1;
220}
221
222u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 144u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
223{ 145{
224 int i; 146 int i;
@@ -268,74 +190,16 @@ void iwl_hw_detect(struct iwl_priv *priv)
268} 190}
269EXPORT_SYMBOL(iwl_hw_detect); 191EXPORT_SYMBOL(iwl_hw_detect);
270 192
271int iwl_hw_nic_init(struct iwl_priv *priv)
272{
273 unsigned long flags;
274 struct iwl_rx_queue *rxq = &priv->rxq;
275 int ret;
276
277 /* nic_init */
278 spin_lock_irqsave(&priv->lock, flags);
279 priv->cfg->ops->lib->apm_ops.init(priv);
280
281 /* Set interrupt coalescing calibration timer to default (512 usecs) */
282 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
283
284 spin_unlock_irqrestore(&priv->lock, flags);
285
286 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
287
288 priv->cfg->ops->lib->apm_ops.config(priv);
289
290 /* Allocate the RX queue, or reset if it is already allocated */
291 if (!rxq->bd) {
292 ret = iwl_rx_queue_alloc(priv);
293 if (ret) {
294 IWL_ERR(priv, "Unable to initialize Rx queue\n");
295 return -ENOMEM;
296 }
297 } else
298 iwl_rx_queue_reset(priv, rxq);
299
300 iwl_rx_replenish(priv);
301
302 iwl_rx_init(priv, rxq);
303
304 spin_lock_irqsave(&priv->lock, flags);
305
306 rxq->need_update = 1;
307 iwl_rx_queue_update_write_ptr(priv, rxq);
308
309 spin_unlock_irqrestore(&priv->lock, flags);
310
311 /* Allocate or reset and init all Tx and Command queues */
312 if (!priv->txq) {
313 ret = iwl_txq_ctx_alloc(priv);
314 if (ret)
315 return ret;
316 } else
317 iwl_txq_ctx_reset(priv);
318
319 set_bit(STATUS_INIT, &priv->status);
320
321 return 0;
322}
323EXPORT_SYMBOL(iwl_hw_nic_init);
324
325/* 193/*
326 * QoS support 194 * QoS support
327*/ 195*/
328void iwl_activate_qos(struct iwl_priv *priv, u8 force) 196static void iwl_update_qos(struct iwl_priv *priv)
329{ 197{
330 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 198 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
331 return; 199 return;
332 200
333 priv->qos_data.def_qos_parm.qos_flags = 0; 201 priv->qos_data.def_qos_parm.qos_flags = 0;
334 202
335 if (priv->qos_data.qos_cap.q_AP.queue_request &&
336 !priv->qos_data.qos_cap.q_AP.txop_request)
337 priv->qos_data.def_qos_parm.qos_flags |=
338 QOS_PARAM_FLG_TXOP_TYPE_MSK;
339 if (priv->qos_data.qos_active) 203 if (priv->qos_data.qos_active)
340 priv->qos_data.def_qos_parm.qos_flags |= 204 priv->qos_data.def_qos_parm.qos_flags |=
341 QOS_PARAM_FLG_UPDATE_EDCA_MSK; 205 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
@@ -343,118 +207,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
343 if (priv->current_ht_config.is_ht) 207 if (priv->current_ht_config.is_ht)
344 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; 208 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
345 209
346 if (force || iwl_is_associated(priv)) { 210 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
347 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", 211 priv->qos_data.qos_active,
348 priv->qos_data.qos_active, 212 priv->qos_data.def_qos_parm.qos_flags);
349 priv->qos_data.def_qos_parm.qos_flags);
350 213
351 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, 214 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
352 sizeof(struct iwl_qosparam_cmd), 215 sizeof(struct iwl_qosparam_cmd),
353 &priv->qos_data.def_qos_parm, NULL); 216 &priv->qos_data.def_qos_parm, NULL);
354 }
355} 217}
356EXPORT_SYMBOL(iwl_activate_qos);
357
358/*
359 * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
360 * (802.11b) (802.11a/g)
361 * AC_BK 15 1023 7 0 0
362 * AC_BE 15 1023 3 0 0
363 * AC_VI 7 15 2 6.016ms 3.008ms
364 * AC_VO 3 7 2 3.264ms 1.504ms
365 */
366void iwl_reset_qos(struct iwl_priv *priv)
367{
368 u16 cw_min = 15;
369 u16 cw_max = 1023;
370 u8 aifs = 2;
371 bool is_legacy = false;
372 unsigned long flags;
373 int i;
374
375 spin_lock_irqsave(&priv->lock, flags);
376 /* QoS always active in AP and ADHOC mode
377 * In STA mode wait for association
378 */
379 if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
380 priv->iw_mode == NL80211_IFTYPE_AP)
381 priv->qos_data.qos_active = 1;
382 else
383 priv->qos_data.qos_active = 0;
384
385 /* check for legacy mode */
386 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
387 (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
388 (priv->iw_mode == NL80211_IFTYPE_STATION &&
389 (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
390 cw_min = 31;
391 is_legacy = 1;
392 }
393
394 if (priv->qos_data.qos_active)
395 aifs = 3;
396
397 /* AC_BE */
398 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
399 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
400 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
401 priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
402 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
403
404 if (priv->qos_data.qos_active) {
405 /* AC_BK */
406 i = 1;
407 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
408 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
409 priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
410 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
411 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
412
413 /* AC_VI */
414 i = 2;
415 priv->qos_data.def_qos_parm.ac[i].cw_min =
416 cpu_to_le16((cw_min + 1) / 2 - 1);
417 priv->qos_data.def_qos_parm.ac[i].cw_max =
418 cpu_to_le16(cw_min);
419 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
420 if (is_legacy)
421 priv->qos_data.def_qos_parm.ac[i].edca_txop =
422 cpu_to_le16(6016);
423 else
424 priv->qos_data.def_qos_parm.ac[i].edca_txop =
425 cpu_to_le16(3008);
426 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
427
428 /* AC_VO */
429 i = 3;
430 priv->qos_data.def_qos_parm.ac[i].cw_min =
431 cpu_to_le16((cw_min + 1) / 4 - 1);
432 priv->qos_data.def_qos_parm.ac[i].cw_max =
433 cpu_to_le16((cw_min + 1) / 2 - 1);
434 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
435 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
436 if (is_legacy)
437 priv->qos_data.def_qos_parm.ac[i].edca_txop =
438 cpu_to_le16(3264);
439 else
440 priv->qos_data.def_qos_parm.ac[i].edca_txop =
441 cpu_to_le16(1504);
442 } else {
443 for (i = 1; i < 4; i++) {
444 priv->qos_data.def_qos_parm.ac[i].cw_min =
445 cpu_to_le16(cw_min);
446 priv->qos_data.def_qos_parm.ac[i].cw_max =
447 cpu_to_le16(cw_max);
448 priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
449 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
450 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
451 }
452 }
453 IWL_DEBUG_QOS(priv, "set QoS to default \n");
454
455 spin_unlock_irqrestore(&priv->lock, flags);
456}
457EXPORT_SYMBOL(iwl_reset_qos);
458 218
459#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 219#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
460#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 220#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
@@ -721,7 +481,7 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
721 return new_val; 481 return new_val;
722} 482}
723 483
724void iwl_setup_rxon_timing(struct iwl_priv *priv) 484void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
725{ 485{
726 u64 tsf; 486 u64 tsf;
727 s32 interval_tm, rem; 487 s32 interval_tm, rem;
@@ -735,15 +495,14 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv)
735 priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); 495 priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
736 priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); 496 priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
737 497
738 if (priv->iw_mode == NL80211_IFTYPE_STATION) { 498 beacon_int = vif->bss_conf.beacon_int;
739 beacon_int = priv->beacon_int;
740 priv->rxon_timing.atim_window = 0;
741 } else {
742 beacon_int = priv->vif->bss_conf.beacon_int;
743 499
500 if (vif->type == NL80211_IFTYPE_ADHOC) {
744 /* TODO: we need to get atim_window from upper stack 501 /* TODO: we need to get atim_window from upper stack
745 * for now we set to 0 */ 502 * for now we set to 0 */
746 priv->rxon_timing.atim_window = 0; 503 priv->rxon_timing.atim_window = 0;
504 } else {
505 priv->rxon_timing.atim_window = 0;
747 } 506 }
748 507
749 beacon_int = iwl_adjust_beacon_interval(beacon_int, 508 beacon_int = iwl_adjust_beacon_interval(beacon_int,
@@ -903,23 +662,10 @@ EXPORT_SYMBOL(iwl_full_rxon_required);
903 662
904u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) 663u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
905{ 664{
906 int i; 665 /*
907 int rate_mask; 666 * Assign the lowest rate -- should really get this from
908 667 * the beacon skb from mac80211.
909 /* Set rate mask*/ 668 */
910 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
911 rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
912 else
913 rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
914
915 /* Find lowest valid rate */
916 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
917 i = iwl_rates[i].next_ieee) {
918 if (rate_mask & (1 << i))
919 return iwl_rates[i].plcp;
920 }
921
922 /* No valid rate was found. Assign the lowest one */
923 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) 669 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
924 return IWL_RATE_1M_PLCP; 670 return IWL_RATE_1M_PLCP;
925 else 671 else
@@ -991,7 +737,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
991 "extension channel offset 0x%x\n", 737 "extension channel offset 0x%x\n",
992 le32_to_cpu(rxon->flags), ht_conf->ht_protection, 738 le32_to_cpu(rxon->flags), ht_conf->ht_protection,
993 ht_conf->extension_chan_offset); 739 ht_conf->extension_chan_offset);
994 return;
995} 740}
996EXPORT_SYMBOL(iwl_set_rxon_ht); 741EXPORT_SYMBOL(iwl_set_rxon_ht);
997 742
@@ -1051,19 +796,6 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
1051} 796}
1052 797
1053/** 798/**
1054 * iwl_is_monitor_mode - Determine if interface in monitor mode
1055 *
1056 * priv->iw_mode is set in add_interface, but add_interface is
1057 * never called for monitor mode. The only way mac80211 informs us about
1058 * monitor mode is through configuring filters (call to configure_filter).
1059 */
1060bool iwl_is_monitor_mode(struct iwl_priv *priv)
1061{
1062 return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
1063}
1064EXPORT_SYMBOL(iwl_is_monitor_mode);
1065
1066/**
1067 * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image 799 * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
1068 * 800 *
1069 * Selects how many and which Rx receivers/antennas/chains to use. 801 * Selects how many and which Rx receivers/antennas/chains to use.
@@ -1106,19 +838,6 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
1106 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; 838 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
1107 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; 839 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
1108 840
1109 /* copied from 'iwl_bg_request_scan()' */
1110 /* Force use of chains B and C (0x6) for Rx for 4965
1111 * Avoid A (0x1) because of its off-channel reception on A-band.
1112 * MIMO is not used here, but value is required */
1113 if (iwl_is_monitor_mode(priv) &&
1114 !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
1115 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
1116 rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
1117 rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
1118 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
1119 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
1120 }
1121
1122 priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); 841 priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
1123 842
1124 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) 843 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -1174,8 +893,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
1174} 893}
1175EXPORT_SYMBOL(iwl_set_rxon_channel); 894EXPORT_SYMBOL(iwl_set_rxon_channel);
1176 895
1177void iwl_set_flags_for_band(struct iwl_priv *priv, 896static void iwl_set_flags_for_band(struct iwl_priv *priv,
1178 enum ieee80211_band band) 897 enum ieee80211_band band,
898 struct ieee80211_vif *vif)
1179{ 899{
1180 if (band == IEEE80211_BAND_5GHZ) { 900 if (band == IEEE80211_BAND_5GHZ) {
1181 priv->staging_rxon.flags &= 901 priv->staging_rxon.flags &=
@@ -1184,12 +904,12 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
1184 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 904 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
1185 } else { 905 } else {
1186 /* Copied from iwl_post_associate() */ 906 /* Copied from iwl_post_associate() */
1187 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 907 if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
1188 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 908 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
1189 else 909 else
1190 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 910 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1191 911
1192 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 912 if (vif && vif->type == NL80211_IFTYPE_ADHOC)
1193 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 913 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1194 914
1195 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 915 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
@@ -1201,13 +921,18 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
1201/* 921/*
1202 * initialize rxon structure with default values from eeprom 922 * initialize rxon structure with default values from eeprom
1203 */ 923 */
1204void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) 924void iwl_connection_init_rx_config(struct iwl_priv *priv,
925 struct ieee80211_vif *vif)
1205{ 926{
1206 const struct iwl_channel_info *ch_info; 927 const struct iwl_channel_info *ch_info;
928 enum nl80211_iftype type = NL80211_IFTYPE_STATION;
929
930 if (vif)
931 type = vif->type;
1207 932
1208 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); 933 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
1209 934
1210 switch (mode) { 935 switch (type) {
1211 case NL80211_IFTYPE_AP: 936 case NL80211_IFTYPE_AP:
1212 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; 937 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
1213 break; 938 break;
@@ -1225,7 +950,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
1225 break; 950 break;
1226 951
1227 default: 952 default:
1228 IWL_ERR(priv, "Unsupported interface type %d\n", mode); 953 IWL_ERR(priv, "Unsupported interface type %d\n", type);
1229 break; 954 break;
1230 } 955 }
1231 956
@@ -1244,18 +969,10 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
1244 if (!ch_info) 969 if (!ch_info)
1245 ch_info = &priv->channel_info[0]; 970 ch_info = &priv->channel_info[0];
1246 971
1247 /*
1248 * in some case A channels are all non IBSS
1249 * in this case force B/G channel
1250 */
1251 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
1252 !(is_channel_ibss(ch_info)))
1253 ch_info = &priv->channel_info[0];
1254
1255 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); 972 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
1256 priv->band = ch_info->band; 973 priv->band = ch_info->band;
1257 974
1258 iwl_set_flags_for_band(priv, priv->band); 975 iwl_set_flags_for_band(priv, priv->band, vif);
1259 976
1260 priv->staging_rxon.ofdm_basic_rates = 977 priv->staging_rxon.ofdm_basic_rates =
1261 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 978 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -1286,7 +1003,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
1286 } 1003 }
1287 1004
1288 priv->active_rate = 0; 1005 priv->active_rate = 0;
1289 priv->active_rate_basic = 0;
1290 1006
1291 for (i = 0; i < hw->n_bitrates; i++) { 1007 for (i = 0; i < hw->n_bitrates; i++) {
1292 rate = &(hw->bitrates[i]); 1008 rate = &(hw->bitrates[i]);
@@ -1294,30 +1010,13 @@ static void iwl_set_rate(struct iwl_priv *priv)
1294 priv->active_rate |= (1 << rate->hw_value); 1010 priv->active_rate |= (1 << rate->hw_value);
1295 } 1011 }
1296 1012
1297 IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n", 1013 IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
1298 priv->active_rate, priv->active_rate_basic);
1299 1014
1300 /* 1015 priv->staging_rxon.cck_basic_rates =
1301 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK) 1016 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1302 * otherwise set it to the default of all CCK rates and 6, 12, 24 for 1017
1303 * OFDM 1018 priv->staging_rxon.ofdm_basic_rates =
1304 */ 1019 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1305 if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
1306 priv->staging_rxon.cck_basic_rates =
1307 ((priv->active_rate_basic &
1308 IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
1309 else
1310 priv->staging_rxon.cck_basic_rates =
1311 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1312
1313 if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
1314 priv->staging_rxon.ofdm_basic_rates =
1315 ((priv->active_rate_basic &
1316 (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
1317 IWL_FIRST_OFDM_RATE) & 0xFF;
1318 else
1319 priv->staging_rxon.ofdm_basic_rates =
1320 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1321} 1020}
1322 1021
1323void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1022void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
@@ -1374,6 +1073,9 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1374 /* Cancel currently queued command. */ 1073 /* Cancel currently queued command. */
1375 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1074 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1376 1075
1076 IWL_ERR(priv, "Loaded firmware version: %s\n",
1077 priv->hw->wiphy->fw_version);
1078
1377 priv->cfg->ops->lib->dump_nic_error_log(priv); 1079 priv->cfg->ops->lib->dump_nic_error_log(priv);
1378 if (priv->cfg->ops->lib->dump_csr) 1080 if (priv->cfg->ops->lib->dump_csr)
1379 priv->cfg->ops->lib->dump_csr(priv); 1081 priv->cfg->ops->lib->dump_csr(priv);
@@ -1401,7 +1103,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1401} 1103}
1402EXPORT_SYMBOL(iwl_irq_handle_error); 1104EXPORT_SYMBOL(iwl_irq_handle_error);
1403 1105
1404int iwl_apm_stop_master(struct iwl_priv *priv) 1106static int iwl_apm_stop_master(struct iwl_priv *priv)
1405{ 1107{
1406 int ret = 0; 1108 int ret = 0;
1407 1109
@@ -1417,7 +1119,6 @@ int iwl_apm_stop_master(struct iwl_priv *priv)
1417 1119
1418 return ret; 1120 return ret;
1419} 1121}
1420EXPORT_SYMBOL(iwl_apm_stop_master);
1421 1122
1422void iwl_apm_stop(struct iwl_priv *priv) 1123void iwl_apm_stop(struct iwl_priv *priv)
1423{ 1124{
@@ -1561,41 +1262,33 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
1561 u64 multicast) 1262 u64 multicast)
1562{ 1263{
1563 struct iwl_priv *priv = hw->priv; 1264 struct iwl_priv *priv = hw->priv;
1564 __le32 *filter_flags = &priv->staging_rxon.filter_flags; 1265 __le32 filter_or = 0, filter_nand = 0;
1266
1267#define CHK(test, flag) do { \
1268 if (*total_flags & (test)) \
1269 filter_or |= (flag); \
1270 else \
1271 filter_nand |= (flag); \
1272 } while (0)
1565 1273
1566 IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", 1274 IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
1567 changed_flags, *total_flags); 1275 changed_flags, *total_flags);
1568 1276
1569 if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { 1277 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
1570 if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) 1278 CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK);
1571 *filter_flags |= RXON_FILTER_PROMISC_MSK; 1279 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
1572 else 1280 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
1573 *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
1574 }
1575 if (changed_flags & FIF_ALLMULTI) {
1576 if (*total_flags & FIF_ALLMULTI)
1577 *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
1578 else
1579 *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
1580 }
1581 if (changed_flags & FIF_CONTROL) {
1582 if (*total_flags & FIF_CONTROL)
1583 *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
1584 else
1585 *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
1586 }
1587 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
1588 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
1589 *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
1590 else
1591 *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
1592 }
1593 1281
1594 /* We avoid iwl_commit_rxon here to commit the new filter flags 1282#undef CHK
1595 * since mac80211 will call ieee80211_hw_config immediately. 1283
1596 * (mc_list is not supported at this time). Otherwise, we need to 1284 mutex_lock(&priv->mutex);
1597 * queue a background iwl_commit_rxon work. 1285
1598 */ 1286 priv->staging_rxon.filter_flags &= ~filter_nand;
1287 priv->staging_rxon.filter_flags |= filter_or;
1288
1289 iwlcore_commit_rxon(priv);
1290
1291 mutex_unlock(&priv->mutex);
1599 1292
1600 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | 1293 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
1601 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 1294 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
@@ -1626,10 +1319,11 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1626 int ret = 0; 1319 int ret = 0;
1627 s8 prev_tx_power = priv->tx_power_user_lmt; 1320 s8 prev_tx_power = priv->tx_power_user_lmt;
1628 1321
1629 if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { 1322 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
1630 IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n", 1323 IWL_WARN(priv,
1324 "Requested user TXPOWER %d below lower limit %d.\n",
1631 tx_power, 1325 tx_power,
1632 IWL_TX_POWER_TARGET_POWER_MIN); 1326 IWLAGN_TX_POWER_TARGET_POWER_MIN);
1633 return -EINVAL; 1327 return -EINVAL;
1634 } 1328 }
1635 1329
@@ -1668,286 +1362,16 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1668} 1362}
1669EXPORT_SYMBOL(iwl_set_tx_power); 1363EXPORT_SYMBOL(iwl_set_tx_power);
1670 1364
1671#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
1672
1673/* Free dram table */
1674void iwl_free_isr_ict(struct iwl_priv *priv)
1675{
1676 if (priv->ict_tbl_vir) {
1677 dma_free_coherent(&priv->pci_dev->dev,
1678 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1679 priv->ict_tbl_vir, priv->ict_tbl_dma);
1680 priv->ict_tbl_vir = NULL;
1681 }
1682}
1683EXPORT_SYMBOL(iwl_free_isr_ict);
1684
1685
1686/* allocate dram shared table it is a PAGE_SIZE aligned
1687 * also reset all data related to ICT table interrupt.
1688 */
1689int iwl_alloc_isr_ict(struct iwl_priv *priv)
1690{
1691
1692 if (priv->cfg->use_isr_legacy)
1693 return 0;
1694 /* allocate shrared data table */
1695 priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev,
1696 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
1697 &priv->ict_tbl_dma, GFP_KERNEL);
1698 if (!priv->ict_tbl_vir)
1699 return -ENOMEM;
1700
1701 /* align table to PAGE_SIZE boundry */
1702 priv->aligned_ict_tbl_dma = ALIGN(priv->ict_tbl_dma, PAGE_SIZE);
1703
1704 IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
1705 (unsigned long long)priv->ict_tbl_dma,
1706 (unsigned long long)priv->aligned_ict_tbl_dma,
1707 (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
1708
1709 priv->ict_tbl = priv->ict_tbl_vir +
1710 (priv->aligned_ict_tbl_dma - priv->ict_tbl_dma);
1711
1712 IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
1713 priv->ict_tbl, priv->ict_tbl_vir,
1714 (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
1715
1716 /* reset table and index to all 0 */
1717 memset(priv->ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
1718 priv->ict_index = 0;
1719
1720 /* add periodic RX interrupt */
1721 priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
1722 return 0;
1723}
1724EXPORT_SYMBOL(iwl_alloc_isr_ict);
1725
1726/* Device is going up inform it about using ICT interrupt table,
1727 * also we need to tell the driver to start using ICT interrupt.
1728 */
1729int iwl_reset_ict(struct iwl_priv *priv)
1730{
1731 u32 val;
1732 unsigned long flags;
1733
1734 if (!priv->ict_tbl_vir)
1735 return 0;
1736
1737 spin_lock_irqsave(&priv->lock, flags);
1738 iwl_disable_interrupts(priv);
1739
1740 memset(&priv->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
1741
1742 val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
1743
1744 val |= CSR_DRAM_INT_TBL_ENABLE;
1745 val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
1746
1747 IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
1748 "aligned dma address %Lx\n",
1749 val, (unsigned long long)priv->aligned_ict_tbl_dma);
1750
1751 iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
1752 priv->use_ict = true;
1753 priv->ict_index = 0;
1754 iwl_write32(priv, CSR_INT, priv->inta_mask);
1755 iwl_enable_interrupts(priv);
1756 spin_unlock_irqrestore(&priv->lock, flags);
1757
1758 return 0;
1759}
1760EXPORT_SYMBOL(iwl_reset_ict);
1761
1762/* Device is going down disable ict interrupt usage */
1763void iwl_disable_ict(struct iwl_priv *priv)
1764{
1765 unsigned long flags;
1766
1767 spin_lock_irqsave(&priv->lock, flags);
1768 priv->use_ict = false;
1769 spin_unlock_irqrestore(&priv->lock, flags);
1770}
1771EXPORT_SYMBOL(iwl_disable_ict);
1772
1773/* interrupt handler using ict table, with this interrupt driver will
1774 * stop using INTA register to get device's interrupt, reading this register
1775 * is expensive, device will write interrupts in ICT dram table, increment
1776 * index then will fire interrupt to driver, driver will OR all ICT table
1777 * entries from current index up to table entry with 0 value. the result is
1778 * the interrupt we need to service, driver will set the entries back to 0 and
1779 * set index.
1780 */
1781irqreturn_t iwl_isr_ict(int irq, void *data)
1782{
1783 struct iwl_priv *priv = data;
1784 u32 inta, inta_mask;
1785 u32 val = 0;
1786
1787 if (!priv)
1788 return IRQ_NONE;
1789
1790 /* dram interrupt table not set yet,
1791 * use legacy interrupt.
1792 */
1793 if (!priv->use_ict)
1794 return iwl_isr(irq, data);
1795
1796 spin_lock(&priv->lock);
1797
1798 /* Disable (but don't clear!) interrupts here to avoid
1799 * back-to-back ISRs and sporadic interrupts from our NIC.
1800 * If we have something to service, the tasklet will re-enable ints.
1801 * If we *don't* have something, we'll re-enable before leaving here.
1802 */
1803 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
1804 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1805
1806
1807 /* Ignore interrupt if there's nothing in NIC to service.
1808 * This may be due to IRQ shared with another device,
1809 * or due to sporadic interrupts thrown from our NIC. */
1810 if (!priv->ict_tbl[priv->ict_index]) {
1811 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
1812 goto none;
1813 }
1814
1815 /* read all entries that not 0 start with ict_index */
1816 while (priv->ict_tbl[priv->ict_index]) {
1817
1818 val |= le32_to_cpu(priv->ict_tbl[priv->ict_index]);
1819 IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
1820 priv->ict_index,
1821 le32_to_cpu(priv->ict_tbl[priv->ict_index]));
1822 priv->ict_tbl[priv->ict_index] = 0;
1823 priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
1824 ICT_COUNT);
1825
1826 }
1827
1828 /* We should not get this value, just ignore it. */
1829 if (val == 0xffffffff)
1830 val = 0;
1831
1832 /*
1833 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1834 * (bit 15 before shifting it to 31) to clear when using interrupt
1835 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1836 * so we use them to decide on the real state of the Rx bit.
1837 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1838 */
1839 if (val & 0xC0000)
1840 val |= 0x8000;
1841
1842 inta = (0xff & val) | ((0xff00 & val) << 16);
1843 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
1844 inta, inta_mask, val);
1845
1846 inta &= priv->inta_mask;
1847 priv->inta |= inta;
1848
1849 /* iwl_irq_tasklet() will service interrupts and re-enable them */
1850 if (likely(inta))
1851 tasklet_schedule(&priv->irq_tasklet);
1852 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) {
1853 /* Allow interrupt if was disabled by this handler and
1854 * no tasklet was schedules, We should not enable interrupt,
1855 * tasklet will enable it.
1856 */
1857 iwl_enable_interrupts(priv);
1858 }
1859
1860 spin_unlock(&priv->lock);
1861 return IRQ_HANDLED;
1862
1863 none:
1864 /* re-enable interrupts here since we don't have anything to service.
1865 * only Re-enable if disabled by irq.
1866 */
1867 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1868 iwl_enable_interrupts(priv);
1869
1870 spin_unlock(&priv->lock);
1871 return IRQ_NONE;
1872}
1873EXPORT_SYMBOL(iwl_isr_ict);
1874
1875
1876static irqreturn_t iwl_isr(int irq, void *data)
1877{
1878 struct iwl_priv *priv = data;
1879 u32 inta, inta_mask;
1880#ifdef CONFIG_IWLWIFI_DEBUG
1881 u32 inta_fh;
1882#endif
1883 if (!priv)
1884 return IRQ_NONE;
1885
1886 spin_lock(&priv->lock);
1887
1888 /* Disable (but don't clear!) interrupts here to avoid
1889 * back-to-back ISRs and sporadic interrupts from our NIC.
1890 * If we have something to service, the tasklet will re-enable ints.
1891 * If we *don't* have something, we'll re-enable before leaving here. */
1892 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
1893 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1894
1895 /* Discover which interrupts are active/pending */
1896 inta = iwl_read32(priv, CSR_INT);
1897
1898 /* Ignore interrupt if there's nothing in NIC to service.
1899 * This may be due to IRQ shared with another device,
1900 * or due to sporadic interrupts thrown from our NIC. */
1901 if (!inta) {
1902 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
1903 goto none;
1904 }
1905
1906 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
1907 /* Hardware disappeared. It might have already raised
1908 * an interrupt */
1909 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
1910 goto unplugged;
1911 }
1912
1913#ifdef CONFIG_IWLWIFI_DEBUG
1914 if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
1915 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1916 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
1917 "fh 0x%08x\n", inta, inta_mask, inta_fh);
1918 }
1919#endif
1920
1921 priv->inta |= inta;
1922 /* iwl_irq_tasklet() will service interrupts and re-enable them */
1923 if (likely(inta))
1924 tasklet_schedule(&priv->irq_tasklet);
1925 else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1926 iwl_enable_interrupts(priv);
1927
1928 unplugged:
1929 spin_unlock(&priv->lock);
1930 return IRQ_HANDLED;
1931
1932 none:
1933 /* re-enable interrupts here since we don't have anything to service. */
1934 /* only Re-enable if diabled by irq and no schedules tasklet. */
1935 if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
1936 iwl_enable_interrupts(priv);
1937
1938 spin_unlock(&priv->lock);
1939 return IRQ_NONE;
1940}
1941
1942irqreturn_t iwl_isr_legacy(int irq, void *data) 1365irqreturn_t iwl_isr_legacy(int irq, void *data)
1943{ 1366{
1944 struct iwl_priv *priv = data; 1367 struct iwl_priv *priv = data;
1945 u32 inta, inta_mask; 1368 u32 inta, inta_mask;
1946 u32 inta_fh; 1369 u32 inta_fh;
1370 unsigned long flags;
1947 if (!priv) 1371 if (!priv)
1948 return IRQ_NONE; 1372 return IRQ_NONE;
1949 1373
1950 spin_lock(&priv->lock); 1374 spin_lock_irqsave(&priv->lock, flags);
1951 1375
1952 /* Disable (but don't clear!) interrupts here to avoid 1376 /* Disable (but don't clear!) interrupts here to avoid
1953 * back-to-back ISRs and sporadic interrupts from our NIC. 1377 * back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1985,7 +1409,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
1985 tasklet_schedule(&priv->irq_tasklet); 1409 tasklet_schedule(&priv->irq_tasklet);
1986 1410
1987 unplugged: 1411 unplugged:
1988 spin_unlock(&priv->lock); 1412 spin_unlock_irqrestore(&priv->lock, flags);
1989 return IRQ_HANDLED; 1413 return IRQ_HANDLED;
1990 1414
1991 none: 1415 none:
@@ -1993,12 +1417,12 @@ irqreturn_t iwl_isr_legacy(int irq, void *data)
1993 /* only Re-enable if diabled by irq */ 1417 /* only Re-enable if diabled by irq */
1994 if (test_bit(STATUS_INT_ENABLED, &priv->status)) 1418 if (test_bit(STATUS_INT_ENABLED, &priv->status))
1995 iwl_enable_interrupts(priv); 1419 iwl_enable_interrupts(priv);
1996 spin_unlock(&priv->lock); 1420 spin_unlock_irqrestore(&priv->lock, flags);
1997 return IRQ_NONE; 1421 return IRQ_NONE;
1998} 1422}
1999EXPORT_SYMBOL(iwl_isr_legacy); 1423EXPORT_SYMBOL(iwl_isr_legacy);
2000 1424
2001int iwl_send_bt_config(struct iwl_priv *priv) 1425void iwl_send_bt_config(struct iwl_priv *priv)
2002{ 1426{
2003 struct iwl_bt_cmd bt_cmd = { 1427 struct iwl_bt_cmd bt_cmd = {
2004 .lead_time = BT_LEAD_TIME_DEF, 1428 .lead_time = BT_LEAD_TIME_DEF,
@@ -2015,8 +1439,9 @@ int iwl_send_bt_config(struct iwl_priv *priv)
2015 IWL_DEBUG_INFO(priv, "BT coex %s\n", 1439 IWL_DEBUG_INFO(priv, "BT coex %s\n",
2016 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); 1440 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
2017 1441
2018 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, 1442 if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
2019 sizeof(struct iwl_bt_cmd), &bt_cmd); 1443 sizeof(struct iwl_bt_cmd), &bt_cmd))
1444 IWL_ERR(priv, "failed to send BT Coex Config\n");
2020} 1445}
2021EXPORT_SYMBOL(iwl_send_bt_config); 1446EXPORT_SYMBOL(iwl_send_bt_config);
2022 1447
@@ -2306,12 +1731,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
2306 cpu_to_le16((params->txop * 32)); 1731 cpu_to_le16((params->txop * 32));
2307 1732
2308 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; 1733 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
2309 priv->qos_data.qos_active = 1;
2310
2311 if (priv->iw_mode == NL80211_IFTYPE_AP)
2312 iwl_activate_qos(priv, 1);
2313 else if (priv->assoc_id && iwl_is_associated(priv))
2314 iwl_activate_qos(priv, 0);
2315 1734
2316 spin_unlock_irqrestore(&priv->lock, flags); 1735 spin_unlock_irqrestore(&priv->lock, flags);
2317 1736
@@ -2321,12 +1740,13 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
2321EXPORT_SYMBOL(iwl_mac_conf_tx); 1740EXPORT_SYMBOL(iwl_mac_conf_tx);
2322 1741
2323static void iwl_ht_conf(struct iwl_priv *priv, 1742static void iwl_ht_conf(struct iwl_priv *priv,
2324 struct ieee80211_bss_conf *bss_conf) 1743 struct ieee80211_vif *vif)
2325{ 1744{
2326 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 1745 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
2327 struct ieee80211_sta *sta; 1746 struct ieee80211_sta *sta;
1747 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
2328 1748
2329 IWL_DEBUG_MAC80211(priv, "enter: \n"); 1749 IWL_DEBUG_MAC80211(priv, "enter:\n");
2330 1750
2331 if (!ht_conf->is_ht) 1751 if (!ht_conf->is_ht)
2332 return; 1752 return;
@@ -2338,10 +1758,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2338 1758
2339 ht_conf->single_chain_sufficient = false; 1759 ht_conf->single_chain_sufficient = false;
2340 1760
2341 switch (priv->iw_mode) { 1761 switch (vif->type) {
2342 case NL80211_IFTYPE_STATION: 1762 case NL80211_IFTYPE_STATION:
2343 rcu_read_lock(); 1763 rcu_read_lock();
2344 sta = ieee80211_find_sta(priv->vif, priv->bssid); 1764 sta = ieee80211_find_sta(vif, bss_conf->bssid);
2345 if (sta) { 1765 if (sta) {
2346 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1766 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2347 int maxstreams; 1767 int maxstreams;
@@ -2379,7 +1799,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2379 1799
2380static inline void iwl_set_no_assoc(struct iwl_priv *priv) 1800static inline void iwl_set_no_assoc(struct iwl_priv *priv)
2381{ 1801{
2382 priv->assoc_id = 0;
2383 iwl_led_disassociate(priv); 1802 iwl_led_disassociate(priv);
2384 /* 1803 /*
2385 * inform the ucode that there is no longer an 1804 * inform the ucode that there is no longer an
@@ -2392,7 +1811,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv)
2392 iwlcore_commit_rxon(priv); 1811 iwlcore_commit_rxon(priv);
2393} 1812}
2394 1813
2395#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
2396void iwl_bss_info_changed(struct ieee80211_hw *hw, 1814void iwl_bss_info_changed(struct ieee80211_hw *hw,
2397 struct ieee80211_vif *vif, 1815 struct ieee80211_vif *vif,
2398 struct ieee80211_bss_conf *bss_conf, 1816 struct ieee80211_bss_conf *bss_conf,
@@ -2408,14 +1826,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2408 1826
2409 mutex_lock(&priv->mutex); 1827 mutex_lock(&priv->mutex);
2410 1828
2411 if (changes & BSS_CHANGED_BEACON && 1829 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
2412 priv->iw_mode == NL80211_IFTYPE_AP) {
2413 dev_kfree_skb(priv->ibss_beacon); 1830 dev_kfree_skb(priv->ibss_beacon);
2414 priv->ibss_beacon = ieee80211_beacon_get(hw, vif); 1831 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
2415 } 1832 }
2416 1833
2417 if (changes & BSS_CHANGED_BEACON_INT) { 1834 if (changes & BSS_CHANGED_BEACON_INT) {
2418 priv->beacon_int = bss_conf->beacon_int;
2419 /* TODO: in AP mode, do something to make this take effect */ 1835 /* TODO: in AP mode, do something to make this take effect */
2420 } 1836 }
2421 1837
@@ -2435,8 +1851,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2435 } 1851 }
2436 1852
2437 /* mac80211 only sets assoc when in STATION mode */ 1853 /* mac80211 only sets assoc when in STATION mode */
2438 if (priv->iw_mode == NL80211_IFTYPE_ADHOC || 1854 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
2439 bss_conf->assoc) {
2440 memcpy(priv->staging_rxon.bssid_addr, 1855 memcpy(priv->staging_rxon.bssid_addr,
2441 bss_conf->bssid, ETH_ALEN); 1856 bss_conf->bssid, ETH_ALEN);
2442 1857
@@ -2454,7 +1869,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2454 * mac80211 decides to do both changes at once because 1869 * mac80211 decides to do both changes at once because
2455 * it will invoke post_associate. 1870 * it will invoke post_associate.
2456 */ 1871 */
2457 if (priv->iw_mode == NL80211_IFTYPE_ADHOC && 1872 if (vif->type == NL80211_IFTYPE_ADHOC &&
2458 changes & BSS_CHANGED_BEACON) { 1873 changes & BSS_CHANGED_BEACON) {
2459 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1874 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2460 1875
@@ -2497,7 +1912,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2497 } 1912 }
2498 1913
2499 if (changes & BSS_CHANGED_HT) { 1914 if (changes & BSS_CHANGED_HT) {
2500 iwl_ht_conf(priv, bss_conf); 1915 iwl_ht_conf(priv, vif);
2501 1916
2502 if (priv->cfg->ops->hcmd->set_rxon_chain) 1917 if (priv->cfg->ops->hcmd->set_rxon_chain)
2503 priv->cfg->ops->hcmd->set_rxon_chain(priv); 1918 priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2506,28 +1921,17 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2506 if (changes & BSS_CHANGED_ASSOC) { 1921 if (changes & BSS_CHANGED_ASSOC) {
2507 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); 1922 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
2508 if (bss_conf->assoc) { 1923 if (bss_conf->assoc) {
2509 priv->assoc_id = bss_conf->aid;
2510 priv->beacon_int = bss_conf->beacon_int;
2511 priv->timestamp = bss_conf->timestamp; 1924 priv->timestamp = bss_conf->timestamp;
2512 priv->assoc_capability = bss_conf->assoc_capability;
2513 1925
2514 iwl_led_associate(priv); 1926 iwl_led_associate(priv);
2515 1927
2516 /*
2517 * We have just associated, don't start scan too early
2518 * leave time for EAPOL exchange to complete.
2519 *
2520 * XXX: do this in mac80211
2521 */
2522 priv->next_scan_jiffies = jiffies +
2523 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
2524 if (!iwl_is_rfkill(priv)) 1928 if (!iwl_is_rfkill(priv))
2525 priv->cfg->ops->lib->post_associate(priv); 1929 priv->cfg->ops->lib->post_associate(priv, vif);
2526 } else 1930 } else
2527 iwl_set_no_assoc(priv); 1931 iwl_set_no_assoc(priv);
2528 } 1932 }
2529 1933
2530 if (changes && iwl_is_associated(priv) && priv->assoc_id) { 1934 if (changes && iwl_is_associated(priv) && bss_conf->aid) {
2531 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", 1935 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
2532 changes); 1936 changes);
2533 ret = iwl_send_rxon_assoc(priv); 1937 ret = iwl_send_rxon_assoc(priv);
@@ -2544,11 +1948,20 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2544 memcpy(priv->staging_rxon.bssid_addr, 1948 memcpy(priv->staging_rxon.bssid_addr,
2545 bss_conf->bssid, ETH_ALEN); 1949 bss_conf->bssid, ETH_ALEN);
2546 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 1950 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
2547 iwlcore_config_ap(priv); 1951 iwlcore_config_ap(priv, vif);
2548 } else 1952 } else
2549 iwl_set_no_assoc(priv); 1953 iwl_set_no_assoc(priv);
2550 } 1954 }
2551 1955
1956 if (changes & BSS_CHANGED_IBSS) {
1957 ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
1958 bss_conf->ibss_joined);
1959 if (ret)
1960 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
1961 bss_conf->ibss_joined ? "add" : "remove",
1962 bss_conf->bssid);
1963 }
1964
2552 mutex_unlock(&priv->mutex); 1965 mutex_unlock(&priv->mutex);
2553 1966
2554 IWL_DEBUG_MAC80211(priv, "leave\n"); 1967 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2568,11 +1981,6 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
2568 return -EIO; 1981 return -EIO;
2569 } 1982 }
2570 1983
2571 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2572 IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
2573 return -EIO;
2574 }
2575
2576 spin_lock_irqsave(&priv->lock, flags); 1984 spin_lock_irqsave(&priv->lock, flags);
2577 1985
2578 if (priv->ibss_beacon) 1986 if (priv->ibss_beacon)
@@ -2580,59 +1988,31 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
2580 1988
2581 priv->ibss_beacon = skb; 1989 priv->ibss_beacon = skb;
2582 1990
2583 priv->assoc_id = 0;
2584 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 1991 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
2585 priv->timestamp = le64_to_cpu(timestamp); 1992 priv->timestamp = le64_to_cpu(timestamp);
2586 1993
2587 IWL_DEBUG_MAC80211(priv, "leave\n"); 1994 IWL_DEBUG_MAC80211(priv, "leave\n");
2588 spin_unlock_irqrestore(&priv->lock, flags); 1995 spin_unlock_irqrestore(&priv->lock, flags);
2589 1996
2590 iwl_reset_qos(priv); 1997 priv->cfg->ops->lib->post_associate(priv, priv->vif);
2591
2592 priv->cfg->ops->lib->post_associate(priv);
2593
2594 1998
2595 return 0; 1999 return 0;
2596} 2000}
2597EXPORT_SYMBOL(iwl_mac_beacon_update); 2001EXPORT_SYMBOL(iwl_mac_beacon_update);
2598 2002
2599int iwl_set_mode(struct iwl_priv *priv, int mode) 2003static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
2600{ 2004{
2601 if (mode == NL80211_IFTYPE_ADHOC) { 2005 iwl_connection_init_rx_config(priv, vif);
2602 const struct iwl_channel_info *ch_info;
2603
2604 ch_info = iwl_get_channel_info(priv,
2605 priv->band,
2606 le16_to_cpu(priv->staging_rxon.channel));
2607
2608 if (!ch_info || !is_channel_ibss(ch_info)) {
2609 IWL_ERR(priv, "channel %d not IBSS channel\n",
2610 le16_to_cpu(priv->staging_rxon.channel));
2611 return -EINVAL;
2612 }
2613 }
2614
2615 iwl_connection_init_rx_config(priv, mode);
2616 2006
2617 if (priv->cfg->ops->hcmd->set_rxon_chain) 2007 if (priv->cfg->ops->hcmd->set_rxon_chain)
2618 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2008 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2619 2009
2620 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 2010 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2621 2011
2622 iwl_clear_stations_table(priv); 2012 return iwlcore_commit_rxon(priv);
2623
2624 /* dont commit rxon if rf-kill is on*/
2625 if (!iwl_is_ready_rf(priv))
2626 return -EAGAIN;
2627
2628 iwlcore_commit_rxon(priv);
2629
2630 return 0;
2631} 2013}
2632EXPORT_SYMBOL(iwl_set_mode);
2633 2014
2634int iwl_mac_add_interface(struct ieee80211_hw *hw, 2015int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2635 struct ieee80211_vif *vif)
2636{ 2016{
2637 struct iwl_priv *priv = hw->priv; 2017 struct iwl_priv *priv = hw->priv;
2638 int err = 0; 2018 int err = 0;
@@ -2641,6 +2021,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2641 2021
2642 mutex_lock(&priv->mutex); 2022 mutex_lock(&priv->mutex);
2643 2023
2024 if (WARN_ON(!iwl_is_ready_rf(priv))) {
2025 err = -EINVAL;
2026 goto out;
2027 }
2028
2644 if (priv->vif) { 2029 if (priv->vif) {
2645 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2030 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2646 err = -EOPNOTSUPP; 2031 err = -EOPNOTSUPP;
@@ -2650,15 +2035,18 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2650 priv->vif = vif; 2035 priv->vif = vif;
2651 priv->iw_mode = vif->type; 2036 priv->iw_mode = vif->type;
2652 2037
2653 if (vif->addr) { 2038 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2654 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); 2039 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2655 memcpy(priv->mac_addr, vif->addr, ETH_ALEN); 2040
2656 } 2041 err = iwl_set_mode(priv, vif);
2042 if (err)
2043 goto out_err;
2657 2044
2658 if (iwl_set_mode(priv, vif->type) == -EAGAIN) 2045 goto out;
2659 /* we are not ready, will run again when ready */
2660 set_bit(STATUS_MODE_PENDING, &priv->status);
2661 2046
2047 out_err:
2048 priv->vif = NULL;
2049 priv->iw_mode = NL80211_IFTYPE_STATION;
2662 out: 2050 out:
2663 mutex_unlock(&priv->mutex); 2051 mutex_unlock(&priv->mutex);
2664 2052
@@ -2668,7 +2056,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2668EXPORT_SYMBOL(iwl_mac_add_interface); 2056EXPORT_SYMBOL(iwl_mac_add_interface);
2669 2057
2670void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2058void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2671 struct ieee80211_vif *vif) 2059 struct ieee80211_vif *vif)
2672{ 2060{
2673 struct iwl_priv *priv = hw->priv; 2061 struct iwl_priv *priv = hw->priv;
2674 2062
@@ -2694,10 +2082,6 @@ EXPORT_SYMBOL(iwl_mac_remove_interface);
2694 2082
2695/** 2083/**
2696 * iwl_mac_config - mac80211 config callback 2084 * iwl_mac_config - mac80211 config callback
2697 *
2698 * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
2699 * be set inappropriately and the driver currently sets the hardware up to
2700 * use it whenever needed.
2701 */ 2085 */
2702int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) 2086int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2703{ 2087{
@@ -2752,15 +2136,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2752 goto set_ch_out; 2136 goto set_ch_out;
2753 } 2137 }
2754 2138
2755 if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2756 !is_channel_ibss(ch_info)) {
2757 IWL_ERR(priv, "channel %d in band %d not "
2758 "IBSS channel\n",
2759 conf->channel->hw_value, conf->channel->band);
2760 ret = -EINVAL;
2761 goto set_ch_out;
2762 }
2763
2764 spin_lock_irqsave(&priv->lock, flags); 2139 spin_lock_irqsave(&priv->lock, flags);
2765 2140
2766 /* Configure HT40 channels */ 2141 /* Configure HT40 channels */
@@ -2794,7 +2169,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2794 iwl_set_rxon_channel(priv, conf->channel); 2169 iwl_set_rxon_channel(priv, conf->channel);
2795 iwl_set_rxon_ht(priv, ht_conf); 2170 iwl_set_rxon_ht(priv, ht_conf);
2796 2171
2797 iwl_set_flags_for_band(priv, conf->channel->band); 2172 iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
2798 spin_unlock_irqrestore(&priv->lock, flags); 2173 spin_unlock_irqrestore(&priv->lock, flags);
2799 if (iwl_is_associated(priv) && 2174 if (iwl_is_associated(priv) &&
2800 (le16_to_cpu(priv->active_rxon.channel) != ch) && 2175 (le16_to_cpu(priv->active_rxon.channel) != ch) &&
@@ -2833,6 +2208,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2833 iwl_set_tx_power(priv, conf->power_level, false); 2208 iwl_set_tx_power(priv, conf->power_level, false);
2834 } 2209 }
2835 2210
2211 if (changed & IEEE80211_CONF_CHANGE_QOS) {
2212 bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS);
2213
2214 spin_lock_irqsave(&priv->lock, flags);
2215 priv->qos_data.qos_active = qos_active;
2216 iwl_update_qos(priv);
2217 spin_unlock_irqrestore(&priv->lock, flags);
2218 }
2219
2836 if (!iwl_is_ready(priv)) { 2220 if (!iwl_is_ready(priv)) {
2837 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2221 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2838 goto out; 2222 goto out;
@@ -2867,12 +2251,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2867 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); 2251 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2868 spin_unlock_irqrestore(&priv->lock, flags); 2252 spin_unlock_irqrestore(&priv->lock, flags);
2869 2253
2870 iwl_reset_qos(priv);
2871
2872 spin_lock_irqsave(&priv->lock, flags); 2254 spin_lock_irqsave(&priv->lock, flags);
2873 priv->assoc_id = 0;
2874 priv->assoc_capability = 0;
2875 priv->assoc_station_added = 0;
2876 2255
2877 /* new association get rid of ibss beacon skb */ 2256 /* new association get rid of ibss beacon skb */
2878 if (priv->ibss_beacon) 2257 if (priv->ibss_beacon)
@@ -2880,10 +2259,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2880 2259
2881 priv->ibss_beacon = NULL; 2260 priv->ibss_beacon = NULL;
2882 2261
2883 priv->beacon_int = priv->vif->bss_conf.beacon_int;
2884 priv->timestamp = 0; 2262 priv->timestamp = 0;
2885 if ((priv->iw_mode == NL80211_IFTYPE_STATION))
2886 priv->beacon_int = 0;
2887 2263
2888 spin_unlock_irqrestore(&priv->lock, flags); 2264 spin_unlock_irqrestore(&priv->lock, flags);
2889 2265
@@ -2896,17 +2272,9 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2896 /* we are restarting association process 2272 /* we are restarting association process
2897 * clear RXON_FILTER_ASSOC_MSK bit 2273 * clear RXON_FILTER_ASSOC_MSK bit
2898 */ 2274 */
2899 if (priv->iw_mode != NL80211_IFTYPE_AP) { 2275 iwl_scan_cancel_timeout(priv, 100);
2900 iwl_scan_cancel_timeout(priv, 100); 2276 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2901 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2277 iwlcore_commit_rxon(priv);
2902 iwlcore_commit_rxon(priv);
2903 }
2904
2905 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2906 IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
2907 mutex_unlock(&priv->mutex);
2908 return;
2909 }
2910 2278
2911 iwl_set_rate(priv); 2279 iwl_set_rate(priv);
2912 2280
@@ -2923,7 +2291,7 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv)
2923 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, 2291 sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
2924 GFP_KERNEL); 2292 GFP_KERNEL);
2925 if (!priv->txq) { 2293 if (!priv->txq) {
2926 IWL_ERR(priv, "Not enough memory for txq \n"); 2294 IWL_ERR(priv, "Not enough memory for txq\n");
2927 return -ENOMEM; 2295 return -ENOMEM;
2928 } 2296 }
2929 return 0; 2297 return 0;
@@ -2937,34 +2305,6 @@ void iwl_free_txq_mem(struct iwl_priv *priv)
2937} 2305}
2938EXPORT_SYMBOL(iwl_free_txq_mem); 2306EXPORT_SYMBOL(iwl_free_txq_mem);
2939 2307
2940int iwl_send_wimax_coex(struct iwl_priv *priv)
2941{
2942 struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
2943
2944 if (priv->cfg->support_wimax_coexist) {
2945 /* UnMask wake up src at associated sleep */
2946 coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
2947
2948 /* UnMask wake up src at unassociated sleep */
2949 coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
2950 memcpy(coex_cmd.sta_prio, cu_priorities,
2951 sizeof(struct iwl_wimax_coex_event_entry) *
2952 COEX_NUM_OF_EVENTS);
2953
2954 /* enabling the coexistence feature */
2955 coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
2956
2957 /* enabling the priorities tables */
2958 coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
2959 } else {
2960 /* coexistence is disabled */
2961 memset(&coex_cmd, 0, sizeof(coex_cmd));
2962 }
2963 return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
2964 sizeof(coex_cmd), &coex_cmd);
2965}
2966EXPORT_SYMBOL(iwl_send_wimax_coex);
2967
2968#ifdef CONFIG_IWLWIFI_DEBUGFS 2308#ifdef CONFIG_IWLWIFI_DEBUGFS
2969 2309
2970#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) 2310#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
@@ -3403,6 +2743,99 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
3403 } 2743 }
3404 return 0; 2744 return 0;
3405} 2745}
2746EXPORT_SYMBOL(iwl_force_reset);
2747
2748/**
2749 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
2750 *
2751 * During normal condition (no queue is stuck), the timer is continually set to
2752 * execute every monitor_recover_period milliseconds after the last timer
2753 * expired. When the queue read_ptr is at the same place, the timer is
2754 * shorten to 100mSecs. This is
2755 * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
2756 * 2) to detect the stuck queues quicker before the station and AP can
2757 * disassociate each other.
2758 *
2759 * This function monitors all the tx queues and recover from it if any
2760 * of the queues are stuck.
2761 * 1. It first check the cmd queue for stuck conditions. If it is stuck,
2762 * it will recover by resetting the firmware and return.
2763 * 2. Then, it checks for station association. If it associates it will check
2764 * other queues. If any queue is stuck, it will recover by resetting
2765 * the firmware.
2766 * Note: It the number of times the queue read_ptr to be at the same place to
2767 * be MAX_REPEAT+1 in order to consider to be stuck.
2768 */
2769/*
2770 * The maximum number of times the read pointer of the tx queue at the
2771 * same place without considering to be stuck.
2772 */
2773#define MAX_REPEAT (2)
2774static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
2775{
2776 struct iwl_tx_queue *txq;
2777 struct iwl_queue *q;
2778
2779 txq = &priv->txq[cnt];
2780 q = &txq->q;
2781 /* queue is empty, skip */
2782 if (q->read_ptr != q->write_ptr) {
2783 if (q->read_ptr == q->last_read_ptr) {
2784 /* a queue has not been read from last time */
2785 if (q->repeat_same_read_ptr > MAX_REPEAT) {
2786 IWL_ERR(priv,
2787 "queue %d stuck %d time. Fw reload.\n",
2788 q->id, q->repeat_same_read_ptr);
2789 q->repeat_same_read_ptr = 0;
2790 iwl_force_reset(priv, IWL_FW_RESET);
2791 } else {
2792 q->repeat_same_read_ptr++;
2793 IWL_DEBUG_RADIO(priv,
2794 "queue %d, not read %d time\n",
2795 q->id,
2796 q->repeat_same_read_ptr);
2797 mod_timer(&priv->monitor_recover, jiffies +
2798 msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
2799 }
2800 return 1;
2801 } else {
2802 q->last_read_ptr = q->read_ptr;
2803 q->repeat_same_read_ptr = 0;
2804 }
2805 }
2806 return 0;
2807}
2808
2809void iwl_bg_monitor_recover(unsigned long data)
2810{
2811 struct iwl_priv *priv = (struct iwl_priv *)data;
2812 int cnt;
2813
2814 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2815 return;
2816
2817 /* monitor and check for stuck cmd queue */
2818 if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
2819 return;
2820
2821 /* monitor and check for other stuck queues */
2822 if (iwl_is_associated(priv)) {
2823 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
2824 /* skip as we already checked the command queue */
2825 if (cnt == IWL_CMD_QUEUE_NUM)
2826 continue;
2827 if (iwl_check_stuck_queue(priv, cnt))
2828 return;
2829 }
2830 }
2831 /*
2832 * Reschedule the timer to occur in
2833 * priv->cfg->monitor_recover_period
2834 */
2835 mod_timer(&priv->monitor_recover,
2836 jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
2837}
2838EXPORT_SYMBOL(iwl_bg_monitor_recover);
3406 2839
3407#ifdef CONFIG_PM 2840#ifdef CONFIG_PM
3408 2841
@@ -3432,6 +2865,12 @@ int iwl_pci_resume(struct pci_dev *pdev)
3432 struct iwl_priv *priv = pci_get_drvdata(pdev); 2865 struct iwl_priv *priv = pci_get_drvdata(pdev);
3433 int ret; 2866 int ret;
3434 2867
2868 /*
2869 * We disable the RETRY_TIMEOUT register (0x41) to keep
2870 * PCI Tx retries from interfering with C3 CPU state.
2871 */
2872 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
2873
3435 pci_set_power_state(pdev, PCI_D0); 2874 pci_set_power_state(pdev, PCI_D0);
3436 ret = pci_enable_device(pdev); 2875 ret = pci_enable_device(pdev);
3437 if (ret) 2876 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 36940a9ec6b9..7e5a5ba41fd2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -90,6 +90,7 @@ struct iwl_hcmd_ops {
90 int (*commit_rxon)(struct iwl_priv *priv); 90 int (*commit_rxon)(struct iwl_priv *priv);
91 void (*set_rxon_chain)(struct iwl_priv *priv); 91 void (*set_rxon_chain)(struct iwl_priv *priv);
92 int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); 92 int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
93 void (*send_bt_config)(struct iwl_priv *priv);
93}; 94};
94 95
95struct iwl_hcmd_utils_ops { 96struct iwl_hcmd_utils_ops {
@@ -105,6 +106,7 @@ struct iwl_hcmd_utils_ops {
105 __le32 *tx_flags); 106 __le32 *tx_flags);
106 int (*calc_rssi)(struct iwl_priv *priv, 107 int (*calc_rssi)(struct iwl_priv *priv,
107 struct iwl_rx_phy_res *rx_resp); 108 struct iwl_rx_phy_res *rx_resp);
109 void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
108}; 110};
109 111
110struct iwl_apm_ops { 112struct iwl_apm_ops {
@@ -114,23 +116,21 @@ struct iwl_apm_ops {
114 int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); 116 int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
115}; 117};
116 118
119struct iwl_debugfs_ops {
120 ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
121 size_t count, loff_t *ppos);
122 ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
123 size_t count, loff_t *ppos);
124 ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
125 size_t count, loff_t *ppos);
126};
127
117struct iwl_temp_ops { 128struct iwl_temp_ops {
118 void (*temperature)(struct iwl_priv *priv); 129 void (*temperature)(struct iwl_priv *priv);
119 void (*set_ct_kill)(struct iwl_priv *priv); 130 void (*set_ct_kill)(struct iwl_priv *priv);
120 void (*set_calib_version)(struct iwl_priv *priv); 131 void (*set_calib_version)(struct iwl_priv *priv);
121}; 132};
122 133
123struct iwl_ucode_ops {
124 u32 (*get_header_size)(u32);
125 u32 (*get_build)(const struct iwl_ucode_header *, u32);
126 u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
127 u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
128 u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
129 u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
130 u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
131 u8 * (*get_data)(const struct iwl_ucode_header *, u32);
132};
133
134struct iwl_lib_ops { 134struct iwl_lib_ops {
135 /* set hw dependent parameters */ 135 /* set hw dependent parameters */
136 int (*set_hw_params)(struct iwl_priv *priv); 136 int (*set_hw_params)(struct iwl_priv *priv);
@@ -180,8 +180,9 @@ struct iwl_lib_ops {
180 /* power */ 180 /* power */
181 int (*send_tx_power) (struct iwl_priv *priv); 181 int (*send_tx_power) (struct iwl_priv *priv);
182 void (*update_chain_flags)(struct iwl_priv *priv); 182 void (*update_chain_flags)(struct iwl_priv *priv);
183 void (*post_associate) (struct iwl_priv *priv); 183 void (*post_associate)(struct iwl_priv *priv,
184 void (*config_ap) (struct iwl_priv *priv); 184 struct ieee80211_vif *vif);
185 void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
185 irqreturn_t (*isr) (int irq, void *data); 186 irqreturn_t (*isr) (int irq, void *data);
186 187
187 /* eeprom operations (as defined in iwl-eeprom.h) */ 188 /* eeprom operations (as defined in iwl-eeprom.h) */
@@ -190,7 +191,17 @@ struct iwl_lib_ops {
190 /* temperature */ 191 /* temperature */
191 struct iwl_temp_ops temp_ops; 192 struct iwl_temp_ops temp_ops;
192 /* station management */ 193 /* station management */
193 void (*add_bcast_station)(struct iwl_priv *priv); 194 int (*manage_ibss_station)(struct iwl_priv *priv,
195 struct ieee80211_vif *vif, bool add);
196 /* recover from tx queue stall */
197 void (*recover_from_tx_stall)(unsigned long data);
198 /* check for plcp health */
199 bool (*check_plcp_health)(struct iwl_priv *priv,
200 struct iwl_rx_packet *pkt);
201 /* check for ack health */
202 bool (*check_ack_health)(struct iwl_priv *priv,
203 struct iwl_rx_packet *pkt);
204 struct iwl_debugfs_ops debugfs_ops;
194}; 205};
195 206
196struct iwl_led_ops { 207struct iwl_led_ops {
@@ -200,7 +211,6 @@ struct iwl_led_ops {
200}; 211};
201 212
202struct iwl_ops { 213struct iwl_ops {
203 const struct iwl_ucode_ops *ucode;
204 const struct iwl_lib_ops *lib; 214 const struct iwl_lib_ops *lib;
205 const struct iwl_hcmd_ops *hcmd; 215 const struct iwl_hcmd_ops *hcmd;
206 const struct iwl_hcmd_utils_ops *utils; 216 const struct iwl_hcmd_utils_ops *utils;
@@ -237,6 +247,18 @@ struct iwl_mod_params {
237 * @support_wimax_coexist: support wimax/wifi co-exist 247 * @support_wimax_coexist: support wimax/wifi co-exist
238 * @plcp_delta_threshold: plcp error rate threshold used to trigger 248 * @plcp_delta_threshold: plcp error rate threshold used to trigger
239 * radio tuning when there is a high receiving plcp error rate 249 * radio tuning when there is a high receiving plcp error rate
250 * @chain_noise_scale: default chain noise scale used for gain computation
251 * @monitor_recover_period: default timer used to check stuck queues
252 * @temperature_kelvin: temperature report by uCode in kelvin
253 * @max_event_log_size: size of event log buffer size for ucode event logging
254 * @tx_power_by_driver: tx power calibration performed by driver
255 * instead of uCode
256 * @ucode_tracing: support ucode continuous tracing
257 * @sensitivity_calib_by_driver: driver has the capability to perform
258 * sensitivity calibration operation
259 * @chain_noise_calib_by_driver: driver has the capability to perform
260 * chain noise calibration operation
261 * @scan_antennas: available antenna for scan operation
240 * 262 *
241 * We enable the driver to be backward compatible wrt API version. The 263 * We enable the driver to be backward compatible wrt API version. The
242 * driver specifies which APIs it supports (with @ucode_api_max being the 264 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -295,6 +317,15 @@ struct iwl_cfg {
295 const bool support_wimax_coexist; 317 const bool support_wimax_coexist;
296 u8 plcp_delta_threshold; 318 u8 plcp_delta_threshold;
297 s32 chain_noise_scale; 319 s32 chain_noise_scale;
320 /* timer period for monitor the driver queues */
321 u32 monitor_recover_period;
322 bool temperature_kelvin;
323 u32 max_event_log_size;
324 const bool tx_power_by_driver;
325 const bool ucode_tracing;
326 const bool sensitivity_calib_by_driver;
327 const bool chain_noise_calib_by_driver;
328 u8 scan_antennas[IEEE80211_NUM_BANDS];
298}; 329};
299 330
300/*************************** 331/***************************
@@ -304,8 +335,7 @@ struct iwl_cfg {
304struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 335struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
305 struct ieee80211_ops *hw_ops); 336 struct ieee80211_ops *hw_ops);
306void iwl_hw_detect(struct iwl_priv *priv); 337void iwl_hw_detect(struct iwl_priv *priv);
307void iwl_reset_qos(struct iwl_priv *priv); 338void iwl_activate_qos(struct iwl_priv *priv);
308void iwl_activate_qos(struct iwl_priv *priv, u8 force);
309int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 339int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
310 const struct ieee80211_tx_queue_params *params); 340 const struct ieee80211_tx_queue_params *params);
311void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); 341void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
@@ -316,8 +346,8 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
316void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); 346void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
317u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, 347u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
318 struct ieee80211_sta_ht_cap *sta_ht_inf); 348 struct ieee80211_sta_ht_cap *sta_ht_inf);
319void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band); 349void iwl_connection_init_rx_config(struct iwl_priv *priv,
320void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode); 350 struct ieee80211_vif *vif);
321int iwl_set_decrypted_flag(struct iwl_priv *priv, 351int iwl_set_decrypted_flag(struct iwl_priv *priv,
322 struct ieee80211_hdr *hdr, 352 struct ieee80211_hdr *hdr,
323 u32 decrypt_res, 353 u32 decrypt_res,
@@ -326,29 +356,25 @@ void iwl_irq_handle_error(struct iwl_priv *priv);
326void iwl_configure_filter(struct ieee80211_hw *hw, 356void iwl_configure_filter(struct ieee80211_hw *hw,
327 unsigned int changed_flags, 357 unsigned int changed_flags,
328 unsigned int *total_flags, u64 multicast); 358 unsigned int *total_flags, u64 multicast);
329int iwl_hw_nic_init(struct iwl_priv *priv);
330int iwl_set_hw_params(struct iwl_priv *priv); 359int iwl_set_hw_params(struct iwl_priv *priv);
331bool iwl_is_monitor_mode(struct iwl_priv *priv); 360void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
332void iwl_post_associate(struct iwl_priv *priv);
333void iwl_bss_info_changed(struct ieee80211_hw *hw, 361void iwl_bss_info_changed(struct ieee80211_hw *hw,
334 struct ieee80211_vif *vif, 362 struct ieee80211_vif *vif,
335 struct ieee80211_bss_conf *bss_conf, 363 struct ieee80211_bss_conf *bss_conf,
336 u32 changes); 364 u32 changes);
337int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); 365int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
338int iwl_commit_rxon(struct iwl_priv *priv); 366int iwl_commit_rxon(struct iwl_priv *priv);
339int iwl_set_mode(struct iwl_priv *priv, int mode);
340int iwl_mac_add_interface(struct ieee80211_hw *hw, 367int iwl_mac_add_interface(struct ieee80211_hw *hw,
341 struct ieee80211_vif *vif); 368 struct ieee80211_vif *vif);
342void iwl_mac_remove_interface(struct ieee80211_hw *hw, 369void iwl_mac_remove_interface(struct ieee80211_hw *hw,
343 struct ieee80211_vif *vif); 370 struct ieee80211_vif *vif);
344int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 371int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
345void iwl_config_ap(struct iwl_priv *priv); 372void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
346void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 373void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
347int iwl_alloc_txq_mem(struct iwl_priv *priv); 374int iwl_alloc_txq_mem(struct iwl_priv *priv);
348void iwl_free_txq_mem(struct iwl_priv *priv); 375void iwl_free_txq_mem(struct iwl_priv *priv);
349void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info, 376void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
350 __le32 *tx_flags); 377 __le32 *tx_flags);
351int iwl_send_wimax_coex(struct iwl_priv *priv);
352#ifdef CONFIG_IWLWIFI_DEBUGFS 378#ifdef CONFIG_IWLWIFI_DEBUGFS
353int iwl_alloc_traffic_mem(struct iwl_priv *priv); 379int iwl_alloc_traffic_mem(struct iwl_priv *priv);
354void iwl_free_traffic_mem(struct iwl_priv *priv); 380void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -411,26 +437,24 @@ void iwl_rx_reply_error(struct iwl_priv *priv,
411/***************************************************** 437/*****************************************************
412* RX 438* RX
413******************************************************/ 439******************************************************/
414void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
415void iwl_cmd_queue_free(struct iwl_priv *priv); 440void iwl_cmd_queue_free(struct iwl_priv *priv);
416int iwl_rx_queue_alloc(struct iwl_priv *priv); 441int iwl_rx_queue_alloc(struct iwl_priv *priv);
417void iwl_rx_handle(struct iwl_priv *priv); 442void iwl_rx_handle(struct iwl_priv *priv);
418void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, 443void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
419 struct iwl_rx_queue *q); 444 struct iwl_rx_queue *q);
420void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
421void iwl_rx_replenish(struct iwl_priv *priv);
422void iwl_rx_replenish_now(struct iwl_priv *priv);
423int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
424void iwl_rx_queue_restock(struct iwl_priv *priv);
425int iwl_rx_queue_space(const struct iwl_rx_queue *q); 445int iwl_rx_queue_space(const struct iwl_rx_queue *q);
426void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
427void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 446void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
428int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
429/* Handlers */ 447/* Handlers */
430void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 448void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
431 struct iwl_rx_mem_buffer *rxb); 449 struct iwl_rx_mem_buffer *rxb);
432void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 450void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb); 451 struct iwl_rx_mem_buffer *rxb);
452bool iwl_good_plcp_health(struct iwl_priv *priv,
453 struct iwl_rx_packet *pkt);
454bool iwl_good_ack_health(struct iwl_priv *priv,
455 struct iwl_rx_packet *pkt);
456void iwl_recover_from_statistics(struct iwl_priv *priv,
457 struct iwl_rx_packet *pkt);
434void iwl_rx_statistics(struct iwl_priv *priv, 458void iwl_rx_statistics(struct iwl_priv *priv,
435 struct iwl_rx_mem_buffer *rxb); 459 struct iwl_rx_mem_buffer *rxb);
436void iwl_reply_statistics(struct iwl_priv *priv, 460void iwl_reply_statistics(struct iwl_priv *priv,
@@ -442,14 +466,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
442/***************************************************** 466/*****************************************************
443* TX 467* TX
444******************************************************/ 468******************************************************/
445int iwl_txq_ctx_alloc(struct iwl_priv *priv);
446void iwl_txq_ctx_reset(struct iwl_priv *priv);
447void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 469void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
448int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, 470int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
449 struct iwl_tx_queue *txq, 471 struct iwl_tx_queue *txq,
450 dma_addr_t addr, u16 len, u8 reset, u8 pad); 472 dma_addr_t addr, u16 len, u8 reset, u8 pad);
451int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
452void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
453int iwl_hw_tx_queue_init(struct iwl_priv *priv, 473int iwl_hw_tx_queue_init(struct iwl_priv *priv,
454 struct iwl_tx_queue *txq); 474 struct iwl_tx_queue *txq);
455void iwl_free_tfds_in_queue(struct iwl_priv *priv, 475void iwl_free_tfds_in_queue(struct iwl_priv *priv,
@@ -460,9 +480,6 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
460void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, 480void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
461 int slots_num, u32 txq_id); 481 int slots_num, u32 txq_id);
462void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 482void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
463int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
464int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
465int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
466/***************************************************** 483/*****************************************************
467 * TX power 484 * TX power
468 ****************************************************/ 485 ****************************************************/
@@ -472,10 +489,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
472 * Rate 489 * Rate
473 ******************************************************************************/ 490 ******************************************************************************/
474 491
475void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
476 struct ieee80211_tx_info *info);
477int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); 492int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
478int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
479 493
480u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 494u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
481 495
@@ -505,7 +519,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
505void iwl_init_scan_params(struct iwl_priv *priv); 519void iwl_init_scan_params(struct iwl_priv *priv);
506int iwl_scan_cancel(struct iwl_priv *priv); 520int iwl_scan_cancel(struct iwl_priv *priv);
507int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 521int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
508int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 522int iwl_mac_hw_scan(struct ieee80211_hw *hw,
523 struct ieee80211_vif *vif,
524 struct cfg80211_scan_request *req);
525void iwl_bg_start_internal_scan(struct work_struct *work);
509void iwl_internal_short_hw_scan(struct iwl_priv *priv); 526void iwl_internal_short_hw_scan(struct iwl_priv *priv);
510int iwl_force_reset(struct iwl_priv *priv, int mode); 527int iwl_force_reset(struct iwl_priv *priv, int mode);
511u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 528u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
@@ -515,7 +532,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
515 enum ieee80211_band band, 532 enum ieee80211_band band,
516 u8 n_probes); 533 u8 n_probes);
517u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, 534u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
518 enum ieee80211_band band); 535 enum ieee80211_band band,
536 struct ieee80211_vif *vif);
519void iwl_bg_scan_check(struct work_struct *data); 537void iwl_bg_scan_check(struct work_struct *data);
520void iwl_bg_abort_scan(struct work_struct *work); 538void iwl_bg_abort_scan(struct work_struct *work);
521void iwl_bg_scan_completed(struct work_struct *work); 539void iwl_bg_scan_completed(struct work_struct *work);
@@ -530,6 +548,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
530#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */ 548#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
531#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */ 549#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
532 550
551#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
533 552
534/******************************************************************************* 553/*******************************************************************************
535 * Calibrations - implemented in iwl-calib.c 554 * Calibrations - implemented in iwl-calib.c
@@ -563,11 +582,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
563 * PCI * 582 * PCI *
564 *****************************************************/ 583 *****************************************************/
565irqreturn_t iwl_isr_legacy(int irq, void *data); 584irqreturn_t iwl_isr_legacy(int irq, void *data);
566int iwl_reset_ict(struct iwl_priv *priv);
567void iwl_disable_ict(struct iwl_priv *priv);
568int iwl_alloc_isr_ict(struct iwl_priv *priv);
569void iwl_free_isr_ict(struct iwl_priv *priv);
570irqreturn_t iwl_isr_ict(int irq, void *data);
571 585
572static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) 586static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
573{ 587{
@@ -577,6 +591,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
577 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); 591 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
578 return pci_lnk_ctl; 592 return pci_lnk_ctl;
579} 593}
594
595void iwl_bg_monitor_recover(unsigned long data);
596
580#ifdef CONFIG_PM 597#ifdef CONFIG_PM
581int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 598int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
582int iwl_pci_resume(struct pci_dev *pdev); 599int iwl_pci_resume(struct pci_dev *pdev);
@@ -625,7 +642,6 @@ void iwlcore_free_geos(struct iwl_priv *priv);
625#define STATUS_SCAN_HW 15 642#define STATUS_SCAN_HW 15
626#define STATUS_POWER_PMI 16 643#define STATUS_POWER_PMI 16
627#define STATUS_FW_ERROR 17 644#define STATUS_FW_ERROR 17
628#define STATUS_MODE_PENDING 18
629 645
630 646
631static inline int iwl_is_ready(struct iwl_priv *priv) 647static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -672,23 +688,16 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
672} 688}
673 689
674extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); 690extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
675extern int iwl_send_bt_config(struct iwl_priv *priv); 691extern void iwl_send_bt_config(struct iwl_priv *priv);
676extern int iwl_send_statistics_request(struct iwl_priv *priv, 692extern int iwl_send_statistics_request(struct iwl_priv *priv,
677 u8 flags, bool clear); 693 u8 flags, bool clear);
678extern int iwl_verify_ucode(struct iwl_priv *priv); 694extern int iwl_verify_ucode(struct iwl_priv *priv);
679extern int iwl_send_lq_cmd(struct iwl_priv *priv, 695extern int iwl_send_lq_cmd(struct iwl_priv *priv,
680 struct iwl_link_quality_cmd *lq, u8 flags); 696 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
681extern void iwl_rx_reply_rx(struct iwl_priv *priv,
682 struct iwl_rx_mem_buffer *rxb);
683extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
684 struct iwl_rx_mem_buffer *rxb);
685void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
686 struct iwl_rx_mem_buffer *rxb);
687void iwl_apm_stop(struct iwl_priv *priv); 697void iwl_apm_stop(struct iwl_priv *priv);
688int iwl_apm_stop_master(struct iwl_priv *priv);
689int iwl_apm_init(struct iwl_priv *priv); 698int iwl_apm_init(struct iwl_priv *priv);
690 699
691void iwl_setup_rxon_timing(struct iwl_priv *priv); 700void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
692static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 701static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
693{ 702{
694 return priv->cfg->ops->hcmd->rxon_assoc(priv); 703 return priv->cfg->ops->hcmd->rxon_assoc(priv);
@@ -697,9 +706,10 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
697{ 706{
698 return priv->cfg->ops->hcmd->commit_rxon(priv); 707 return priv->cfg->ops->hcmd->commit_rxon(priv);
699} 708}
700static inline void iwlcore_config_ap(struct iwl_priv *priv) 709static inline void iwlcore_config_ap(struct iwl_priv *priv,
710 struct ieee80211_vif *vif)
701{ 711{
702 priv->cfg->ops->lib->config_ap(priv); 712 priv->cfg->ops->lib->config_ap(priv, vif);
703} 713}
704static inline const struct ieee80211_supported_band *iwl_get_hw_mode( 714static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
705 struct iwl_priv *priv, enum ieee80211_band band) 715 struct iwl_priv *priv, enum ieee80211_band band)
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 808b7146bead..254c35ae8b38 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -298,6 +298,7 @@
298#define CSR_HW_REV_TYPE_1000 (0x0000060) 298#define CSR_HW_REV_TYPE_1000 (0x0000060)
299#define CSR_HW_REV_TYPE_6x00 (0x0000070) 299#define CSR_HW_REV_TYPE_6x00 (0x0000070)
300#define CSR_HW_REV_TYPE_6x50 (0x0000080) 300#define CSR_HW_REV_TYPE_6x50 (0x0000080)
301#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0)
301#define CSR_HW_REV_TYPE_NONE (0x00000F0) 302#define CSR_HW_REV_TYPE_NONE (0x00000F0)
302 303
303/* EEPROM REG */ 304/* EEPROM REG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 1c7b53d511c7..5c2bcef5df0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -78,6 +78,8 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
78#ifdef CONFIG_IWLWIFI_DEBUGFS 78#ifdef CONFIG_IWLWIFI_DEBUGFS
79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name); 79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
80void iwl_dbgfs_unregister(struct iwl_priv *priv); 80void iwl_dbgfs_unregister(struct iwl_priv *priv);
81extern int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
82 int bufsz);
81#else 83#else
82static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 84static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
83{ 85{
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index b6e1b0ebe230..9659c5d01df9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -106,6 +106,26 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
106 .open = iwl_dbgfs_open_file_generic, \ 106 .open = iwl_dbgfs_open_file_generic, \
107}; 107};
108 108
109int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
110{
111 int p = 0;
112
113 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
114 le32_to_cpu(priv->statistics.flag));
115 if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
116 p += scnprintf(buf + p, bufsz - p,
117 "\tStatistics have been cleared\n");
118 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
119 (le32_to_cpu(priv->statistics.flag) &
120 UCODE_STATISTICS_FREQUENCY_MSK)
121 ? "2.4 GHz" : "5.2 GHz");
122 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
123 (le32_to_cpu(priv->statistics.flag) &
124 UCODE_STATISTICS_NARROW_BAND_MSK)
125 ? "enabled" : "disabled");
126 return p;
127}
128EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
109 129
110static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 130static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
111 char __user *user_buf, 131 char __user *user_buf,
@@ -561,8 +581,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
561 test_bit(STATUS_POWER_PMI, &priv->status)); 581 test_bit(STATUS_POWER_PMI, &priv->status));
562 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 582 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
563 test_bit(STATUS_FW_ERROR, &priv->status)); 583 test_bit(STATUS_FW_ERROR, &priv->status));
564 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
565 test_bit(STATUS_MODE_PENDING, &priv->status));
566 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 584 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
567} 585}
568 586
@@ -661,7 +679,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
661 int pos = 0, i; 679 int pos = 0, i;
662 char buf[256]; 680 char buf[256];
663 const size_t bufsz = sizeof(buf); 681 const size_t bufsz = sizeof(buf);
664 ssize_t ret;
665 682
666 for (i = 0; i < AC_NUM; i++) { 683 for (i = 0; i < AC_NUM; i++) {
667 pos += scnprintf(buf + pos, bufsz - pos, 684 pos += scnprintf(buf + pos, bufsz - pos,
@@ -673,8 +690,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
673 priv->qos_data.def_qos_parm.ac[i].aifsn, 690 priv->qos_data.def_qos_parm.ac[i].aifsn,
674 priv->qos_data.def_qos_parm.ac[i].edca_txop); 691 priv->qos_data.def_qos_parm.ac[i].edca_txop);
675 } 692 }
676 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 693 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
677 return ret;
678} 694}
679 695
680static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 696static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
@@ -684,7 +700,6 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
684 int pos = 0; 700 int pos = 0;
685 char buf[256]; 701 char buf[256];
686 const size_t bufsz = sizeof(buf); 702 const size_t bufsz = sizeof(buf);
687 ssize_t ret;
688 703
689 pos += scnprintf(buf + pos, bufsz - pos, 704 pos += scnprintf(buf + pos, bufsz - pos,
690 "allow blinking: %s\n", 705 "allow blinking: %s\n",
@@ -698,8 +713,7 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
698 priv->last_blink_time); 713 priv->last_blink_time);
699 } 714 }
700 715
701 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 716 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
702 return ret;
703} 717}
704 718
705static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 719static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
@@ -712,7 +726,6 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
712 char buf[100]; 726 char buf[100];
713 int pos = 0; 727 int pos = 0;
714 const size_t bufsz = sizeof(buf); 728 const size_t bufsz = sizeof(buf);
715 ssize_t ret;
716 729
717 pos += scnprintf(buf + pos, bufsz - pos, 730 pos += scnprintf(buf + pos, bufsz - pos,
718 "Thermal Throttling Mode: %s\n", 731 "Thermal Throttling Mode: %s\n",
@@ -732,8 +745,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
732 "HT mode: %d\n", 745 "HT mode: %d\n",
733 restriction->is_ht); 746 restriction->is_ht);
734 } 747 }
735 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 748 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
736 return ret;
737} 749}
738 750
739static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 751static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
@@ -770,13 +782,11 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
770 char buf[100]; 782 char buf[100];
771 int pos = 0; 783 int pos = 0;
772 const size_t bufsz = sizeof(buf); 784 const size_t bufsz = sizeof(buf);
773 ssize_t ret;
774 785
775 pos += scnprintf(buf + pos, bufsz - pos, 786 pos += scnprintf(buf + pos, bufsz - pos,
776 "11n 40MHz Mode: %s\n", 787 "11n 40MHz Mode: %s\n",
777 priv->disable_ht40 ? "Disabled" : "Enabled"); 788 priv->disable_ht40 ? "Disabled" : "Enabled");
778 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 789 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
779 return ret;
780} 790}
781 791
782static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 792static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
@@ -1044,474 +1054,13 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1044 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1054 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1045} 1055}
1046 1056
1047static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1048 int bufsz)
1049{
1050 int p = 0;
1051
1052 p += scnprintf(buf + p, bufsz - p,
1053 "Statistics Flag(0x%X):\n",
1054 le32_to_cpu(priv->statistics.flag));
1055 if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
1056 p += scnprintf(buf + p, bufsz - p,
1057 "\tStatistics have been cleared\n");
1058 p += scnprintf(buf + p, bufsz - p,
1059 "\tOperational Frequency: %s\n",
1060 (le32_to_cpu(priv->statistics.flag) &
1061 UCODE_STATISTICS_FREQUENCY_MSK)
1062 ? "2.4 GHz" : "5.2 GHz");
1063 p += scnprintf(buf + p, bufsz - p,
1064 "\tTGj Narrow Band: %s\n",
1065 (le32_to_cpu(priv->statistics.flag) &
1066 UCODE_STATISTICS_NARROW_BAND_MSK)
1067 ? "enabled" : "disabled");
1068 return p;
1069}
1070
1071static const char ucode_stats_header[] =
1072 "%-32s current acumulative delta max\n";
1073static const char ucode_stats_short_format[] =
1074 " %-30s %10u\n";
1075static const char ucode_stats_format[] =
1076 " %-30s %10u %10u %10u %10u\n";
1077
1078static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1057static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1079 char __user *user_buf, 1058 char __user *user_buf,
1080 size_t count, loff_t *ppos) 1059 size_t count, loff_t *ppos)
1081{ 1060{
1082 struct iwl_priv *priv = file->private_data; 1061 struct iwl_priv *priv = file->private_data;
1083 int pos = 0; 1062 return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
1084 char *buf; 1063 user_buf, count, ppos);
1085 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1086 sizeof(struct statistics_rx_non_phy) * 40 +
1087 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1088 ssize_t ret;
1089 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1090 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1091 struct statistics_rx_non_phy *general, *accum_general;
1092 struct statistics_rx_non_phy *delta_general, *max_general;
1093 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1094
1095 if (!iwl_is_alive(priv))
1096 return -EAGAIN;
1097
1098 buf = kzalloc(bufsz, GFP_KERNEL);
1099 if (!buf) {
1100 IWL_ERR(priv, "Can not allocate Buffer\n");
1101 return -ENOMEM;
1102 }
1103
1104 /* the statistic information display here is based on
1105 * the last statistics notification from uCode
1106 * might not reflect the current uCode activity
1107 */
1108 ofdm = &priv->statistics.rx.ofdm;
1109 cck = &priv->statistics.rx.cck;
1110 general = &priv->statistics.rx.general;
1111 ht = &priv->statistics.rx.ofdm_ht;
1112 accum_ofdm = &priv->accum_statistics.rx.ofdm;
1113 accum_cck = &priv->accum_statistics.rx.cck;
1114 accum_general = &priv->accum_statistics.rx.general;
1115 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1116 delta_ofdm = &priv->delta_statistics.rx.ofdm;
1117 delta_cck = &priv->delta_statistics.rx.cck;
1118 delta_general = &priv->delta_statistics.rx.general;
1119 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1120 max_ofdm = &priv->max_delta.rx.ofdm;
1121 max_cck = &priv->max_delta.rx.cck;
1122 max_general = &priv->max_delta.rx.general;
1123 max_ht = &priv->max_delta.rx.ofdm_ht;
1124
1125 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1126 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1127 "Statistics_Rx - OFDM:");
1128 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1129 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1130 accum_ofdm->ina_cnt,
1131 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1132 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1133 "fina_cnt:",
1134 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1135 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1136 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1137 "plcp_err:",
1138 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1139 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1140 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1141 "crc32_err:",
1142 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1143 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1144 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1145 "overrun_err:",
1146 le32_to_cpu(ofdm->overrun_err),
1147 accum_ofdm->overrun_err,
1148 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1149 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1150 "early_overrun_err:",
1151 le32_to_cpu(ofdm->early_overrun_err),
1152 accum_ofdm->early_overrun_err,
1153 delta_ofdm->early_overrun_err,
1154 max_ofdm->early_overrun_err);
1155 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1156 "crc32_good:",
1157 le32_to_cpu(ofdm->crc32_good),
1158 accum_ofdm->crc32_good,
1159 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1160 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1161 "false_alarm_cnt:",
1162 le32_to_cpu(ofdm->false_alarm_cnt),
1163 accum_ofdm->false_alarm_cnt,
1164 delta_ofdm->false_alarm_cnt,
1165 max_ofdm->false_alarm_cnt);
1166 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1167 "fina_sync_err_cnt:",
1168 le32_to_cpu(ofdm->fina_sync_err_cnt),
1169 accum_ofdm->fina_sync_err_cnt,
1170 delta_ofdm->fina_sync_err_cnt,
1171 max_ofdm->fina_sync_err_cnt);
1172 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1173 "sfd_timeout:",
1174 le32_to_cpu(ofdm->sfd_timeout),
1175 accum_ofdm->sfd_timeout,
1176 delta_ofdm->sfd_timeout,
1177 max_ofdm->sfd_timeout);
1178 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1179 "fina_timeout:",
1180 le32_to_cpu(ofdm->fina_timeout),
1181 accum_ofdm->fina_timeout,
1182 delta_ofdm->fina_timeout,
1183 max_ofdm->fina_timeout);
1184 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1185 "unresponded_rts:",
1186 le32_to_cpu(ofdm->unresponded_rts),
1187 accum_ofdm->unresponded_rts,
1188 delta_ofdm->unresponded_rts,
1189 max_ofdm->unresponded_rts);
1190 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1191 "rxe_frame_lmt_ovrun:",
1192 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1193 accum_ofdm->rxe_frame_limit_overrun,
1194 delta_ofdm->rxe_frame_limit_overrun,
1195 max_ofdm->rxe_frame_limit_overrun);
1196 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1197 "sent_ack_cnt:",
1198 le32_to_cpu(ofdm->sent_ack_cnt),
1199 accum_ofdm->sent_ack_cnt,
1200 delta_ofdm->sent_ack_cnt,
1201 max_ofdm->sent_ack_cnt);
1202 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1203 "sent_cts_cnt:",
1204 le32_to_cpu(ofdm->sent_cts_cnt),
1205 accum_ofdm->sent_cts_cnt,
1206 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1207 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1208 "sent_ba_rsp_cnt:",
1209 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1210 accum_ofdm->sent_ba_rsp_cnt,
1211 delta_ofdm->sent_ba_rsp_cnt,
1212 max_ofdm->sent_ba_rsp_cnt);
1213 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1214 "dsp_self_kill:",
1215 le32_to_cpu(ofdm->dsp_self_kill),
1216 accum_ofdm->dsp_self_kill,
1217 delta_ofdm->dsp_self_kill,
1218 max_ofdm->dsp_self_kill);
1219 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1220 "mh_format_err:",
1221 le32_to_cpu(ofdm->mh_format_err),
1222 accum_ofdm->mh_format_err,
1223 delta_ofdm->mh_format_err,
1224 max_ofdm->mh_format_err);
1225 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1226 "re_acq_main_rssi_sum:",
1227 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1228 accum_ofdm->re_acq_main_rssi_sum,
1229 delta_ofdm->re_acq_main_rssi_sum,
1230 max_ofdm->re_acq_main_rssi_sum);
1231
1232 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1233 "Statistics_Rx - CCK:");
1234 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1235 "ina_cnt:",
1236 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1237 delta_cck->ina_cnt, max_cck->ina_cnt);
1238 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1239 "fina_cnt:",
1240 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1241 delta_cck->fina_cnt, max_cck->fina_cnt);
1242 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1243 "plcp_err:",
1244 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1245 delta_cck->plcp_err, max_cck->plcp_err);
1246 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1247 "crc32_err:",
1248 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1249 delta_cck->crc32_err, max_cck->crc32_err);
1250 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1251 "overrun_err:",
1252 le32_to_cpu(cck->overrun_err),
1253 accum_cck->overrun_err,
1254 delta_cck->overrun_err, max_cck->overrun_err);
1255 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1256 "early_overrun_err:",
1257 le32_to_cpu(cck->early_overrun_err),
1258 accum_cck->early_overrun_err,
1259 delta_cck->early_overrun_err,
1260 max_cck->early_overrun_err);
1261 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1262 "crc32_good:",
1263 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1264 delta_cck->crc32_good,
1265 max_cck->crc32_good);
1266 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1267 "false_alarm_cnt:",
1268 le32_to_cpu(cck->false_alarm_cnt),
1269 accum_cck->false_alarm_cnt,
1270 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1271 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1272 "fina_sync_err_cnt:",
1273 le32_to_cpu(cck->fina_sync_err_cnt),
1274 accum_cck->fina_sync_err_cnt,
1275 delta_cck->fina_sync_err_cnt,
1276 max_cck->fina_sync_err_cnt);
1277 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1278 "sfd_timeout:",
1279 le32_to_cpu(cck->sfd_timeout),
1280 accum_cck->sfd_timeout,
1281 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1282 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1283 "fina_timeout:",
1284 le32_to_cpu(cck->fina_timeout),
1285 accum_cck->fina_timeout,
1286 delta_cck->fina_timeout, max_cck->fina_timeout);
1287 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1288 "unresponded_rts:",
1289 le32_to_cpu(cck->unresponded_rts),
1290 accum_cck->unresponded_rts,
1291 delta_cck->unresponded_rts,
1292 max_cck->unresponded_rts);
1293 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1294 "rxe_frame_lmt_ovrun:",
1295 le32_to_cpu(cck->rxe_frame_limit_overrun),
1296 accum_cck->rxe_frame_limit_overrun,
1297 delta_cck->rxe_frame_limit_overrun,
1298 max_cck->rxe_frame_limit_overrun);
1299 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1300 "sent_ack_cnt:",
1301 le32_to_cpu(cck->sent_ack_cnt),
1302 accum_cck->sent_ack_cnt,
1303 delta_cck->sent_ack_cnt,
1304 max_cck->sent_ack_cnt);
1305 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1306 "sent_cts_cnt:",
1307 le32_to_cpu(cck->sent_cts_cnt),
1308 accum_cck->sent_cts_cnt,
1309 delta_cck->sent_cts_cnt,
1310 max_cck->sent_cts_cnt);
1311 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1312 "sent_ba_rsp_cnt:",
1313 le32_to_cpu(cck->sent_ba_rsp_cnt),
1314 accum_cck->sent_ba_rsp_cnt,
1315 delta_cck->sent_ba_rsp_cnt,
1316 max_cck->sent_ba_rsp_cnt);
1317 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1318 "dsp_self_kill:",
1319 le32_to_cpu(cck->dsp_self_kill),
1320 accum_cck->dsp_self_kill,
1321 delta_cck->dsp_self_kill,
1322 max_cck->dsp_self_kill);
1323 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1324 "mh_format_err:",
1325 le32_to_cpu(cck->mh_format_err),
1326 accum_cck->mh_format_err,
1327 delta_cck->mh_format_err, max_cck->mh_format_err);
1328 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1329 "re_acq_main_rssi_sum:",
1330 le32_to_cpu(cck->re_acq_main_rssi_sum),
1331 accum_cck->re_acq_main_rssi_sum,
1332 delta_cck->re_acq_main_rssi_sum,
1333 max_cck->re_acq_main_rssi_sum);
1334
1335 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1336 "Statistics_Rx - GENERAL:");
1337 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1338 "bogus_cts:",
1339 le32_to_cpu(general->bogus_cts),
1340 accum_general->bogus_cts,
1341 delta_general->bogus_cts, max_general->bogus_cts);
1342 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1343 "bogus_ack:",
1344 le32_to_cpu(general->bogus_ack),
1345 accum_general->bogus_ack,
1346 delta_general->bogus_ack, max_general->bogus_ack);
1347 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1348 "non_bssid_frames:",
1349 le32_to_cpu(general->non_bssid_frames),
1350 accum_general->non_bssid_frames,
1351 delta_general->non_bssid_frames,
1352 max_general->non_bssid_frames);
1353 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1354 "filtered_frames:",
1355 le32_to_cpu(general->filtered_frames),
1356 accum_general->filtered_frames,
1357 delta_general->filtered_frames,
1358 max_general->filtered_frames);
1359 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1360 "non_channel_beacons:",
1361 le32_to_cpu(general->non_channel_beacons),
1362 accum_general->non_channel_beacons,
1363 delta_general->non_channel_beacons,
1364 max_general->non_channel_beacons);
1365 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1366 "channel_beacons:",
1367 le32_to_cpu(general->channel_beacons),
1368 accum_general->channel_beacons,
1369 delta_general->channel_beacons,
1370 max_general->channel_beacons);
1371 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1372 "num_missed_bcon:",
1373 le32_to_cpu(general->num_missed_bcon),
1374 accum_general->num_missed_bcon,
1375 delta_general->num_missed_bcon,
1376 max_general->num_missed_bcon);
1377 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1378 "adc_rx_saturation_time:",
1379 le32_to_cpu(general->adc_rx_saturation_time),
1380 accum_general->adc_rx_saturation_time,
1381 delta_general->adc_rx_saturation_time,
1382 max_general->adc_rx_saturation_time);
1383 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1384 "ina_detect_search_tm:",
1385 le32_to_cpu(general->ina_detection_search_time),
1386 accum_general->ina_detection_search_time,
1387 delta_general->ina_detection_search_time,
1388 max_general->ina_detection_search_time);
1389 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1390 "beacon_silence_rssi_a:",
1391 le32_to_cpu(general->beacon_silence_rssi_a),
1392 accum_general->beacon_silence_rssi_a,
1393 delta_general->beacon_silence_rssi_a,
1394 max_general->beacon_silence_rssi_a);
1395 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1396 "beacon_silence_rssi_b:",
1397 le32_to_cpu(general->beacon_silence_rssi_b),
1398 accum_general->beacon_silence_rssi_b,
1399 delta_general->beacon_silence_rssi_b,
1400 max_general->beacon_silence_rssi_b);
1401 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1402 "beacon_silence_rssi_c:",
1403 le32_to_cpu(general->beacon_silence_rssi_c),
1404 accum_general->beacon_silence_rssi_c,
1405 delta_general->beacon_silence_rssi_c,
1406 max_general->beacon_silence_rssi_c);
1407 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1408 "interference_data_flag:",
1409 le32_to_cpu(general->interference_data_flag),
1410 accum_general->interference_data_flag,
1411 delta_general->interference_data_flag,
1412 max_general->interference_data_flag);
1413 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1414 "channel_load:",
1415 le32_to_cpu(general->channel_load),
1416 accum_general->channel_load,
1417 delta_general->channel_load,
1418 max_general->channel_load);
1419 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1420 "dsp_false_alarms:",
1421 le32_to_cpu(general->dsp_false_alarms),
1422 accum_general->dsp_false_alarms,
1423 delta_general->dsp_false_alarms,
1424 max_general->dsp_false_alarms);
1425 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1426 "beacon_rssi_a:",
1427 le32_to_cpu(general->beacon_rssi_a),
1428 accum_general->beacon_rssi_a,
1429 delta_general->beacon_rssi_a,
1430 max_general->beacon_rssi_a);
1431 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1432 "beacon_rssi_b:",
1433 le32_to_cpu(general->beacon_rssi_b),
1434 accum_general->beacon_rssi_b,
1435 delta_general->beacon_rssi_b,
1436 max_general->beacon_rssi_b);
1437 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1438 "beacon_rssi_c:",
1439 le32_to_cpu(general->beacon_rssi_c),
1440 accum_general->beacon_rssi_c,
1441 delta_general->beacon_rssi_c,
1442 max_general->beacon_rssi_c);
1443 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1444 "beacon_energy_a:",
1445 le32_to_cpu(general->beacon_energy_a),
1446 accum_general->beacon_energy_a,
1447 delta_general->beacon_energy_a,
1448 max_general->beacon_energy_a);
1449 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1450 "beacon_energy_b:",
1451 le32_to_cpu(general->beacon_energy_b),
1452 accum_general->beacon_energy_b,
1453 delta_general->beacon_energy_b,
1454 max_general->beacon_energy_b);
1455 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1456 "beacon_energy_c:",
1457 le32_to_cpu(general->beacon_energy_c),
1458 accum_general->beacon_energy_c,
1459 delta_general->beacon_energy_c,
1460 max_general->beacon_energy_c);
1461
1462 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1463 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1464 "Statistics_Rx - OFDM_HT:");
1465 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1466 "plcp_err:",
1467 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1468 delta_ht->plcp_err, max_ht->plcp_err);
1469 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1470 "overrun_err:",
1471 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1472 delta_ht->overrun_err, max_ht->overrun_err);
1473 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1474 "early_overrun_err:",
1475 le32_to_cpu(ht->early_overrun_err),
1476 accum_ht->early_overrun_err,
1477 delta_ht->early_overrun_err,
1478 max_ht->early_overrun_err);
1479 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1480 "crc32_good:",
1481 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1482 delta_ht->crc32_good, max_ht->crc32_good);
1483 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1484 "crc32_err:",
1485 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1486 delta_ht->crc32_err, max_ht->crc32_err);
1487 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1488 "mh_format_err:",
1489 le32_to_cpu(ht->mh_format_err),
1490 accum_ht->mh_format_err,
1491 delta_ht->mh_format_err, max_ht->mh_format_err);
1492 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1493 "agg_crc32_good:",
1494 le32_to_cpu(ht->agg_crc32_good),
1495 accum_ht->agg_crc32_good,
1496 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1497 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1498 "agg_mpdu_cnt:",
1499 le32_to_cpu(ht->agg_mpdu_cnt),
1500 accum_ht->agg_mpdu_cnt,
1501 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1502 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1503 "agg_cnt:",
1504 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1505 delta_ht->agg_cnt, max_ht->agg_cnt);
1506 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1507 "unsupport_mcs:",
1508 le32_to_cpu(ht->unsupport_mcs),
1509 accum_ht->unsupport_mcs,
1510 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1511
1512 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1513 kfree(buf);
1514 return ret;
1515} 1064}
1516 1065
1517static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, 1066static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1519,173 +1068,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1519 size_t count, loff_t *ppos) 1068 size_t count, loff_t *ppos)
1520{ 1069{
1521 struct iwl_priv *priv = file->private_data; 1070 struct iwl_priv *priv = file->private_data;
1522 int pos = 0; 1071 return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
1523 char *buf; 1072 user_buf, count, ppos);
1524 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1525 ssize_t ret;
1526 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1527
1528 if (!iwl_is_alive(priv))
1529 return -EAGAIN;
1530
1531 buf = kzalloc(bufsz, GFP_KERNEL);
1532 if (!buf) {
1533 IWL_ERR(priv, "Can not allocate Buffer\n");
1534 return -ENOMEM;
1535 }
1536
1537 /* the statistic information display here is based on
1538 * the last statistics notification from uCode
1539 * might not reflect the current uCode activity
1540 */
1541 tx = &priv->statistics.tx;
1542 accum_tx = &priv->accum_statistics.tx;
1543 delta_tx = &priv->delta_statistics.tx;
1544 max_tx = &priv->max_delta.tx;
1545 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1546 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1547 "Statistics_Tx:");
1548 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1549 "preamble:",
1550 le32_to_cpu(tx->preamble_cnt),
1551 accum_tx->preamble_cnt,
1552 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1553 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1554 "rx_detected_cnt:",
1555 le32_to_cpu(tx->rx_detected_cnt),
1556 accum_tx->rx_detected_cnt,
1557 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1558 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1559 "bt_prio_defer_cnt:",
1560 le32_to_cpu(tx->bt_prio_defer_cnt),
1561 accum_tx->bt_prio_defer_cnt,
1562 delta_tx->bt_prio_defer_cnt,
1563 max_tx->bt_prio_defer_cnt);
1564 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1565 "bt_prio_kill_cnt:",
1566 le32_to_cpu(tx->bt_prio_kill_cnt),
1567 accum_tx->bt_prio_kill_cnt,
1568 delta_tx->bt_prio_kill_cnt,
1569 max_tx->bt_prio_kill_cnt);
1570 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1571 "few_bytes_cnt:",
1572 le32_to_cpu(tx->few_bytes_cnt),
1573 accum_tx->few_bytes_cnt,
1574 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1575 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1576 "cts_timeout:",
1577 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1578 delta_tx->cts_timeout, max_tx->cts_timeout);
1579 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1580 "ack_timeout:",
1581 le32_to_cpu(tx->ack_timeout),
1582 accum_tx->ack_timeout,
1583 delta_tx->ack_timeout, max_tx->ack_timeout);
1584 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1585 "expected_ack_cnt:",
1586 le32_to_cpu(tx->expected_ack_cnt),
1587 accum_tx->expected_ack_cnt,
1588 delta_tx->expected_ack_cnt,
1589 max_tx->expected_ack_cnt);
1590 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1591 "actual_ack_cnt:",
1592 le32_to_cpu(tx->actual_ack_cnt),
1593 accum_tx->actual_ack_cnt,
1594 delta_tx->actual_ack_cnt,
1595 max_tx->actual_ack_cnt);
1596 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1597 "dump_msdu_cnt:",
1598 le32_to_cpu(tx->dump_msdu_cnt),
1599 accum_tx->dump_msdu_cnt,
1600 delta_tx->dump_msdu_cnt,
1601 max_tx->dump_msdu_cnt);
1602 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1603 "abort_nxt_frame_mismatch:",
1604 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1605 accum_tx->burst_abort_next_frame_mismatch_cnt,
1606 delta_tx->burst_abort_next_frame_mismatch_cnt,
1607 max_tx->burst_abort_next_frame_mismatch_cnt);
1608 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1609 "abort_missing_nxt_frame:",
1610 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1611 accum_tx->burst_abort_missing_next_frame_cnt,
1612 delta_tx->burst_abort_missing_next_frame_cnt,
1613 max_tx->burst_abort_missing_next_frame_cnt);
1614 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1615 "cts_timeout_collision:",
1616 le32_to_cpu(tx->cts_timeout_collision),
1617 accum_tx->cts_timeout_collision,
1618 delta_tx->cts_timeout_collision,
1619 max_tx->cts_timeout_collision);
1620 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1621 "ack_ba_timeout_collision:",
1622 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1623 accum_tx->ack_or_ba_timeout_collision,
1624 delta_tx->ack_or_ba_timeout_collision,
1625 max_tx->ack_or_ba_timeout_collision);
1626 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1627 "agg ba_timeout:",
1628 le32_to_cpu(tx->agg.ba_timeout),
1629 accum_tx->agg.ba_timeout,
1630 delta_tx->agg.ba_timeout,
1631 max_tx->agg.ba_timeout);
1632 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1633 "agg ba_resched_frames:",
1634 le32_to_cpu(tx->agg.ba_reschedule_frames),
1635 accum_tx->agg.ba_reschedule_frames,
1636 delta_tx->agg.ba_reschedule_frames,
1637 max_tx->agg.ba_reschedule_frames);
1638 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1639 "agg scd_query_agg_frame:",
1640 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1641 accum_tx->agg.scd_query_agg_frame_cnt,
1642 delta_tx->agg.scd_query_agg_frame_cnt,
1643 max_tx->agg.scd_query_agg_frame_cnt);
1644 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1645 "agg scd_query_no_agg:",
1646 le32_to_cpu(tx->agg.scd_query_no_agg),
1647 accum_tx->agg.scd_query_no_agg,
1648 delta_tx->agg.scd_query_no_agg,
1649 max_tx->agg.scd_query_no_agg);
1650 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1651 "agg scd_query_agg:",
1652 le32_to_cpu(tx->agg.scd_query_agg),
1653 accum_tx->agg.scd_query_agg,
1654 delta_tx->agg.scd_query_agg,
1655 max_tx->agg.scd_query_agg);
1656 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1657 "agg scd_query_mismatch:",
1658 le32_to_cpu(tx->agg.scd_query_mismatch),
1659 accum_tx->agg.scd_query_mismatch,
1660 delta_tx->agg.scd_query_mismatch,
1661 max_tx->agg.scd_query_mismatch);
1662 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1663 "agg frame_not_ready:",
1664 le32_to_cpu(tx->agg.frame_not_ready),
1665 accum_tx->agg.frame_not_ready,
1666 delta_tx->agg.frame_not_ready,
1667 max_tx->agg.frame_not_ready);
1668 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1669 "agg underrun:",
1670 le32_to_cpu(tx->agg.underrun),
1671 accum_tx->agg.underrun,
1672 delta_tx->agg.underrun, max_tx->agg.underrun);
1673 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1674 "agg bt_prio_kill:",
1675 le32_to_cpu(tx->agg.bt_prio_kill),
1676 accum_tx->agg.bt_prio_kill,
1677 delta_tx->agg.bt_prio_kill,
1678 max_tx->agg.bt_prio_kill);
1679 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1680 "agg rx_ba_rsp_cnt:",
1681 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1682 accum_tx->agg.rx_ba_rsp_cnt,
1683 delta_tx->agg.rx_ba_rsp_cnt,
1684 max_tx->agg.rx_ba_rsp_cnt);
1685
1686 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1687 kfree(buf);
1688 return ret;
1689} 1073}
1690 1074
1691static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, 1075static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1693,107 +1077,8 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1693 size_t count, loff_t *ppos) 1077 size_t count, loff_t *ppos)
1694{ 1078{
1695 struct iwl_priv *priv = file->private_data; 1079 struct iwl_priv *priv = file->private_data;
1696 int pos = 0; 1080 return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
1697 char *buf; 1081 user_buf, count, ppos);
1698 int bufsz = sizeof(struct statistics_general) * 10 + 300;
1699 ssize_t ret;
1700 struct statistics_general *general, *accum_general;
1701 struct statistics_general *delta_general, *max_general;
1702 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1703 struct statistics_div *div, *accum_div, *delta_div, *max_div;
1704
1705 if (!iwl_is_alive(priv))
1706 return -EAGAIN;
1707
1708 buf = kzalloc(bufsz, GFP_KERNEL);
1709 if (!buf) {
1710 IWL_ERR(priv, "Can not allocate Buffer\n");
1711 return -ENOMEM;
1712 }
1713
1714 /* the statistic information display here is based on
1715 * the last statistics notification from uCode
1716 * might not reflect the current uCode activity
1717 */
1718 general = &priv->statistics.general;
1719 dbg = &priv->statistics.general.dbg;
1720 div = &priv->statistics.general.div;
1721 accum_general = &priv->accum_statistics.general;
1722 delta_general = &priv->delta_statistics.general;
1723 max_general = &priv->max_delta.general;
1724 accum_dbg = &priv->accum_statistics.general.dbg;
1725 delta_dbg = &priv->delta_statistics.general.dbg;
1726 max_dbg = &priv->max_delta.general.dbg;
1727 accum_div = &priv->accum_statistics.general.div;
1728 delta_div = &priv->delta_statistics.general.div;
1729 max_div = &priv->max_delta.general.div;
1730 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1731 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1732 "Statistics_General:");
1733 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1734 "temperature:",
1735 le32_to_cpu(general->temperature));
1736 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1737 "temperature_m:",
1738 le32_to_cpu(general->temperature_m));
1739 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1740 "burst_check:",
1741 le32_to_cpu(dbg->burst_check),
1742 accum_dbg->burst_check,
1743 delta_dbg->burst_check, max_dbg->burst_check);
1744 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1745 "burst_count:",
1746 le32_to_cpu(dbg->burst_count),
1747 accum_dbg->burst_count,
1748 delta_dbg->burst_count, max_dbg->burst_count);
1749 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1750 "sleep_time:",
1751 le32_to_cpu(general->sleep_time),
1752 accum_general->sleep_time,
1753 delta_general->sleep_time, max_general->sleep_time);
1754 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1755 "slots_out:",
1756 le32_to_cpu(general->slots_out),
1757 accum_general->slots_out,
1758 delta_general->slots_out, max_general->slots_out);
1759 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1760 "slots_idle:",
1761 le32_to_cpu(general->slots_idle),
1762 accum_general->slots_idle,
1763 delta_general->slots_idle, max_general->slots_idle);
1764 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1765 le32_to_cpu(general->ttl_timestamp));
1766 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1767 "tx_on_a:",
1768 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1769 delta_div->tx_on_a, max_div->tx_on_a);
1770 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1771 "tx_on_b:",
1772 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1773 delta_div->tx_on_b, max_div->tx_on_b);
1774 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1775 "exec_time:",
1776 le32_to_cpu(div->exec_time), accum_div->exec_time,
1777 delta_div->exec_time, max_div->exec_time);
1778 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1779 "probe_time:",
1780 le32_to_cpu(div->probe_time), accum_div->probe_time,
1781 delta_div->probe_time, max_div->probe_time);
1782 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1783 "rx_enable_counter:",
1784 le32_to_cpu(general->rx_enable_counter),
1785 accum_general->rx_enable_counter,
1786 delta_general->rx_enable_counter,
1787 max_general->rx_enable_counter);
1788 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1789 "num_of_sos_states:",
1790 le32_to_cpu(general->num_of_sos_states),
1791 accum_general->num_of_sos_states,
1792 delta_general->num_of_sos_states,
1793 max_general->num_of_sos_states);
1794 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1795 kfree(buf);
1796 return ret;
1797} 1082}
1798 1083
1799static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 1084static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -1935,46 +1220,6 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1935 return ret; 1220 return ret;
1936} 1221}
1937 1222
1938static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1939 char __user *user_buf,
1940 size_t count, loff_t *ppos) {
1941
1942 struct iwl_priv *priv = file->private_data;
1943 char buf[128];
1944 int pos = 0;
1945 const size_t bufsz = sizeof(buf);
1946 struct statistics_tx *tx;
1947
1948 if (!iwl_is_alive(priv))
1949 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1950 else {
1951 tx = &priv->statistics.tx;
1952 if (tx->tx_power.ant_a ||
1953 tx->tx_power.ant_b ||
1954 tx->tx_power.ant_c) {
1955 pos += scnprintf(buf + pos, bufsz - pos,
1956 "tx power: (1/2 dB step)\n");
1957 if ((priv->cfg->valid_tx_ant & ANT_A) &&
1958 tx->tx_power.ant_a)
1959 pos += scnprintf(buf + pos, bufsz - pos,
1960 "\tantenna A: 0x%X\n",
1961 tx->tx_power.ant_a);
1962 if ((priv->cfg->valid_tx_ant & ANT_B) &&
1963 tx->tx_power.ant_b)
1964 pos += scnprintf(buf + pos, bufsz - pos,
1965 "\tantenna B: 0x%X\n",
1966 tx->tx_power.ant_b);
1967 if ((priv->cfg->valid_tx_ant & ANT_C) &&
1968 tx->tx_power.ant_c)
1969 pos += scnprintf(buf + pos, bufsz - pos,
1970 "\tantenna C: 0x%X\n",
1971 tx->tx_power.ant_c);
1972 } else
1973 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1974 }
1975 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1976}
1977
1978static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 1223static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1979 char __user *user_buf, 1224 char __user *user_buf,
1980 size_t count, loff_t *ppos) 1225 size_t count, loff_t *ppos)
@@ -2052,7 +1297,6 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2052 int pos = 0; 1297 int pos = 0;
2053 char buf[128]; 1298 char buf[128];
2054 const size_t bufsz = sizeof(buf); 1299 const size_t bufsz = sizeof(buf);
2055 ssize_t ret;
2056 1300
2057 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 1301 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2058 priv->event_log.ucode_trace ? "On" : "Off"); 1302 priv->event_log.ucode_trace ? "On" : "Off");
@@ -2063,8 +1307,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2063 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 1307 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2064 priv->event_log.wraps_more_count); 1308 priv->event_log.wraps_more_count);
2065 1309
2066 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1310 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2067 return ret;
2068} 1311}
2069 1312
2070static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 1313static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
@@ -2096,6 +1339,31 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2096 return count; 1339 return count;
2097} 1340}
2098 1341
1342static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
1343 char __user *user_buf,
1344 size_t count, loff_t *ppos) {
1345
1346 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1347 int len = 0;
1348 char buf[20];
1349
1350 len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
1351 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1352}
1353
1354static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
1355 char __user *user_buf,
1356 size_t count, loff_t *ppos) {
1357
1358 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1359 int len = 0;
1360 char buf[20];
1361
1362 len = sprintf(buf, "0x%04X\n",
1363 le32_to_cpu(priv->active_rxon.filter_flags));
1364 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1365}
1366
2099static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, 1367static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2100 char __user *user_buf, 1368 char __user *user_buf,
2101 size_t count, loff_t *ppos) 1369 size_t count, loff_t *ppos)
@@ -2125,13 +1393,11 @@ static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2125 int pos = 0; 1393 int pos = 0;
2126 char buf[12]; 1394 char buf[12];
2127 const size_t bufsz = sizeof(buf); 1395 const size_t bufsz = sizeof(buf);
2128 ssize_t ret;
2129 1396
2130 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 1397 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2131 priv->missed_beacon_threshold); 1398 priv->missed_beacon_threshold);
2132 1399
2133 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1400 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2134 return ret;
2135} 1401}
2136 1402
2137static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 1403static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
@@ -2160,27 +1426,6 @@ static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2160 return count; 1426 return count;
2161} 1427}
2162 1428
2163static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2164 const char __user *user_buf,
2165 size_t count, loff_t *ppos)
2166{
2167 struct iwl_priv *priv = file->private_data;
2168 char buf[8];
2169 int buf_size;
2170 int scan;
2171
2172 memset(buf, 0, sizeof(buf));
2173 buf_size = min(count, sizeof(buf) - 1);
2174 if (copy_from_user(buf, user_buf, buf_size))
2175 return -EFAULT;
2176 if (sscanf(buf, "%d", &scan) != 1)
2177 return -EINVAL;
2178
2179 iwl_internal_short_hw_scan(priv);
2180
2181 return count;
2182}
2183
2184static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 1429static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2185 char __user *user_buf, 1430 char __user *user_buf,
2186 size_t count, loff_t *ppos) { 1431 size_t count, loff_t *ppos) {
@@ -2189,13 +1434,11 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2189 int pos = 0; 1434 int pos = 0;
2190 char buf[12]; 1435 char buf[12];
2191 const size_t bufsz = sizeof(buf); 1436 const size_t bufsz = sizeof(buf);
2192 ssize_t ret;
2193 1437
2194 pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 1438 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2195 priv->cfg->plcp_delta_threshold); 1439 priv->cfg->plcp_delta_threshold);
2196 1440
2197 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1441 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2198 return ret;
2199} 1442}
2200 1443
2201static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 1444static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
@@ -2288,7 +1531,6 @@ DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2288DEBUGFS_READ_FILE_OPS(ucode_general_stats); 1531DEBUGFS_READ_FILE_OPS(ucode_general_stats);
2289DEBUGFS_READ_FILE_OPS(sensitivity); 1532DEBUGFS_READ_FILE_OPS(sensitivity);
2290DEBUGFS_READ_FILE_OPS(chain_noise); 1533DEBUGFS_READ_FILE_OPS(chain_noise);
2291DEBUGFS_READ_FILE_OPS(tx_power);
2292DEBUGFS_READ_FILE_OPS(power_save_status); 1534DEBUGFS_READ_FILE_OPS(power_save_status);
2293DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 1535DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
2294DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1536DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
@@ -2296,9 +1538,10 @@ DEBUGFS_WRITE_FILE_OPS(csr);
2296DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 1538DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2297DEBUGFS_READ_FILE_OPS(fh_reg); 1539DEBUGFS_READ_FILE_OPS(fh_reg);
2298DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 1540DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2299DEBUGFS_WRITE_FILE_OPS(internal_scan);
2300DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 1541DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2301DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 1542DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1543DEBUGFS_READ_FILE_OPS(rxon_flags);
1544DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
2302 1545
2303/* 1546/*
2304 * Create the debugfs files and directories 1547 * Create the debugfs files and directories
@@ -2334,8 +1577,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2334 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 1577 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
2335 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 1578 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
2336 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); 1579 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
2337 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); 1580 if (!priv->cfg->broken_powersave) {
2338 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); 1581 DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
1582 S_IWUSR | S_IRUSR);
1583 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1584 }
2339 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); 1585 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
2340 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); 1586 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
2341 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); 1587 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
@@ -2343,29 +1589,33 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2343 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); 1589 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
2344 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); 1590 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
2345 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); 1591 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
2346 DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
2347 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); 1592 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
2348 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); 1593 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
2349 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); 1594 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
2350 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); 1595 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
2351 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); 1596 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
2352 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 1597 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2353 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2354 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 1598 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2355 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 1599 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
2356 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 1600 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2357 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 1601 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2358 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 1602 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
2359 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 1603
1604 if (priv->cfg->sensitivity_calib_by_driver)
2360 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 1605 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1606 if (priv->cfg->chain_noise_calib_by_driver)
2361 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 1607 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1608 if (priv->cfg->ucode_tracing)
2362 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 1609 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2363 } 1610 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2364 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); 1611 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2365 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 1612 if (priv->cfg->sensitivity_calib_by_driver)
2366 &priv->disable_chain_noise_cal); 1613 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
2367 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 1614 &priv->disable_sens_cal);
2368 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 1615 if (priv->cfg->chain_noise_calib_by_driver)
1616 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1617 &priv->disable_chain_noise_cal);
1618 if (priv->cfg->tx_power_by_driver)
2369 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, 1619 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
2370 &priv->disable_tx_power_cal); 1620 &priv->disable_tx_power_cal);
2371 return 0; 1621 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ef1720a852e9..f3f3473c5c7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -43,6 +43,7 @@
43#include "iwl-debug.h" 43#include "iwl-debug.h"
44#include "iwl-4965-hw.h" 44#include "iwl-4965-hw.h"
45#include "iwl-3945-hw.h" 45#include "iwl-3945-hw.h"
46#include "iwl-agn-hw.h"
46#include "iwl-led.h" 47#include "iwl-led.h"
47#include "iwl-power.h" 48#include "iwl-power.h"
48#include "iwl-agn-rs.h" 49#include "iwl-agn-rs.h"
@@ -56,6 +57,7 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
56extern struct iwl_cfg iwl5100_abg_cfg; 57extern struct iwl_cfg iwl5100_abg_cfg;
57extern struct iwl_cfg iwl5150_agn_cfg; 58extern struct iwl_cfg iwl5150_agn_cfg;
58extern struct iwl_cfg iwl5150_abg_cfg; 59extern struct iwl_cfg iwl5150_abg_cfg;
60extern struct iwl_cfg iwl6000g2a_2agn_cfg;
59extern struct iwl_cfg iwl6000i_2agn_cfg; 61extern struct iwl_cfg iwl6000i_2agn_cfg;
60extern struct iwl_cfg iwl6000i_2abg_cfg; 62extern struct iwl_cfg iwl6000i_2abg_cfg;
61extern struct iwl_cfg iwl6000i_2bg_cfg; 63extern struct iwl_cfg iwl6000i_2bg_cfg;
@@ -67,45 +69,6 @@ extern struct iwl_cfg iwl1000_bg_cfg;
67 69
68struct iwl_tx_queue; 70struct iwl_tx_queue;
69 71
70/* shared structures from iwl-5000.c */
71extern struct iwl_mod_params iwl50_mod_params;
72extern struct iwl_ucode_ops iwl5000_ucode;
73extern struct iwl_lib_ops iwl5000_lib;
74extern struct iwl_hcmd_ops iwl5000_hcmd;
75extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
76
77/* shared functions from iwl-5000.c */
78extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
79extern u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd,
80 u8 *data);
81extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
82 __le32 *tx_flags);
83extern int iwl5000_calc_rssi(struct iwl_priv *priv,
84 struct iwl_rx_phy_res *rx_resp);
85extern void iwl5000_nic_config(struct iwl_priv *priv);
86extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
87extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
88 size_t offset);
89extern void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
90 struct iwl_tx_queue *txq,
91 u16 byte_cnt);
92extern void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
93 struct iwl_tx_queue *txq);
94extern int iwl5000_load_ucode(struct iwl_priv *priv);
95extern void iwl5000_init_alive_start(struct iwl_priv *priv);
96extern int iwl5000_alive_notify(struct iwl_priv *priv);
97extern int iwl5000_hw_set_hw_params(struct iwl_priv *priv);
98extern int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
99 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
100extern int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
101 u16 ssn_idx, u8 tx_fifo);
102extern void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask);
103extern void iwl5000_setup_deferred_work(struct iwl_priv *priv);
104extern void iwl5000_rx_handler_setup(struct iwl_priv *priv);
105extern int iwl5000_hw_valid_rtc_data_addr(u32 addr);
106extern int iwl5000_send_tx_power(struct iwl_priv *priv);
107extern void iwl5000_temperature(struct iwl_priv *priv);
108
109/* CT-KILL constants */ 72/* CT-KILL constants */
110#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 73#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
111#define CT_KILL_THRESHOLD 114 /* in Celsius */ 74#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -183,6 +146,10 @@ struct iwl_queue {
183 int n_bd; /* number of BDs in this queue */ 146 int n_bd; /* number of BDs in this queue */
184 int write_ptr; /* 1-st empty entry (index) host_w*/ 147 int write_ptr; /* 1-st empty entry (index) host_w*/
185 int read_ptr; /* last used entry (index) host_r*/ 148 int read_ptr; /* last used entry (index) host_r*/
149 /* use for monitoring and recovering the stuck queue */
150 int last_read_ptr; /* storing the last read_ptr */
151 /* number of time read_ptr and last_read_ptr are the same */
152 u8 repeat_same_read_ptr;
186 dma_addr_t dma_addr; /* physical addr for BD's */ 153 dma_addr_t dma_addr; /* physical addr for BD's */
187 int n_window; /* safe queue window */ 154 int n_window; /* safe queue window */
188 u32 id; 155 u32 id;
@@ -304,13 +271,11 @@ struct iwl_channel_info {
304 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; 271 struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
305}; 272};
306 273
307#define IWL_TX_FIFO_AC0 0 274#define IWL_TX_FIFO_BK 0
308#define IWL_TX_FIFO_AC1 1 275#define IWL_TX_FIFO_BE 1
309#define IWL_TX_FIFO_AC2 2 276#define IWL_TX_FIFO_VI 2
310#define IWL_TX_FIFO_AC3 3 277#define IWL_TX_FIFO_VO 3
311#define IWL_TX_FIFO_HCCA_1 5 278#define IWL_TX_FIFO_UNUSED -1
312#define IWL_TX_FIFO_HCCA_2 6
313#define IWL_TX_FIFO_NONE 7
314 279
315/* Minimum number of queues. MAX_NUM is defined in hw specific files. 280/* Minimum number of queues. MAX_NUM is defined in hw specific files.
316 * Set the minimum to accommodate the 4 standard TX queues, 1 command 281 * Set the minimum to accommodate the 4 standard TX queues, 1 command
@@ -361,13 +326,6 @@ enum {
361 326
362#define DEF_CMD_PAYLOAD_SIZE 320 327#define DEF_CMD_PAYLOAD_SIZE 320
363 328
364/*
365 * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
366 * SNAP header and alignment. It should also be big enough for 802.11
367 * control frames.
368 */
369#define IWL_LINK_HDR_MAX 64
370
371/** 329/**
372 * struct iwl_device_cmd 330 * struct iwl_device_cmd
373 * 331 *
@@ -519,38 +477,28 @@ struct iwl_ht_config {
519 u8 non_GF_STA_present; 477 u8 non_GF_STA_present;
520}; 478};
521 479
522union iwl_qos_capabity {
523 struct {
524 u8 edca_count:4; /* bit 0-3 */
525 u8 q_ack:1; /* bit 4 */
526 u8 queue_request:1; /* bit 5 */
527 u8 txop_request:1; /* bit 6 */
528 u8 reserved:1; /* bit 7 */
529 } q_AP;
530 struct {
531 u8 acvo_APSD:1; /* bit 0 */
532 u8 acvi_APSD:1; /* bit 1 */
533 u8 ac_bk_APSD:1; /* bit 2 */
534 u8 ac_be_APSD:1; /* bit 3 */
535 u8 q_ack:1; /* bit 4 */
536 u8 max_len:2; /* bit 5-6 */
537 u8 more_data_ack:1; /* bit 7 */
538 } q_STA;
539 u8 val;
540};
541
542/* QoS structures */ 480/* QoS structures */
543struct iwl_qos_info { 481struct iwl_qos_info {
544 int qos_active; 482 int qos_active;
545 union iwl_qos_capabity qos_cap;
546 struct iwl_qosparam_cmd def_qos_parm; 483 struct iwl_qosparam_cmd def_qos_parm;
547}; 484};
548 485
486/*
487 * Structure should be accessed with sta_lock held. When station addition
488 * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only
489 * the commands (iwl_addsta_cmd and iwl_link_quality_cmd) without sta_lock
490 * held.
491 */
549struct iwl_station_entry { 492struct iwl_station_entry {
550 struct iwl_addsta_cmd sta; 493 struct iwl_addsta_cmd sta;
551 struct iwl_tid_data tid[MAX_TID_COUNT]; 494 struct iwl_tid_data tid[MAX_TID_COUNT];
552 u8 used; 495 u8 used;
553 struct iwl_hw_key keyinfo; 496 struct iwl_hw_key keyinfo;
497 struct iwl_link_quality_cmd *lq;
498};
499
500struct iwl_station_priv_common {
501 u8 sta_id;
554}; 502};
555 503
556/* 504/*
@@ -559,14 +507,28 @@ struct iwl_station_entry {
559 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 507 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
560 * in the structure for use by driver. This structure is places in that 508 * in the structure for use by driver. This structure is places in that
561 * space. 509 * space.
510 *
511 * The common struct MUST be first because it is shared between
512 * 3945 and agn!
562 */ 513 */
563struct iwl_station_priv { 514struct iwl_station_priv {
515 struct iwl_station_priv_common common;
564 struct iwl_lq_sta lq_sta; 516 struct iwl_lq_sta lq_sta;
565 atomic_t pending_frames; 517 atomic_t pending_frames;
566 bool client; 518 bool client;
567 bool asleep; 519 bool asleep;
568}; 520};
569 521
522/**
523 * struct iwl_vif_priv - driver's private per-interface information
524 *
525 * When mac80211 allocates a virtual interface, it can allocate
526 * space for us to put data into.
527 */
528struct iwl_vif_priv {
529 u8 ibss_bssid_sta_id;
530};
531
570/* one for each uCode image (inst/data, boot/init/runtime) */ 532/* one for each uCode image (inst/data, boot/init/runtime) */
571struct fw_desc { 533struct fw_desc {
572 void *v_addr; /* access by driver */ 534 void *v_addr; /* access by driver */
@@ -574,7 +536,7 @@ struct fw_desc {
574 u32 len; /* bytes */ 536 u32 len; /* bytes */
575}; 537};
576 538
577/* uCode file layout */ 539/* v1/v2 uCode file layout */
578struct iwl_ucode_header { 540struct iwl_ucode_header {
579 __le32 ver; /* major/minor/API/serial */ 541 __le32 ver; /* major/minor/API/serial */
580 union { 542 union {
@@ -597,7 +559,62 @@ struct iwl_ucode_header {
597 } v2; 559 } v2;
598 } u; 560 } u;
599}; 561};
600#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28) 562
563/*
564 * new TLV uCode file layout
565 *
566 * The new TLV file format contains TLVs, that each specify
567 * some piece of data. To facilitate "groups", for example
568 * different instruction image with different capabilities,
569 * bundled with the same init image, an alternative mechanism
570 * is provided:
571 * When the alternative field is 0, that means that the item
572 * is always valid. When it is non-zero, then it is only
573 * valid in conjunction with items of the same alternative,
574 * in which case the driver (user) selects one alternative
575 * to use.
576 */
577
578enum iwl_ucode_tlv_type {
579 IWL_UCODE_TLV_INVALID = 0, /* unused */
580 IWL_UCODE_TLV_INST = 1,
581 IWL_UCODE_TLV_DATA = 2,
582 IWL_UCODE_TLV_INIT = 3,
583 IWL_UCODE_TLV_INIT_DATA = 4,
584 IWL_UCODE_TLV_BOOT = 5,
585 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
586};
587
588struct iwl_ucode_tlv {
589 __le16 type; /* see above */
590 __le16 alternative; /* see comment */
591 __le32 length; /* not including type/length fields */
592 u8 data[0];
593} __attribute__ ((packed));
594
595#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
596
597struct iwl_tlv_ucode_header {
598 /*
599 * The TLV style ucode header is distinguished from
600 * the v1/v2 style header by first four bytes being
601 * zero, as such is an invalid combination of
602 * major/minor/API/serial versions.
603 */
604 __le32 zero;
605 __le32 magic;
606 u8 human_readable[64];
607 __le32 ver; /* major/minor/API/serial */
608 __le32 build;
609 __le64 alternatives; /* bitmask of valid alternatives */
610 /*
611 * The data contained herein has a TLV layout,
612 * see above for the TLV header and types.
613 * Note that each TLV is padded to a length
614 * that is a multiple of 4 for alignment.
615 */
616 u8 data[0];
617};
601 618
602struct iwl4965_ibss_seq { 619struct iwl4965_ibss_seq {
603 u8 mac[ETH_ALEN]; 620 u8 mac[ETH_ALEN];
@@ -1039,6 +1056,11 @@ struct iwl_event_log {
1039#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) 1056#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
1040#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) 1057#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
1041 1058
1059/* timer constants use to monitor and recover stuck tx queues in mSecs */
1060#define IWL_MONITORING_PERIOD (1000)
1061#define IWL_ONE_HUNDRED_MSECS (100)
1062#define IWL_SIXTY_SECS (60000)
1063
1042enum iwl_reset { 1064enum iwl_reset {
1043 IWL_RF_RESET = 0, 1065 IWL_RF_RESET = 0,
1044 IWL_FW_RESET, 1066 IWL_FW_RESET,
@@ -1092,10 +1114,6 @@ struct iwl_priv {
1092 struct iwl_channel_info *channel_info; /* channel info array */ 1114 struct iwl_channel_info *channel_info; /* channel info array */
1093 u8 channel_count; /* # of channels */ 1115 u8 channel_count; /* # of channels */
1094 1116
1095 /* each calibration channel group in the EEPROM has a derived
1096 * clip setting for each rate. 3945 only.*/
1097 const struct iwl3945_clip_group clip39_groups[5];
1098
1099 /* thermal calibration */ 1117 /* thermal calibration */
1100 s32 temperature; /* degrees Kelvin */ 1118 s32 temperature; /* degrees Kelvin */
1101 s32 last_temperature; 1119 s32 last_temperature;
@@ -1104,12 +1122,10 @@ struct iwl_priv {
1104 struct iwl_calib_result calib_results[IWL_CALIB_MAX]; 1122 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
1105 1123
1106 /* Scan related variables */ 1124 /* Scan related variables */
1107 unsigned long next_scan_jiffies;
1108 unsigned long scan_start; 1125 unsigned long scan_start;
1109 unsigned long scan_pass_start;
1110 unsigned long scan_start_tsf; 1126 unsigned long scan_start_tsf;
1111 void *scan; 1127 void *scan_cmd;
1112 int scan_bands; 1128 enum ieee80211_band scan_band;
1113 struct cfg80211_scan_request *scan_request; 1129 struct cfg80211_scan_request *scan_request;
1114 bool is_internal_short_scan; 1130 bool is_internal_short_scan;
1115 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1131 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
@@ -1168,16 +1184,13 @@ struct iwl_priv {
1168 u64 led_tpt; 1184 u64 led_tpt;
1169 1185
1170 u16 active_rate; 1186 u16 active_rate;
1171 u16 active_rate_basic;
1172 1187
1173 u8 assoc_station_added;
1174 u8 start_calib; 1188 u8 start_calib;
1175 struct iwl_sensitivity_data sensitivity_data; 1189 struct iwl_sensitivity_data sensitivity_data;
1176 struct iwl_chain_noise_data chain_noise_data; 1190 struct iwl_chain_noise_data chain_noise_data;
1177 __le16 sensitivity_tbl[HD_TABLE_SIZE]; 1191 __le16 sensitivity_tbl[HD_TABLE_SIZE];
1178 1192
1179 struct iwl_ht_config current_ht_config; 1193 struct iwl_ht_config current_ht_config;
1180 u8 last_phy_res[100];
1181 1194
1182 /* Rate scaling data */ 1195 /* Rate scaling data */
1183 u8 retry_rate; 1196 u8 retry_rate;
@@ -1197,9 +1210,6 @@ struct iwl_priv {
1197 1210
1198 unsigned long status; 1211 unsigned long status;
1199 1212
1200 int last_rx_rssi; /* From Rx packet statistics */
1201 int last_rx_noise; /* From beacon statistics */
1202
1203 /* counts mgmt, ctl, and data packets */ 1213 /* counts mgmt, ctl, and data packets */
1204 struct traffic_stats tx_stats; 1214 struct traffic_stats tx_stats;
1205 struct traffic_stats rx_stats; 1215 struct traffic_stats rx_stats;
@@ -1218,18 +1228,14 @@ struct iwl_priv {
1218#endif 1228#endif
1219 1229
1220 /* context information */ 1230 /* context information */
1221 u16 rates_mask; 1231 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
1222
1223 u8 bssid[ETH_ALEN];
1224 u16 rts_threshold;
1225 u8 mac_addr[ETH_ALEN]; 1232 u8 mac_addr[ETH_ALEN];
1226 1233
1227 /*station table variables */ 1234 /*station table variables */
1228 spinlock_t sta_lock; 1235 spinlock_t sta_lock;
1229 int num_stations; 1236 int num_stations;
1230 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1237 struct iwl_station_entry stations[IWL_STATION_COUNT];
1231 struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; 1238 struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
1232 u8 default_wep_key;
1233 u8 key_mapping_key; 1239 u8 key_mapping_key;
1234 unsigned long ucode_key_table; 1240 unsigned long ucode_key_table;
1235 1241
@@ -1244,10 +1250,6 @@ struct iwl_priv {
1244 1250
1245 u8 mac80211_registered; 1251 u8 mac80211_registered;
1246 1252
1247 /* Rx'd packet timing information */
1248 u32 last_beacon_time;
1249 u64 last_tsf;
1250
1251 /* eeprom -- this is in the card's little endian byte order */ 1253 /* eeprom -- this is in the card's little endian byte order */
1252 u8 *eeprom; 1254 u8 *eeprom;
1253 int nvm_device_type; 1255 int nvm_device_type;
@@ -1259,29 +1261,67 @@ struct iwl_priv {
1259 1261
1260 /* Last Rx'd beacon timestamp */ 1262 /* Last Rx'd beacon timestamp */
1261 u64 timestamp; 1263 u64 timestamp;
1262 u16 beacon_int;
1263 struct ieee80211_vif *vif; 1264 struct ieee80211_vif *vif;
1264 1265
1265 /*Added for 3945 */ 1266 union {
1266 void *shared_virt; 1267#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
1267 dma_addr_t shared_phys; 1268 struct {
1268 /*End*/ 1269 void *shared_virt;
1269 struct iwl_hw_params hw_params; 1270 dma_addr_t shared_phys;
1270 1271
1271 /* INT ICT Table */ 1272 struct delayed_work thermal_periodic;
1272 __le32 *ict_tbl; 1273 struct delayed_work rfkill_poll;
1273 dma_addr_t ict_tbl_dma; 1274
1274 dma_addr_t aligned_ict_tbl_dma; 1275 struct iwl3945_notif_statistics statistics;
1275 int ict_index; 1276#ifdef CONFIG_IWLWIFI_DEBUG
1276 void *ict_tbl_vir; 1277 struct iwl3945_notif_statistics accum_statistics;
1277 u32 inta; 1278 struct iwl3945_notif_statistics delta_statistics;
1278 bool use_ict; 1279 struct iwl3945_notif_statistics max_delta;
1280#endif
1281
1282 u32 sta_supp_rates;
1283 int last_rx_rssi; /* From Rx packet statistics */
1284
1285 /* Rx'd packet timing information */
1286 u32 last_beacon_time;
1287 u64 last_tsf;
1288
1289 /*
1290 * each calibration channel group in the
1291 * EEPROM has a derived clip setting for
1292 * each rate.
1293 */
1294 const struct iwl3945_clip_group clip_groups[5];
1295
1296 } _3945;
1297#endif
1298#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
1299 struct {
1300 /* INT ICT Table */
1301 __le32 *ict_tbl;
1302 void *ict_tbl_vir;
1303 dma_addr_t ict_tbl_dma;
1304 dma_addr_t aligned_ict_tbl_dma;
1305 int ict_index;
1306 u32 inta;
1307 bool use_ict;
1308 /*
1309 * reporting the number of tids has AGG on. 0 means
1310 * no AGGREGATION
1311 */
1312 u8 agg_tids_count;
1313
1314 struct iwl_rx_phy_res last_phy_res;
1315 bool last_phy_res_valid;
1316
1317 struct completion firmware_loading_complete;
1318 } _agn;
1319#endif
1320 };
1321
1322 struct iwl_hw_params hw_params;
1279 1323
1280 u32 inta_mask; 1324 u32 inta_mask;
1281 /* Current association information needed to configure the
1282 * hardware */
1283 u16 assoc_id;
1284 u16 assoc_capability;
1285 1325
1286 struct iwl_qos_info qos_data; 1326 struct iwl_qos_info qos_data;
1287 1327
@@ -1291,7 +1331,6 @@ struct iwl_priv {
1291 struct work_struct scan_completed; 1331 struct work_struct scan_completed;
1292 struct work_struct rx_replenish; 1332 struct work_struct rx_replenish;
1293 struct work_struct abort_scan; 1333 struct work_struct abort_scan;
1294 struct work_struct request_scan;
1295 struct work_struct beacon_update; 1334 struct work_struct beacon_update;
1296 struct work_struct tt_work; 1335 struct work_struct tt_work;
1297 struct work_struct ct_enter; 1336 struct work_struct ct_enter;
@@ -1304,10 +1343,6 @@ struct iwl_priv {
1304 struct delayed_work alive_start; 1343 struct delayed_work alive_start;
1305 struct delayed_work scan_check; 1344 struct delayed_work scan_check;
1306 1345
1307 /*For 3945 only*/
1308 struct delayed_work thermal_periodic;
1309 struct delayed_work rfkill_poll;
1310
1311 /* TX Power */ 1346 /* TX Power */
1312 s8 tx_power_user_lmt; 1347 s8 tx_power_user_lmt;
1313 s8 tx_power_device_lmt; 1348 s8 tx_power_device_lmt;
@@ -1339,13 +1374,8 @@ struct iwl_priv {
1339 struct work_struct run_time_calib_work; 1374 struct work_struct run_time_calib_work;
1340 struct timer_list statistics_periodic; 1375 struct timer_list statistics_periodic;
1341 struct timer_list ucode_trace; 1376 struct timer_list ucode_trace;
1377 struct timer_list monitor_recover;
1342 bool hw_ready; 1378 bool hw_ready;
1343 /*For 3945*/
1344#define IWL_DEFAULT_TX_POWER 0x0F
1345
1346 struct iwl3945_notif_statistics statistics_39;
1347
1348 u32 sta_supp_rates;
1349 1379
1350 struct iwl_event_log event_log; 1380 struct iwl_event_log event_log;
1351}; /*iwl_priv */ 1381}; /*iwl_priv */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 2ffc2edbf4f0..4a487639d932 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -37,6 +37,7 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); 38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 42EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
42EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); 43EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index fb5bb487f3bc..ee11452519e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -590,9 +590,16 @@ int iwl_eeprom_init(struct iwl_priv *priv)
590 e[addr / 2] = cpu_to_le16(r >> 16); 590 e[addr / 2] = cpu_to_le16(r >> 16);
591 } 591 }
592 } 592 }
593
594 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
595 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
596 ? "OTP" : "EEPROM",
597 iwl_eeprom_query16(priv, EEPROM_VERSION));
598
593 ret = 0; 599 ret = 0;
594done: 600done:
595 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); 601 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
602
596err: 603err:
597 if (ret) 604 if (ret)
598 iwl_eeprom_free(priv); 605 iwl_eeprom_free(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 8171c701e4e1..95aa202c85e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -172,35 +172,35 @@ struct iwl_eeprom_enhanced_txpwr {
172#define EEPROM_5000_TX_POWER_VERSION (4) 172#define EEPROM_5000_TX_POWER_VERSION (4)
173#define EEPROM_5000_EEPROM_VERSION (0x11A) 173#define EEPROM_5000_EEPROM_VERSION (0x11A)
174 174
175/*5000 calibrations */ 175/* 5000 and up calibration */
176#define EEPROM_5000_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) 176#define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
177#define EEPROM_5000_XTAL ((2*0x128) | EEPROM_5000_CALIB_ALL) 177#define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL)
178#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_5000_CALIB_ALL) 178
179 179/* 5000 temperature */
180/* 5000 links */ 180#define EEPROM_5000_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL)
181#define EEPROM_5000_LINK_HOST (2*0x64) 181
182#define EEPROM_5000_LINK_GENERAL (2*0x65) 182/* agn links */
183#define EEPROM_5000_LINK_REGULATORY (2*0x66) 183#define EEPROM_LINK_HOST (2*0x64)
184#define EEPROM_5000_LINK_CALIBRATION (2*0x67) 184#define EEPROM_LINK_GENERAL (2*0x65)
185#define EEPROM_5000_LINK_PROCESS_ADJST (2*0x68) 185#define EEPROM_LINK_REGULATORY (2*0x66)
186#define EEPROM_5000_LINK_OTHERS (2*0x69) 186#define EEPROM_LINK_CALIBRATION (2*0x67)
187 187#define EEPROM_LINK_PROCESS_ADJST (2*0x68)
188/* 5000 regulatory - indirect access */ 188#define EEPROM_LINK_OTHERS (2*0x69)
189#define EEPROM_5000_REG_SKU_ID ((0x02)\ 189
190 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 4 bytes */ 190/* agn regulatory - indirect access */
191#define EEPROM_5000_REG_BAND_1_CHANNELS ((0x08)\ 191#define EEPROM_REG_BAND_1_CHANNELS ((0x08)\
192 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */ 192 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */
193#define EEPROM_5000_REG_BAND_2_CHANNELS ((0x26)\ 193#define EEPROM_REG_BAND_2_CHANNELS ((0x26)\
194 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */ 194 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */
195#define EEPROM_5000_REG_BAND_3_CHANNELS ((0x42)\ 195#define EEPROM_REG_BAND_3_CHANNELS ((0x42)\
196 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ 196 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
197#define EEPROM_5000_REG_BAND_4_CHANNELS ((0x5C)\ 197#define EEPROM_REG_BAND_4_CHANNELS ((0x5C)\
198 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ 198 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
199#define EEPROM_5000_REG_BAND_5_CHANNELS ((0x74)\ 199#define EEPROM_REG_BAND_5_CHANNELS ((0x74)\
200 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */ 200 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */
201#define EEPROM_5000_REG_BAND_24_HT40_CHANNELS ((0x82)\ 201#define EEPROM_REG_BAND_24_HT40_CHANNELS ((0x82)\
202 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ 202 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
203#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS ((0x92)\ 203#define EEPROM_REG_BAND_52_HT40_CHANNELS ((0x92)\
204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ 204 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
205 205
206/* 6000 regulatory - indirect access */ 206/* 6000 regulatory - indirect access */
@@ -265,14 +265,21 @@ struct iwl_eeprom_enhanced_txpwr {
265#define EEPROM_5050_EEPROM_VERSION (0x21E) 265#define EEPROM_5050_EEPROM_VERSION (0x21E)
266 266
267/* 1000 Specific */ 267/* 1000 Specific */
268#define EEPROM_1000_TX_POWER_VERSION (4)
268#define EEPROM_1000_EEPROM_VERSION (0x15C) 269#define EEPROM_1000_EEPROM_VERSION (0x15C)
269 270
270/* 6x00 Specific */ 271/* 6x00 Specific */
272#define EEPROM_6000_TX_POWER_VERSION (4)
271#define EEPROM_6000_EEPROM_VERSION (0x434) 273#define EEPROM_6000_EEPROM_VERSION (0x434)
272 274
273/* 6x50 Specific */ 275/* 6x50 Specific */
276#define EEPROM_6050_TX_POWER_VERSION (4)
274#define EEPROM_6050_EEPROM_VERSION (0x532) 277#define EEPROM_6050_EEPROM_VERSION (0x532)
275 278
279/* 6x00g2 Specific */
280#define EEPROM_6000G2_TX_POWER_VERSION (6)
281#define EEPROM_6000G2_EEPROM_VERSION (0x709)
282
276/* OTP */ 283/* OTP */
277/* lower blocks contain EEPROM image and calibration data */ 284/* lower blocks contain EEPROM image and calibration data */
278#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */ 285#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 73681c4fefe7..51f89e7ba681 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -169,7 +169,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
169 mutex_lock(&priv->sync_cmd_mutex); 169 mutex_lock(&priv->sync_cmd_mutex);
170 170
171 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 171 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
172 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n", 172 IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
173 get_cmd_string(cmd->id)); 173 get_cmd_string(cmd->id));
174 174
175 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 175 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
@@ -191,7 +191,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
191 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 191 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
192 192
193 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 193 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
194 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", 194 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
195 get_cmd_string(cmd->id)); 195 get_cmd_string(cmd->id));
196 ret = -ETIMEDOUT; 196 ret = -ETIMEDOUT;
197 goto cancel; 197 goto cancel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 51a67fb2e185..3ff6b9d25a10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -31,6 +31,9 @@
31#define __iwl_helpers_h__ 31#define __iwl_helpers_h__
32 32
33#include <linux/ctype.h> 33#include <linux/ctype.h>
34#include <net/mac80211.h>
35
36#include "iwl-io.h"
34 37
35#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) 38#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
36 39
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 16eb3ced9b30..0203a3bbf872 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -298,7 +298,7 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
298 struct iwl_priv *priv, u32 reg) 298 struct iwl_priv *priv, u32 reg)
299{ 299{
300 u32 value = _iwl_read_direct32(priv, reg); 300 u32 value = _iwl_read_direct32(priv, reg);
301 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, 301 IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
302 f, l); 302 f, l);
303 return value; 303 return value;
304} 304}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index a6f9c918aabc..db5bfcb036ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -46,7 +46,7 @@
46static int led_mode; 46static int led_mode;
47module_param(led_mode, int, S_IRUGO); 47module_param(led_mode, int, S_IRUGO);
48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " 48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
49 "(default 0)\n"); 49 "(default 0)");
50 50
51 51
52static const struct { 52static const struct {
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 548dac2f6a96..cda6a94d6cc9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -318,10 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
318 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || 318 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
319 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 319 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
320 320
321 if (priv->vif) 321 dtimper = priv->hw->conf.ps_dtim_period ?: 1;
322 dtimper = priv->hw->conf.ps_dtim_period;
323 else
324 dtimper = 1;
325 322
326 if (priv->cfg->broken_powersave) 323 if (priv->cfg->broken_powersave)
327 iwl_power_sleep_cam_cmd(priv, &cmd); 324 iwl_power_sleep_cam_cmd(priv, &cmd);
@@ -384,10 +381,10 @@ EXPORT_SYMBOL(iwl_ht_enabled);
384 381
385bool iwl_within_ct_kill_margin(struct iwl_priv *priv) 382bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
386{ 383{
387 s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */ 384 s32 temp = priv->temperature; /* degrees CELSIUS except specified */
388 bool within_margin = false; 385 bool within_margin = false;
389 386
390 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 387 if (priv->cfg->temperature_kelvin)
391 temp = KELVIN_TO_CELSIUS(priv->temperature); 388 temp = KELVIN_TO_CELSIUS(priv->temperature);
392 389
393 if (!priv->thermal_throttle.advanced_tt) 390 if (!priv->thermal_throttle.advanced_tt)
@@ -840,12 +837,12 @@ EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
840static void iwl_bg_tt_work(struct work_struct *work) 837static void iwl_bg_tt_work(struct work_struct *work)
841{ 838{
842 struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); 839 struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
843 s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */ 840 s32 temp = priv->temperature; /* degrees CELSIUS except specified */
844 841
845 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 842 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
846 return; 843 return;
847 844
848 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 845 if (priv->cfg->temperature_kelvin)
849 temp = KELVIN_TO_CELSIUS(priv->temperature); 846 temp = KELVIN_TO_CELSIUS(priv->temperature);
850 847
851 if (!priv->thermal_throttle.advanced_tt) 848 if (!priv->thermal_throttle.advanced_tt)
@@ -875,7 +872,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
875 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); 872 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
876 struct iwl_tt_trans *transaction; 873 struct iwl_tt_trans *transaction;
877 874
878 IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling \n"); 875 IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n");
879 876
880 memset(tt, 0, sizeof(struct iwl_tt_mgmt)); 877 memset(tt, 0, sizeof(struct iwl_tt_mgmt));
881 878
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index d2d2a9174900..b1f101caf19d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -254,7 +254,7 @@
254 * device. A queue maps to only one (selectable by driver) Tx DMA channel, 254 * device. A queue maps to only one (selectable by driver) Tx DMA channel,
255 * but one DMA channel may take input from several queues. 255 * but one DMA channel may take input from several queues.
256 * 256 *
257 * Tx DMA channels have dedicated purposes. For 4965, they are used as follows 257 * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows
258 * (cf. default_queue_to_tx_fifo in iwl-4965.c): 258 * (cf. default_queue_to_tx_fifo in iwl-4965.c):
259 * 259 *
260 * 0 -- EDCA BK (background) frames, lowest priority 260 * 0 -- EDCA BK (background) frames, lowest priority
@@ -262,20 +262,20 @@
262 * 2 -- EDCA VI (video) frames, higher priority 262 * 2 -- EDCA VI (video) frames, higher priority
263 * 3 -- EDCA VO (voice) and management frames, highest priority 263 * 3 -- EDCA VO (voice) and management frames, highest priority
264 * 4 -- Commands (e.g. RXON, etc.) 264 * 4 -- Commands (e.g. RXON, etc.)
265 * 5 -- HCCA short frames 265 * 5 -- unused (HCCA)
266 * 6 -- HCCA long frames 266 * 6 -- unused (HCCA)
267 * 7 -- not used by driver (device-internal only) 267 * 7 -- not used by driver (device-internal only)
268 * 268 *
269 * For 5000 series and up, they are used slightly differently 269 * For 5000 series and up, they are used differently
270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): 270 * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
271 * 271 *
272 * 0 -- EDCA BK (background) frames, lowest priority 272 * 0 -- EDCA BK (background) frames, lowest priority
273 * 1 -- EDCA BE (best effort) frames, normal priority 273 * 1 -- EDCA BE (best effort) frames, normal priority
274 * 2 -- EDCA VI (video) frames, higher priority 274 * 2 -- EDCA VI (video) frames, higher priority
275 * 3 -- EDCA VO (voice) and management frames, highest priority 275 * 3 -- EDCA VO (voice) and management frames, highest priority
276 * 4 -- (TBD) 276 * 4 -- unused
277 * 5 -- HCCA short frames 277 * 5 -- unused
278 * 6 -- HCCA long frames 278 * 6 -- unused
279 * 7 -- Commands 279 * 7 -- Commands
280 * 280 *
281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. 281 * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
@@ -529,48 +529,48 @@
529#define IWL_SCD_TXFIFO_POS_RA (4) 529#define IWL_SCD_TXFIFO_POS_RA (4)
530#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) 530#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
531 531
532/* 5000 SCD */ 532/* agn SCD */
533#define IWL50_SCD_QUEUE_STTS_REG_POS_TXF (0) 533#define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF (0)
534#define IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE (3) 534#define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE (3)
535#define IWL50_SCD_QUEUE_STTS_REG_POS_WSL (4) 535#define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL (4)
536#define IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) 536#define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
537#define IWL50_SCD_QUEUE_STTS_REG_MSK (0x00FF0000) 537#define IWLAGN_SCD_QUEUE_STTS_REG_MSK (0x00FF0000)
538 538
539#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_POS (8) 539#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS (8)
540#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) 540#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00)
541#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) 541#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24)
542#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) 542#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000)
543#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0) 543#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0)
544#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) 544#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
545#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) 545#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
546#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) 546#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
547 547
548#define IWL50_SCD_CONTEXT_DATA_OFFSET (0x600) 548#define IWLAGN_SCD_CONTEXT_DATA_OFFSET (0x600)
549#define IWL50_SCD_TX_STTS_BITMAP_OFFSET (0x7B1) 549#define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET (0x7B1)
550#define IWL50_SCD_TRANSLATE_TBL_OFFSET (0x7E0) 550#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET (0x7E0)
551 551
552#define IWL50_SCD_CONTEXT_QUEUE_OFFSET(x)\ 552#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\
553 (IWL50_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) 553 (IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
554 554
555#define IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ 555#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
556 ((IWL50_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) 556 ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
557 557
558#define IWL50_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\ 558#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
559 (~(1<<IWL_CMD_QUEUE_NUM))) 559 (~(1<<IWL_CMD_QUEUE_NUM)))
560 560
561#define IWL50_SCD_BASE (PRPH_BASE + 0xa02c00) 561#define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00)
562 562
563#define IWL50_SCD_SRAM_BASE_ADDR (IWL50_SCD_BASE + 0x0) 563#define IWLAGN_SCD_SRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x0)
564#define IWL50_SCD_DRAM_BASE_ADDR (IWL50_SCD_BASE + 0x8) 564#define IWLAGN_SCD_DRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x8)
565#define IWL50_SCD_AIT (IWL50_SCD_BASE + 0x0c) 565#define IWLAGN_SCD_AIT (IWLAGN_SCD_BASE + 0x0c)
566#define IWL50_SCD_TXFACT (IWL50_SCD_BASE + 0x10) 566#define IWLAGN_SCD_TXFACT (IWLAGN_SCD_BASE + 0x10)
567#define IWL50_SCD_ACTIVE (IWL50_SCD_BASE + 0x14) 567#define IWLAGN_SCD_ACTIVE (IWLAGN_SCD_BASE + 0x14)
568#define IWL50_SCD_QUEUE_WRPTR(x) (IWL50_SCD_BASE + 0x18 + (x) * 4) 568#define IWLAGN_SCD_QUEUE_WRPTR(x) (IWLAGN_SCD_BASE + 0x18 + (x) * 4)
569#define IWL50_SCD_QUEUE_RDPTR(x) (IWL50_SCD_BASE + 0x68 + (x) * 4) 569#define IWLAGN_SCD_QUEUE_RDPTR(x) (IWLAGN_SCD_BASE + 0x68 + (x) * 4)
570#define IWL50_SCD_QUEUECHAIN_SEL (IWL50_SCD_BASE + 0xe8) 570#define IWLAGN_SCD_QUEUECHAIN_SEL (IWLAGN_SCD_BASE + 0xe8)
571#define IWL50_SCD_AGGR_SEL (IWL50_SCD_BASE + 0x248) 571#define IWLAGN_SCD_AGGR_SEL (IWLAGN_SCD_BASE + 0x248)
572#define IWL50_SCD_INTERRUPT_MASK (IWL50_SCD_BASE + 0x108) 572#define IWLAGN_SCD_INTERRUPT_MASK (IWLAGN_SCD_BASE + 0x108)
573#define IWL50_SCD_QUEUE_STATUS_BITS(x) (IWL50_SCD_BASE + 0x10c + (x) * 4) 573#define IWLAGN_SCD_QUEUE_STATUS_BITS(x) (IWLAGN_SCD_BASE + 0x10c + (x) * 4)
574 574
575/*********************** END TX SCHEDULER *************************************/ 575/*********************** END TX SCHEDULER *************************************/
576 576
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index e5eb339107dd..0a5d7cf25196 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -163,197 +163,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
163 spin_unlock_irqrestore(&q->lock, flags); 163 spin_unlock_irqrestore(&q->lock, flags);
164} 164}
165EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); 165EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);
166/**
167 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
168 */
169static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
170 dma_addr_t dma_addr)
171{
172 return cpu_to_le32((u32)(dma_addr >> 8));
173}
174
175/**
176 * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
177 *
178 * If there are slots in the RX queue that need to be restocked,
179 * and we have free pre-allocated buffers, fill the ranks as much
180 * as we can, pulling from rx_free.
181 *
182 * This moves the 'write' index forward to catch up with 'processed', and
183 * also updates the memory address in the firmware to reference the new
184 * target buffer.
185 */
186void iwl_rx_queue_restock(struct iwl_priv *priv)
187{
188 struct iwl_rx_queue *rxq = &priv->rxq;
189 struct list_head *element;
190 struct iwl_rx_mem_buffer *rxb;
191 unsigned long flags;
192 int write;
193
194 spin_lock_irqsave(&rxq->lock, flags);
195 write = rxq->write & ~0x7;
196 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
197 /* Get next free Rx buffer, remove from free list */
198 element = rxq->rx_free.next;
199 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
200 list_del(element);
201
202 /* Point to Rx buffer via next RBD in circular buffer */
203 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->page_dma);
204 rxq->queue[rxq->write] = rxb;
205 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
206 rxq->free_count--;
207 }
208 spin_unlock_irqrestore(&rxq->lock, flags);
209 /* If the pre-allocated buffer pool is dropping low, schedule to
210 * refill it */
211 if (rxq->free_count <= RX_LOW_WATERMARK)
212 queue_work(priv->workqueue, &priv->rx_replenish);
213
214
215 /* If we've added more space for the firmware to place data, tell it.
216 * Increment device's write pointer in multiples of 8. */
217 if (rxq->write_actual != (rxq->write & ~0x7)) {
218 spin_lock_irqsave(&rxq->lock, flags);
219 rxq->need_update = 1;
220 spin_unlock_irqrestore(&rxq->lock, flags);
221 iwl_rx_queue_update_write_ptr(priv, rxq);
222 }
223}
224EXPORT_SYMBOL(iwl_rx_queue_restock);
225
226
227/**
228 * iwl_rx_replenish - Move all used packet from rx_used to rx_free
229 *
230 * When moving to rx_free an SKB is allocated for the slot.
231 *
232 * Also restock the Rx queue via iwl_rx_queue_restock.
233 * This is called as a scheduled work item (except for during initialization)
234 */
235void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
236{
237 struct iwl_rx_queue *rxq = &priv->rxq;
238 struct list_head *element;
239 struct iwl_rx_mem_buffer *rxb;
240 struct page *page;
241 unsigned long flags;
242 gfp_t gfp_mask = priority;
243
244 while (1) {
245 spin_lock_irqsave(&rxq->lock, flags);
246 if (list_empty(&rxq->rx_used)) {
247 spin_unlock_irqrestore(&rxq->lock, flags);
248 return;
249 }
250 spin_unlock_irqrestore(&rxq->lock, flags);
251
252 if (rxq->free_count > RX_LOW_WATERMARK)
253 gfp_mask |= __GFP_NOWARN;
254
255 if (priv->hw_params.rx_page_order > 0)
256 gfp_mask |= __GFP_COMP;
257
258 /* Alloc a new receive buffer */
259 page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
260 if (!page) {
261 if (net_ratelimit())
262 IWL_DEBUG_INFO(priv, "alloc_pages failed, "
263 "order: %d\n",
264 priv->hw_params.rx_page_order);
265
266 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
267 net_ratelimit())
268 IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
269 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
270 rxq->free_count);
271 /* We don't reschedule replenish work here -- we will
272 * call the restock method and if it still needs
273 * more buffers it will schedule replenish */
274 return;
275 }
276
277 spin_lock_irqsave(&rxq->lock, flags);
278
279 if (list_empty(&rxq->rx_used)) {
280 spin_unlock_irqrestore(&rxq->lock, flags);
281 __free_pages(page, priv->hw_params.rx_page_order);
282 return;
283 }
284 element = rxq->rx_used.next;
285 rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
286 list_del(element);
287
288 spin_unlock_irqrestore(&rxq->lock, flags);
289
290 rxb->page = page;
291 /* Get physical address of the RB */
292 rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
293 PAGE_SIZE << priv->hw_params.rx_page_order,
294 PCI_DMA_FROMDEVICE);
295 /* dma address must be no more than 36 bits */
296 BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
297 /* and also 256 byte aligned! */
298 BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
299
300 spin_lock_irqsave(&rxq->lock, flags);
301
302 list_add_tail(&rxb->list, &rxq->rx_free);
303 rxq->free_count++;
304 priv->alloc_rxb_page++;
305
306 spin_unlock_irqrestore(&rxq->lock, flags);
307 }
308}
309
310void iwl_rx_replenish(struct iwl_priv *priv)
311{
312 unsigned long flags;
313
314 iwl_rx_allocate(priv, GFP_KERNEL);
315
316 spin_lock_irqsave(&priv->lock, flags);
317 iwl_rx_queue_restock(priv);
318 spin_unlock_irqrestore(&priv->lock, flags);
319}
320EXPORT_SYMBOL(iwl_rx_replenish);
321
322void iwl_rx_replenish_now(struct iwl_priv *priv)
323{
324 iwl_rx_allocate(priv, GFP_ATOMIC);
325
326 iwl_rx_queue_restock(priv);
327}
328EXPORT_SYMBOL(iwl_rx_replenish_now);
329
330
331/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
332 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
333 * This free routine walks the list of POOL entries and if SKB is set to
334 * non NULL it is unmapped and freed
335 */
336void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
337{
338 int i;
339 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
340 if (rxq->pool[i].page != NULL) {
341 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
342 PAGE_SIZE << priv->hw_params.rx_page_order,
343 PCI_DMA_FROMDEVICE);
344 __iwl_free_pages(priv, rxq->pool[i].page);
345 rxq->pool[i].page = NULL;
346 }
347 }
348
349 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
350 rxq->dma_addr);
351 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
352 rxq->rb_stts, rxq->rb_stts_dma);
353 rxq->bd = NULL;
354 rxq->rb_stts = NULL;
355}
356EXPORT_SYMBOL(iwl_rx_queue_free);
357 166
358int iwl_rx_queue_alloc(struct iwl_priv *priv) 167int iwl_rx_queue_alloc(struct iwl_priv *priv)
359{ 168{
@@ -396,98 +205,6 @@ err_bd:
396} 205}
397EXPORT_SYMBOL(iwl_rx_queue_alloc); 206EXPORT_SYMBOL(iwl_rx_queue_alloc);
398 207
399void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
400{
401 unsigned long flags;
402 int i;
403 spin_lock_irqsave(&rxq->lock, flags);
404 INIT_LIST_HEAD(&rxq->rx_free);
405 INIT_LIST_HEAD(&rxq->rx_used);
406 /* Fill the rx_used queue with _all_ of the Rx buffers */
407 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
408 /* In the reset function, these buffers may have been allocated
409 * to an SKB, so we need to unmap and free potential storage */
410 if (rxq->pool[i].page != NULL) {
411 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
412 PAGE_SIZE << priv->hw_params.rx_page_order,
413 PCI_DMA_FROMDEVICE);
414 __iwl_free_pages(priv, rxq->pool[i].page);
415 rxq->pool[i].page = NULL;
416 }
417 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
418 }
419
420 /* Set us so that we have processed and used all buffers, but have
421 * not restocked the Rx queue with fresh buffers */
422 rxq->read = rxq->write = 0;
423 rxq->write_actual = 0;
424 rxq->free_count = 0;
425 spin_unlock_irqrestore(&rxq->lock, flags);
426}
427
428int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
429{
430 u32 rb_size;
431 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
432 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
433
434 if (!priv->cfg->use_isr_legacy)
435 rb_timeout = RX_RB_TIMEOUT;
436
437 if (priv->cfg->mod_params->amsdu_size_8K)
438 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
439 else
440 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
441
442 /* Stop Rx DMA */
443 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
444
445 /* Reset driver's Rx queue write index */
446 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
447
448 /* Tell device where to find RBD circular buffer in DRAM */
449 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
450 (u32)(rxq->dma_addr >> 8));
451
452 /* Tell device where in DRAM to update its Rx status */
453 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
454 rxq->rb_stts_dma >> 4);
455
456 /* Enable Rx DMA
457 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
458 * the credit mechanism in 5000 HW RX FIFO
459 * Direct rx interrupts to hosts
460 * Rx buffer size 4 or 8k
461 * RB timeout 0x10
462 * 256 RBDs
463 */
464 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
465 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
466 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
467 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
468 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
469 rb_size|
470 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
471 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
472
473 /* Set interrupt coalescing timer to default (2048 usecs) */
474 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
475
476 return 0;
477}
478
479int iwl_rxq_stop(struct iwl_priv *priv)
480{
481
482 /* stop Rx DMA */
483 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
484 iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
485 FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
486
487 return 0;
488}
489EXPORT_SYMBOL(iwl_rxq_stop);
490
491void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 208void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
492 struct iwl_rx_mem_buffer *rxb) 209 struct iwl_rx_mem_buffer *rxb)
493 210
@@ -543,6 +260,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
543 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; 260 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
544 int bcn_silence_c = 261 int bcn_silence_c =
545 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; 262 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
263 int last_rx_noise;
546 264
547 if (bcn_silence_a) { 265 if (bcn_silence_a) {
548 total_silence += bcn_silence_a; 266 total_silence += bcn_silence_a;
@@ -559,13 +277,13 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
559 277
560 /* Average among active antennas */ 278 /* Average among active antennas */
561 if (num_active_rx) 279 if (num_active_rx)
562 priv->last_rx_noise = (total_silence / num_active_rx) - 107; 280 last_rx_noise = (total_silence / num_active_rx) - 107;
563 else 281 else
564 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 282 last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
565 283
566 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", 284 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
567 bcn_silence_a, bcn_silence_b, bcn_silence_c, 285 bcn_silence_a, bcn_silence_b, bcn_silence_c,
568 priv->last_rx_noise); 286 last_rx_noise);
569} 287}
570 288
571#ifdef CONFIG_IWLWIFI_DEBUG 289#ifdef CONFIG_IWLWIFI_DEBUG
@@ -617,29 +335,20 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
617 335
618#define REG_RECALIB_PERIOD (60) 336#define REG_RECALIB_PERIOD (60)
619 337
620#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" 338/**
621void iwl_rx_statistics(struct iwl_priv *priv, 339 * iwl_good_plcp_health - checks for plcp error.
622 struct iwl_rx_mem_buffer *rxb) 340 *
341 * When the plcp error is exceeding the thresholds, reset the radio
342 * to improve the throughput.
343 */
344bool iwl_good_plcp_health(struct iwl_priv *priv,
345 struct iwl_rx_packet *pkt)
623{ 346{
624 int change; 347 bool rc = true;
625 struct iwl_rx_packet *pkt = rxb_addr(rxb);
626 int combined_plcp_delta; 348 int combined_plcp_delta;
627 unsigned int plcp_msec; 349 unsigned int plcp_msec;
628 unsigned long plcp_received_jiffies; 350 unsigned long plcp_received_jiffies;
629 351
630 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
631 (int)sizeof(priv->statistics),
632 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
633
634 change = ((priv->statistics.general.temperature !=
635 pkt->u.stats.general.temperature) ||
636 ((priv->statistics.flag &
637 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
638 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
639
640#ifdef CONFIG_IWLWIFI_DEBUG
641 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
642#endif
643 /* 352 /*
644 * check for plcp_err and trigger radio reset if it exceeds 353 * check for plcp_err and trigger radio reset if it exceeds
645 * the plcp error threshold plcp_delta. 354 * the plcp error threshold plcp_delta.
@@ -660,11 +369,11 @@ void iwl_rx_statistics(struct iwl_priv *priv,
660 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); 369 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
661 370
662 if ((combined_plcp_delta > 0) && 371 if ((combined_plcp_delta > 0) &&
663 ((combined_plcp_delta * 100) / plcp_msec) > 372 ((combined_plcp_delta * 100) / plcp_msec) >
664 priv->cfg->plcp_delta_threshold) { 373 priv->cfg->plcp_delta_threshold) {
665 /* 374 /*
666 * if plcp_err exceed the threshold, the following 375 * if plcp_err exceed the threshold,
667 * data is printed in csv format: 376 * the following data is printed in csv format:
668 * Text: plcp_err exceeded %d, 377 * Text: plcp_err exceeded %d,
669 * Received ofdm.plcp_err, 378 * Received ofdm.plcp_err,
670 * Current ofdm.plcp_err, 379 * Current ofdm.plcp_err,
@@ -673,22 +382,76 @@ void iwl_rx_statistics(struct iwl_priv *priv,
673 * combined_plcp_delta, 382 * combined_plcp_delta,
674 * plcp_msec 383 * plcp_msec
675 */ 384 */
676 IWL_DEBUG_RADIO(priv, PLCP_MSG, 385 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
386 "%u, %u, %u, %u, %d, %u mSecs\n",
677 priv->cfg->plcp_delta_threshold, 387 priv->cfg->plcp_delta_threshold,
678 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 388 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
679 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), 389 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
680 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 390 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
681 le32_to_cpu( 391 le32_to_cpu(
682 priv->statistics.rx.ofdm_ht.plcp_err), 392 priv->statistics.rx.ofdm_ht.plcp_err),
683 combined_plcp_delta, plcp_msec); 393 combined_plcp_delta, plcp_msec);
394 rc = false;
395 }
396 }
397 return rc;
398}
399EXPORT_SYMBOL(iwl_good_plcp_health);
684 400
685 /* 401void iwl_recover_from_statistics(struct iwl_priv *priv,
686 * Reset the RF radio due to the high plcp 402 struct iwl_rx_packet *pkt)
687 * error rate 403{
688 */ 404 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
689 iwl_force_reset(priv, IWL_RF_RESET); 405 return;
406 if (iwl_is_associated(priv)) {
407 if (priv->cfg->ops->lib->check_ack_health) {
408 if (!priv->cfg->ops->lib->check_ack_health(
409 priv, pkt)) {
410 /*
411 * low ack count detected
412 * restart Firmware
413 */
414 IWL_ERR(priv, "low ack count detected, "
415 "restart firmware\n");
416 if (!iwl_force_reset(priv, IWL_FW_RESET))
417 return;
418 }
419 }
420 if (priv->cfg->ops->lib->check_plcp_health) {
421 if (!priv->cfg->ops->lib->check_plcp_health(
422 priv, pkt)) {
423 /*
424 * high plcp error detected
425 * reset Radio
426 */
427 iwl_force_reset(priv, IWL_RF_RESET);
428 }
690 } 429 }
691 } 430 }
431}
432EXPORT_SYMBOL(iwl_recover_from_statistics);
433
434void iwl_rx_statistics(struct iwl_priv *priv,
435 struct iwl_rx_mem_buffer *rxb)
436{
437 int change;
438 struct iwl_rx_packet *pkt = rxb_addr(rxb);
439
440
441 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
442 (int)sizeof(priv->statistics),
443 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
444
445 change = ((priv->statistics.general.temperature !=
446 pkt->u.stats.general.temperature) ||
447 ((priv->statistics.flag &
448 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
449 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
450
451#ifdef CONFIG_IWLWIFI_DEBUG
452 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
453#endif
454 iwl_recover_from_statistics(priv, pkt);
692 455
693 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 456 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
694 457
@@ -731,139 +494,6 @@ void iwl_reply_statistics(struct iwl_priv *priv,
731} 494}
732EXPORT_SYMBOL(iwl_reply_statistics); 495EXPORT_SYMBOL(iwl_reply_statistics);
733 496
734/* Calc max signal level (dBm) among 3 possible receivers */
735static inline int iwl_calc_rssi(struct iwl_priv *priv,
736 struct iwl_rx_phy_res *rx_resp)
737{
738 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
739}
740
741#ifdef CONFIG_IWLWIFI_DEBUG
742/**
743 * iwl_dbg_report_frame - dump frame to syslog during debug sessions
744 *
745 * You may hack this function to show different aspects of received frames,
746 * including selective frame dumps.
747 * group100 parameter selects whether to show 1 out of 100 good data frames.
748 * All beacon and probe response frames are printed.
749 */
750static void iwl_dbg_report_frame(struct iwl_priv *priv,
751 struct iwl_rx_phy_res *phy_res, u16 length,
752 struct ieee80211_hdr *header, int group100)
753{
754 u32 to_us;
755 u32 print_summary = 0;
756 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
757 u32 hundred = 0;
758 u32 dataframe = 0;
759 __le16 fc;
760 u16 seq_ctl;
761 u16 channel;
762 u16 phy_flags;
763 u32 rate_n_flags;
764 u32 tsf_low;
765 int rssi;
766
767 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
768 return;
769
770 /* MAC header */
771 fc = header->frame_control;
772 seq_ctl = le16_to_cpu(header->seq_ctrl);
773
774 /* metadata */
775 channel = le16_to_cpu(phy_res->channel);
776 phy_flags = le16_to_cpu(phy_res->phy_flags);
777 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
778
779 /* signal statistics */
780 rssi = iwl_calc_rssi(priv, phy_res);
781 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
782
783 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
784
785 /* if data frame is to us and all is good,
786 * (optionally) print summary for only 1 out of every 100 */
787 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
788 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
789 dataframe = 1;
790 if (!group100)
791 print_summary = 1; /* print each frame */
792 else if (priv->framecnt_to_us < 100) {
793 priv->framecnt_to_us++;
794 print_summary = 0;
795 } else {
796 priv->framecnt_to_us = 0;
797 print_summary = 1;
798 hundred = 1;
799 }
800 } else {
801 /* print summary for all other frames */
802 print_summary = 1;
803 }
804
805 if (print_summary) {
806 char *title;
807 int rate_idx;
808 u32 bitrate;
809
810 if (hundred)
811 title = "100Frames";
812 else if (ieee80211_has_retry(fc))
813 title = "Retry";
814 else if (ieee80211_is_assoc_resp(fc))
815 title = "AscRsp";
816 else if (ieee80211_is_reassoc_resp(fc))
817 title = "RasRsp";
818 else if (ieee80211_is_probe_resp(fc)) {
819 title = "PrbRsp";
820 print_dump = 1; /* dump frame contents */
821 } else if (ieee80211_is_beacon(fc)) {
822 title = "Beacon";
823 print_dump = 1; /* dump frame contents */
824 } else if (ieee80211_is_atim(fc))
825 title = "ATIM";
826 else if (ieee80211_is_auth(fc))
827 title = "Auth";
828 else if (ieee80211_is_deauth(fc))
829 title = "DeAuth";
830 else if (ieee80211_is_disassoc(fc))
831 title = "DisAssoc";
832 else
833 title = "Frame";
834
835 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
836 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
837 bitrate = 0;
838 WARN_ON_ONCE(1);
839 } else {
840 bitrate = iwl_rates[rate_idx].ieee / 2;
841 }
842
843 /* print frame summary.
844 * MAC addresses show just the last byte (for brevity),
845 * but you can hack it to show more, if you'd like to. */
846 if (dataframe)
847 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
848 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
849 title, le16_to_cpu(fc), header->addr1[5],
850 length, rssi, channel, bitrate);
851 else {
852 /* src/dst addresses assume managed mode */
853 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
854 "len=%u, rssi=%d, tim=%lu usec, "
855 "phy=0x%02x, chnl=%d\n",
856 title, le16_to_cpu(fc), header->addr1[5],
857 header->addr3[5], length, rssi,
858 tsf_low - priv->scan_start_tsf,
859 phy_flags, channel);
860 }
861 }
862 if (print_dump)
863 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
864}
865#endif
866
867/* 497/*
868 * returns non-zero if packet should be dropped 498 * returns non-zero if packet should be dropped
869 */ 499 */
@@ -911,305 +541,3 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
911 return 0; 541 return 0;
912} 542}
913EXPORT_SYMBOL(iwl_set_decrypted_flag); 543EXPORT_SYMBOL(iwl_set_decrypted_flag);
914
915static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
916{
917 u32 decrypt_out = 0;
918
919 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
920 RX_RES_STATUS_STATION_FOUND)
921 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
922 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
923
924 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
925
926 /* packet was not encrypted */
927 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
928 RX_RES_STATUS_SEC_TYPE_NONE)
929 return decrypt_out;
930
931 /* packet was encrypted with unknown alg */
932 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
933 RX_RES_STATUS_SEC_TYPE_ERR)
934 return decrypt_out;
935
936 /* decryption was not done in HW */
937 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
938 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
939 return decrypt_out;
940
941 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
942
943 case RX_RES_STATUS_SEC_TYPE_CCMP:
944 /* alg is CCM: check MIC only */
945 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
946 /* Bad MIC */
947 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
948 else
949 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
950
951 break;
952
953 case RX_RES_STATUS_SEC_TYPE_TKIP:
954 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
955 /* Bad TTAK */
956 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
957 break;
958 }
959 /* fall through if TTAK OK */
960 default:
961 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
962 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
963 else
964 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
965 break;
966 };
967
968 IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
969 decrypt_in, decrypt_out);
970
971 return decrypt_out;
972}
973
974static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
975 struct ieee80211_hdr *hdr,
976 u16 len,
977 u32 ampdu_status,
978 struct iwl_rx_mem_buffer *rxb,
979 struct ieee80211_rx_status *stats)
980{
981 struct sk_buff *skb;
982 int ret = 0;
983 __le16 fc = hdr->frame_control;
984
985 /* We only process data packets if the interface is open */
986 if (unlikely(!priv->is_open)) {
987 IWL_DEBUG_DROP_LIMIT(priv,
988 "Dropping packet while interface is not open.\n");
989 return;
990 }
991
992 /* In case of HW accelerated crypto and bad decryption, drop */
993 if (!priv->cfg->mod_params->sw_crypto &&
994 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
995 return;
996
997 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
998 if (!skb) {
999 IWL_ERR(priv, "alloc_skb failed\n");
1000 return;
1001 }
1002
1003 skb_reserve(skb, IWL_LINK_HDR_MAX);
1004 skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
1005
1006 /* mac80211 currently doesn't support paged SKB. Convert it to
1007 * linear SKB for management frame and data frame requires
1008 * software decryption or software defragementation. */
1009 if (ieee80211_is_mgmt(fc) ||
1010 ieee80211_has_protected(fc) ||
1011 ieee80211_has_morefrags(fc) ||
1012 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
1013 (ieee80211_is_data_qos(fc) &&
1014 *ieee80211_get_qos_ctl(hdr) &
1015 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
1016 ret = skb_linearize(skb);
1017 else
1018 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
1019 0 : -ENOMEM;
1020
1021 if (ret) {
1022 kfree_skb(skb);
1023 goto out;
1024 }
1025
1026 /*
1027 * XXX: We cannot touch the page and its virtual memory (hdr) after
1028 * here. It might have already been freed by the above skb change.
1029 */
1030
1031 iwl_update_stats(priv, false, fc, len);
1032 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
1033
1034 ieee80211_rx(priv->hw, skb);
1035 out:
1036 priv->alloc_rxb_page--;
1037 rxb->page = NULL;
1038}
1039
1040/* This is necessary only for a number of statistics, see the caller. */
1041static int iwl_is_network_packet(struct iwl_priv *priv,
1042 struct ieee80211_hdr *header)
1043{
1044 /* Filter incoming packets to determine if they are targeted toward
1045 * this network, discarding packets coming from ourselves */
1046 switch (priv->iw_mode) {
1047 case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */
1048 /* packets to our IBSS update information */
1049 return !compare_ether_addr(header->addr3, priv->bssid);
1050 case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */
1051 /* packets to our IBSS update information */
1052 return !compare_ether_addr(header->addr2, priv->bssid);
1053 default:
1054 return 1;
1055 }
1056}
1057
1058/* Called for REPLY_RX (legacy ABG frames), or
1059 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
1060void iwl_rx_reply_rx(struct iwl_priv *priv,
1061 struct iwl_rx_mem_buffer *rxb)
1062{
1063 struct ieee80211_hdr *header;
1064 struct ieee80211_rx_status rx_status;
1065 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1066 struct iwl_rx_phy_res *phy_res;
1067 __le32 rx_pkt_status;
1068 struct iwl4965_rx_mpdu_res_start *amsdu;
1069 u32 len;
1070 u32 ampdu_status;
1071 u32 rate_n_flags;
1072
1073 /**
1074 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
1075 * REPLY_RX: physical layer info is in this buffer
1076 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
1077 * command and cached in priv->last_phy_res
1078 *
1079 * Here we set up local variables depending on which command is
1080 * received.
1081 */
1082 if (pkt->hdr.cmd == REPLY_RX) {
1083 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
1084 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
1085 + phy_res->cfg_phy_cnt);
1086
1087 len = le16_to_cpu(phy_res->byte_count);
1088 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
1089 phy_res->cfg_phy_cnt + len);
1090 ampdu_status = le32_to_cpu(rx_pkt_status);
1091 } else {
1092 if (!priv->last_phy_res[0]) {
1093 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
1094 return;
1095 }
1096 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
1097 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1098 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1099 len = le16_to_cpu(amsdu->byte_count);
1100 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
1101 ampdu_status = iwl_translate_rx_status(priv,
1102 le32_to_cpu(rx_pkt_status));
1103 }
1104
1105 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
1106 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
1107 phy_res->cfg_phy_cnt);
1108 return;
1109 }
1110
1111 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
1112 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1113 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1114 le32_to_cpu(rx_pkt_status));
1115 return;
1116 }
1117
1118 /* This will be used in several places later */
1119 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
1120
1121 /* rx_status carries information about the packet to mac80211 */
1122 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
1123 rx_status.freq =
1124 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
1125 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1126 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1127 rx_status.rate_idx =
1128 iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
1129 rx_status.flag = 0;
1130
1131 /* TSF isn't reliable. In order to allow smooth user experience,
1132 * this W/A doesn't propagate it to the mac80211 */
1133 /*rx_status.flag |= RX_FLAG_TSFT;*/
1134
1135 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
1136
1137 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1138 rx_status.signal = iwl_calc_rssi(priv, phy_res);
1139
1140 /* Meaningful noise values are available only from beacon statistics,
1141 * which are gathered only when associated, and indicate noise
1142 * only for the associated network channel ...
1143 * Ignore these noise values while scanning (other channels) */
1144 if (iwl_is_associated(priv) &&
1145 !test_bit(STATUS_SCANNING, &priv->status)) {
1146 rx_status.noise = priv->last_rx_noise;
1147 } else {
1148 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1149 }
1150
1151 /* Reset beacon noise level if not associated. */
1152 if (!iwl_is_associated(priv))
1153 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1154
1155#ifdef CONFIG_IWLWIFI_DEBUG
1156 /* Set "1" to report good data frames in groups of 100 */
1157 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1158 iwl_dbg_report_frame(priv, phy_res, len, header, 1);
1159#endif
1160 iwl_dbg_log_rx_data_frame(priv, len, header);
1161 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n",
1162 rx_status.signal, rx_status.noise,
1163 (unsigned long long)rx_status.mactime);
1164
1165 /*
1166 * "antenna number"
1167 *
1168 * It seems that the antenna field in the phy flags value
1169 * is actually a bit field. This is undefined by radiotap,
1170 * it wants an actual antenna number but I always get "7"
1171 * for most legacy frames I receive indicating that the
1172 * same frame was received on all three RX chains.
1173 *
1174 * I think this field should be removed in favor of a
1175 * new 802.11n radiotap field "RX chains" that is defined
1176 * as a bitmask.
1177 */
1178 rx_status.antenna =
1179 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1180 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1181
1182 /* set the preamble flag if appropriate */
1183 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1184 rx_status.flag |= RX_FLAG_SHORTPRE;
1185
1186 /* Set up the HT phy flags */
1187 if (rate_n_flags & RATE_MCS_HT_MSK)
1188 rx_status.flag |= RX_FLAG_HT;
1189 if (rate_n_flags & RATE_MCS_HT40_MSK)
1190 rx_status.flag |= RX_FLAG_40MHZ;
1191 if (rate_n_flags & RATE_MCS_SGI_MSK)
1192 rx_status.flag |= RX_FLAG_SHORT_GI;
1193
1194 if (iwl_is_network_packet(priv, header)) {
1195 priv->last_rx_rssi = rx_status.signal;
1196 priv->last_beacon_time = priv->ucode_beacon_time;
1197 priv->last_tsf = le64_to_cpu(phy_res->timestamp);
1198 }
1199
1200 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1201 rxb, &rx_status);
1202}
1203EXPORT_SYMBOL(iwl_rx_reply_rx);
1204
1205/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1206 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1207void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
1208 struct iwl_rx_mem_buffer *rxb)
1209{
1210 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1211 priv->last_phy_res[0] = 1;
1212 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1213 sizeof(struct iwl_rx_phy_res));
1214}
1215EXPORT_SYMBOL(iwl_rx_reply_rx_phy);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 741e65ec8301..107e173112f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -69,9 +69,8 @@ int iwl_scan_cancel(struct iwl_priv *priv)
69 } 69 }
70 70
71 if (test_bit(STATUS_SCANNING, &priv->status)) { 71 if (test_bit(STATUS_SCANNING, &priv->status)) {
72 if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { 72 if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
73 IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n"); 73 IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
74 set_bit(STATUS_SCAN_ABORTING, &priv->status);
75 queue_work(priv->workqueue, &priv->abort_scan); 74 queue_work(priv->workqueue, &priv->abort_scan);
76 75
77 } else 76 } else
@@ -201,9 +200,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
201 le32_to_cpu(notif->statistics[0]), 200 le32_to_cpu(notif->statistics[0]),
202 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); 201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
203#endif 202#endif
204
205 if (!priv->is_internal_short_scan)
206 priv->next_scan_jiffies = 0;
207} 203}
208 204
209/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 205/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -223,49 +219,24 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
223 /* The HW is no longer scanning */ 219 /* The HW is no longer scanning */
224 clear_bit(STATUS_SCAN_HW, &priv->status); 220 clear_bit(STATUS_SCAN_HW, &priv->status);
225 221
226 IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n", 222 IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
227 (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? 223 (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
228 "2.4" : "5.2",
229 jiffies_to_msecs(elapsed_jiffies 224 jiffies_to_msecs(elapsed_jiffies
230 (priv->scan_pass_start, jiffies))); 225 (priv->scan_start, jiffies)));
231 226
232 /* Remove this scanned band from the list of pending 227 /*
233 * bands to scan, band G precedes A in order of scanning 228 * If a request to abort was given, or the scan did not succeed
234 * as seen in iwl_bg_request_scan */
235 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
236 priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
237 else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
238 priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
239
240 /* If a request to abort was given, or the scan did not succeed
241 * then we reset the scan state machine and terminate, 229 * then we reset the scan state machine and terminate,
242 * re-queuing another scan if one has been requested */ 230 * re-queuing another scan if one has been requested
243 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { 231 */
232 if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
244 IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); 233 IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
245 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
246 } else {
247 /* If there are more bands on this scan pass reschedule */
248 if (priv->scan_bands)
249 goto reschedule;
250 }
251
252 if (!priv->is_internal_short_scan)
253 priv->next_scan_jiffies = 0;
254 234
255 IWL_DEBUG_INFO(priv, "Setting scan to off\n"); 235 IWL_DEBUG_INFO(priv, "Setting scan to off\n");
256 236
257 clear_bit(STATUS_SCANNING, &priv->status); 237 clear_bit(STATUS_SCANNING, &priv->status);
258 238
259 IWL_DEBUG_INFO(priv, "Scan took %dms\n",
260 jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
261
262 queue_work(priv->workqueue, &priv->scan_completed); 239 queue_work(priv->workqueue, &priv->scan_completed);
263
264 return;
265
266reschedule:
267 priv->scan_pass_start = jiffies;
268 queue_work(priv->workqueue, &priv->request_scan);
269} 240}
270 241
271void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) 242void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -294,7 +265,8 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
294EXPORT_SYMBOL(iwl_get_active_dwell_time); 265EXPORT_SYMBOL(iwl_get_active_dwell_time);
295 266
296u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, 267u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
297 enum ieee80211_band band) 268 enum ieee80211_band band,
269 struct ieee80211_vif *vif)
298{ 270{
299 u16 passive = (band == IEEE80211_BAND_2GHZ) ? 271 u16 passive = (band == IEEE80211_BAND_2GHZ) ?
300 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : 272 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -304,7 +276,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
304 /* If we're associated, we clamp the maximum passive 276 /* If we're associated, we clamp the maximum passive
305 * dwell time to be 98% of the beacon interval (minus 277 * dwell time to be 98% of the beacon interval (minus
306 * 2 * channel tune time) */ 278 * 2 * channel tune time) */
307 passive = priv->beacon_int; 279 passive = vif ? vif->bss_conf.beacon_int : 0;
308 if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) 280 if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
309 passive = IWL_PASSIVE_DWELL_BASE; 281 passive = IWL_PASSIVE_DWELL_BASE;
310 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; 282 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
@@ -314,150 +286,6 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
314} 286}
315EXPORT_SYMBOL(iwl_get_passive_dwell_time); 287EXPORT_SYMBOL(iwl_get_passive_dwell_time);
316 288
317static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
318 enum ieee80211_band band,
319 struct iwl_scan_channel *scan_ch)
320{
321 const struct ieee80211_supported_band *sband;
322 const struct iwl_channel_info *ch_info;
323 u16 passive_dwell = 0;
324 u16 active_dwell = 0;
325 int i, added = 0;
326 u16 channel = 0;
327
328 sband = iwl_get_hw_mode(priv, band);
329 if (!sband) {
330 IWL_ERR(priv, "invalid band\n");
331 return added;
332 }
333
334 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
335 passive_dwell = iwl_get_passive_dwell_time(priv, band);
336
337 if (passive_dwell <= active_dwell)
338 passive_dwell = active_dwell + 1;
339
340 /* only scan single channel, good enough to reset the RF */
341 /* pick the first valid not in-use channel */
342 if (band == IEEE80211_BAND_5GHZ) {
343 for (i = 14; i < priv->channel_count; i++) {
344 if (priv->channel_info[i].channel !=
345 le16_to_cpu(priv->staging_rxon.channel)) {
346 channel = priv->channel_info[i].channel;
347 ch_info = iwl_get_channel_info(priv,
348 band, channel);
349 if (is_channel_valid(ch_info))
350 break;
351 }
352 }
353 } else {
354 for (i = 0; i < 14; i++) {
355 if (priv->channel_info[i].channel !=
356 le16_to_cpu(priv->staging_rxon.channel)) {
357 channel =
358 priv->channel_info[i].channel;
359 ch_info = iwl_get_channel_info(priv,
360 band, channel);
361 if (is_channel_valid(ch_info))
362 break;
363 }
364 }
365 }
366 if (channel) {
367 scan_ch->channel = cpu_to_le16(channel);
368 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
369 scan_ch->active_dwell = cpu_to_le16(active_dwell);
370 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
371 /* Set txpower levels to defaults */
372 scan_ch->dsp_atten = 110;
373 if (band == IEEE80211_BAND_5GHZ)
374 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
375 else
376 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
377 added++;
378 } else
379 IWL_ERR(priv, "no valid channel found\n");
380 return added;
381}
382
383static int iwl_get_channels_for_scan(struct iwl_priv *priv,
384 enum ieee80211_band band,
385 u8 is_active, u8 n_probes,
386 struct iwl_scan_channel *scan_ch)
387{
388 struct ieee80211_channel *chan;
389 const struct ieee80211_supported_band *sband;
390 const struct iwl_channel_info *ch_info;
391 u16 passive_dwell = 0;
392 u16 active_dwell = 0;
393 int added, i;
394 u16 channel;
395
396 sband = iwl_get_hw_mode(priv, band);
397 if (!sband)
398 return 0;
399
400 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
401 passive_dwell = iwl_get_passive_dwell_time(priv, band);
402
403 if (passive_dwell <= active_dwell)
404 passive_dwell = active_dwell + 1;
405
406 for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
407 chan = priv->scan_request->channels[i];
408
409 if (chan->band != band)
410 continue;
411
412 channel = ieee80211_frequency_to_channel(chan->center_freq);
413 scan_ch->channel = cpu_to_le16(channel);
414
415 ch_info = iwl_get_channel_info(priv, band, channel);
416 if (!is_channel_valid(ch_info)) {
417 IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
418 channel);
419 continue;
420 }
421
422 if (!is_active || is_channel_passive(ch_info) ||
423 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
424 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
425 else
426 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
427
428 if (n_probes)
429 scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
430
431 scan_ch->active_dwell = cpu_to_le16(active_dwell);
432 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
433
434 /* Set txpower levels to defaults */
435 scan_ch->dsp_atten = 110;
436
437 /* NOTE: if we were doing 6Mb OFDM for scans we'd use
438 * power level:
439 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
440 */
441 if (band == IEEE80211_BAND_5GHZ)
442 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
443 else
444 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
445
446 IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
447 channel, le32_to_cpu(scan_ch->type),
448 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
449 "ACTIVE" : "PASSIVE",
450 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
451 active_dwell : passive_dwell);
452
453 scan_ch++;
454 added++;
455 }
456
457 IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
458 return added;
459}
460
461void iwl_init_scan_params(struct iwl_priv *priv) 289void iwl_init_scan_params(struct iwl_priv *priv)
462{ 290{
463 u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; 291 u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1;
@@ -468,7 +296,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
468} 296}
469EXPORT_SYMBOL(iwl_init_scan_params); 297EXPORT_SYMBOL(iwl_init_scan_params);
470 298
471static int iwl_scan_initiate(struct iwl_priv *priv) 299static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
472{ 300{
473 WARN_ON(!mutex_is_locked(&priv->mutex)); 301 WARN_ON(!mutex_is_locked(&priv->mutex));
474 302
@@ -476,26 +304,28 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
476 set_bit(STATUS_SCANNING, &priv->status); 304 set_bit(STATUS_SCANNING, &priv->status);
477 priv->is_internal_short_scan = false; 305 priv->is_internal_short_scan = false;
478 priv->scan_start = jiffies; 306 priv->scan_start = jiffies;
479 priv->scan_pass_start = priv->scan_start;
480 307
481 queue_work(priv->workqueue, &priv->request_scan); 308 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
309 return -EOPNOTSUPP;
310
311 priv->cfg->ops->utils->request_scan(priv, vif);
482 312
483 return 0; 313 return 0;
484} 314}
485 315
486#define IWL_DELAY_NEXT_SCAN (HZ*2)
487
488int iwl_mac_hw_scan(struct ieee80211_hw *hw, 316int iwl_mac_hw_scan(struct ieee80211_hw *hw,
489 struct cfg80211_scan_request *req) 317 struct ieee80211_vif *vif,
318 struct cfg80211_scan_request *req)
490{ 319{
491 unsigned long flags;
492 struct iwl_priv *priv = hw->priv; 320 struct iwl_priv *priv = hw->priv;
493 int ret, i; 321 int ret;
494 322
495 IWL_DEBUG_MAC80211(priv, "enter\n"); 323 IWL_DEBUG_MAC80211(priv, "enter\n");
496 324
325 if (req->n_channels == 0)
326 return -EINVAL;
327
497 mutex_lock(&priv->mutex); 328 mutex_lock(&priv->mutex);
498 spin_lock_irqsave(&priv->lock, flags);
499 329
500 if (!iwl_is_ready_rf(priv)) { 330 if (!iwl_is_ready_rf(priv)) {
501 ret = -EIO; 331 ret = -EIO;
@@ -515,30 +345,15 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
515 goto out_unlock; 345 goto out_unlock;
516 } 346 }
517 347
518 /* We don't schedule scan within next_scan_jiffies period. 348 /* mac80211 will only ask for one band at a time */
519 * Avoid scanning during possible EAPOL exchange, return 349 priv->scan_band = req->channels[0]->band;
520 * success immediately.
521 */
522 if (priv->next_scan_jiffies &&
523 time_after(priv->next_scan_jiffies, jiffies)) {
524 IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
525 queue_work(priv->workqueue, &priv->scan_completed);
526 ret = 0;
527 goto out_unlock;
528 }
529
530 priv->scan_bands = 0;
531 for (i = 0; i < req->n_channels; i++)
532 priv->scan_bands |= BIT(req->channels[i]->band);
533
534 priv->scan_request = req; 350 priv->scan_request = req;
535 351
536 ret = iwl_scan_initiate(priv); 352 ret = iwl_scan_initiate(priv, vif);
537 353
538 IWL_DEBUG_MAC80211(priv, "leave\n"); 354 IWL_DEBUG_MAC80211(priv, "leave\n");
539 355
540out_unlock: 356out_unlock:
541 spin_unlock_irqrestore(&priv->lock, flags);
542 mutex_unlock(&priv->mutex); 357 mutex_unlock(&priv->mutex);
543 358
544 return ret; 359 return ret;
@@ -554,7 +369,7 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv)
554 queue_work(priv->workqueue, &priv->start_internal_scan); 369 queue_work(priv->workqueue, &priv->start_internal_scan);
555} 370}
556 371
557static void iwl_bg_start_internal_scan(struct work_struct *work) 372void iwl_bg_start_internal_scan(struct work_struct *work)
558{ 373{
559 struct iwl_priv *priv = 374 struct iwl_priv *priv =
560 container_of(work, struct iwl_priv, start_internal_scan); 375 container_of(work, struct iwl_priv, start_internal_scan);
@@ -576,22 +391,20 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
576 goto unlock; 391 goto unlock;
577 } 392 }
578 393
579 priv->scan_bands = 0; 394 priv->scan_band = priv->band;
580 if (priv->band == IEEE80211_BAND_5GHZ)
581 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
582 else
583 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
584 395
585 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n"); 396 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
586 set_bit(STATUS_SCANNING, &priv->status); 397 set_bit(STATUS_SCANNING, &priv->status);
587 priv->is_internal_short_scan = true; 398 priv->is_internal_short_scan = true;
588 queue_work(priv->workqueue, &priv->request_scan); 399
400 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
401 goto unlock;
402
403 priv->cfg->ops->utils->request_scan(priv, NULL);
589 unlock: 404 unlock:
590 mutex_unlock(&priv->mutex); 405 mutex_unlock(&priv->mutex);
591} 406}
592EXPORT_SYMBOL(iwl_internal_short_hw_scan); 407EXPORT_SYMBOL(iwl_bg_start_internal_scan);
593
594#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
595 408
596void iwl_bg_scan_check(struct work_struct *data) 409void iwl_bg_scan_check(struct work_struct *data)
597{ 410{
@@ -654,289 +467,15 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
654 if (WARN_ON(left < ie_len)) 467 if (WARN_ON(left < ie_len))
655 return len; 468 return len;
656 469
657 if (ies) 470 if (ies && ie_len) {
658 memcpy(pos, ies, ie_len); 471 memcpy(pos, ies, ie_len);
659 len += ie_len; 472 len += ie_len;
660 left -= ie_len; 473 }
661 474
662 return (u16)len; 475 return (u16)len;
663} 476}
664EXPORT_SYMBOL(iwl_fill_probe_req); 477EXPORT_SYMBOL(iwl_fill_probe_req);
665 478
666static void iwl_bg_request_scan(struct work_struct *data)
667{
668 struct iwl_priv *priv =
669 container_of(data, struct iwl_priv, request_scan);
670 struct iwl_host_cmd cmd = {
671 .id = REPLY_SCAN_CMD,
672 .len = sizeof(struct iwl_scan_cmd),
673 .flags = CMD_SIZE_HUGE,
674 };
675 struct iwl_scan_cmd *scan;
676 struct ieee80211_conf *conf = NULL;
677 int ret = 0;
678 u32 rate_flags = 0;
679 u16 cmd_len;
680 u16 rx_chain = 0;
681 enum ieee80211_band band;
682 u8 n_probes = 0;
683 u8 rx_ant = priv->hw_params.valid_rx_ant;
684 u8 rate;
685 bool is_active = false;
686 int chan_mod;
687 u8 active_chains;
688
689 conf = ieee80211_get_hw_conf(priv->hw);
690
691 mutex_lock(&priv->mutex);
692
693 cancel_delayed_work(&priv->scan_check);
694
695 if (!iwl_is_ready(priv)) {
696 IWL_WARN(priv, "request scan called when driver not ready.\n");
697 goto done;
698 }
699
700 /* Make sure the scan wasn't canceled before this queued work
701 * was given the chance to run... */
702 if (!test_bit(STATUS_SCANNING, &priv->status))
703 goto done;
704
705 /* This should never be called or scheduled if there is currently
706 * a scan active in the hardware. */
707 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
708 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
709 "Ignoring second request.\n");
710 ret = -EIO;
711 goto done;
712 }
713
714 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
715 IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
716 goto done;
717 }
718
719 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
720 IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
721 goto done;
722 }
723
724 if (iwl_is_rfkill(priv)) {
725 IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
726 goto done;
727 }
728
729 if (!test_bit(STATUS_READY, &priv->status)) {
730 IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
731 goto done;
732 }
733
734 if (!priv->scan_bands) {
735 IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
736 goto done;
737 }
738
739 if (!priv->scan) {
740 priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
741 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
742 if (!priv->scan) {
743 ret = -ENOMEM;
744 goto done;
745 }
746 }
747 scan = priv->scan;
748 memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
749
750 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
751 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
752
753 if (iwl_is_associated(priv)) {
754 u16 interval = 0;
755 u32 extra;
756 u32 suspend_time = 100;
757 u32 scan_suspend_time = 100;
758 unsigned long flags;
759
760 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
761 spin_lock_irqsave(&priv->lock, flags);
762 interval = priv->beacon_int;
763 spin_unlock_irqrestore(&priv->lock, flags);
764
765 scan->suspend_time = 0;
766 scan->max_out_time = cpu_to_le32(200 * 1024);
767 if (!interval)
768 interval = suspend_time;
769
770 extra = (suspend_time / interval) << 22;
771 scan_suspend_time = (extra |
772 ((suspend_time % interval) * 1024));
773 scan->suspend_time = cpu_to_le32(scan_suspend_time);
774 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
775 scan_suspend_time, interval);
776 }
777
778 if (priv->is_internal_short_scan) {
779 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
780 } else if (priv->scan_request->n_ssids) {
781 int i, p = 0;
782 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
783 for (i = 0; i < priv->scan_request->n_ssids; i++) {
784 /* always does wildcard anyway */
785 if (!priv->scan_request->ssids[i].ssid_len)
786 continue;
787 scan->direct_scan[p].id = WLAN_EID_SSID;
788 scan->direct_scan[p].len =
789 priv->scan_request->ssids[i].ssid_len;
790 memcpy(scan->direct_scan[p].ssid,
791 priv->scan_request->ssids[i].ssid,
792 priv->scan_request->ssids[i].ssid_len);
793 n_probes++;
794 p++;
795 }
796 is_active = true;
797 } else
798 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
799
800 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
801 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
802 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
803
804
805 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
806 band = IEEE80211_BAND_2GHZ;
807 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
808 chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
809 >> RXON_FLG_CHANNEL_MODE_POS;
810 if (chan_mod == CHANNEL_MODE_PURE_40) {
811 rate = IWL_RATE_6M_PLCP;
812 } else {
813 rate = IWL_RATE_1M_PLCP;
814 rate_flags = RATE_MCS_CCK_MSK;
815 }
816 scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
817 } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
818 band = IEEE80211_BAND_5GHZ;
819 rate = IWL_RATE_6M_PLCP;
820 /*
821 * If active scanning is requested but a certain channel is
822 * marked passive, we can do active scanning if we detect
823 * transmissions.
824 *
825 * There is an issue with some firmware versions that triggers
826 * a sysassert on a "good CRC threshold" of zero (== disabled),
827 * on a radar channel even though this means that we should NOT
828 * send probes.
829 *
830 * The "good CRC threshold" is the number of frames that we
831 * need to receive during our dwell time on a channel before
832 * sending out probes -- setting this to a huge value will
833 * mean we never reach it, but at the same time work around
834 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
835 * here instead of IWL_GOOD_CRC_TH_DISABLED.
836 */
837 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
838 IWL_GOOD_CRC_TH_NEVER;
839
840 /* Force use of chains B and C (0x6) for scan Rx for 4965
841 * Avoid A (0x1) because of its off-channel reception on A-band.
842 */
843 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
844 rx_ant = ANT_BC;
845 } else {
846 IWL_WARN(priv, "Invalid scan band count\n");
847 goto done;
848 }
849
850 priv->scan_tx_ant[band] =
851 iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
852 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
853 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
854
855 /* In power save mode use one chain, otherwise use all chains */
856 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
857 /* rx_ant has been set to all valid chains previously */
858 active_chains = rx_ant &
859 ((u8)(priv->chain_noise_data.active_chains));
860 if (!active_chains)
861 active_chains = rx_ant;
862
863 IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
864 priv->chain_noise_data.active_chains);
865
866 rx_ant = first_antenna(active_chains);
867 }
868 /* MIMO is not used here, but value is required */
869 rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
870 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
871 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
872 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
873 scan->rx_chain = cpu_to_le16(rx_chain);
874 if (!priv->is_internal_short_scan) {
875 cmd_len = iwl_fill_probe_req(priv,
876 (struct ieee80211_mgmt *)scan->data,
877 priv->scan_request->ie,
878 priv->scan_request->ie_len,
879 IWL_MAX_SCAN_SIZE - sizeof(*scan));
880 } else {
881 cmd_len = iwl_fill_probe_req(priv,
882 (struct ieee80211_mgmt *)scan->data,
883 NULL, 0,
884 IWL_MAX_SCAN_SIZE - sizeof(*scan));
885
886 }
887 scan->tx_cmd.len = cpu_to_le16(cmd_len);
888 if (iwl_is_monitor_mode(priv))
889 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
890
891 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
892 RXON_FILTER_BCON_AWARE_MSK);
893
894 if (priv->is_internal_short_scan) {
895 scan->channel_count =
896 iwl_get_single_channel_for_scan(priv, band,
897 (void *)&scan->data[le16_to_cpu(
898 scan->tx_cmd.len)]);
899 } else {
900 scan->channel_count =
901 iwl_get_channels_for_scan(priv, band,
902 is_active, n_probes,
903 (void *)&scan->data[le16_to_cpu(
904 scan->tx_cmd.len)]);
905 }
906 if (scan->channel_count == 0) {
907 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
908 goto done;
909 }
910
911 cmd.len += le16_to_cpu(scan->tx_cmd.len) +
912 scan->channel_count * sizeof(struct iwl_scan_channel);
913 cmd.data = scan;
914 scan->len = cpu_to_le16(cmd.len);
915
916 set_bit(STATUS_SCAN_HW, &priv->status);
917 ret = iwl_send_cmd_sync(priv, &cmd);
918 if (ret)
919 goto done;
920
921 queue_delayed_work(priv->workqueue, &priv->scan_check,
922 IWL_SCAN_CHECK_WATCHDOG);
923
924 mutex_unlock(&priv->mutex);
925 return;
926
927 done:
928 /* Cannot perform scan. Make sure we clear scanning
929 * bits from status so next scan request can be performed.
930 * If we don't clear scanning status bit here all next scan
931 * will fail
932 */
933 clear_bit(STATUS_SCAN_HW, &priv->status);
934 clear_bit(STATUS_SCANNING, &priv->status);
935 /* inform mac80211 scan aborted */
936 queue_work(priv->workqueue, &priv->scan_completed);
937 mutex_unlock(&priv->mutex);
938}
939
940void iwl_bg_abort_scan(struct work_struct *work) 479void iwl_bg_abort_scan(struct work_struct *work)
941{ 480{
942 struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); 481 struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
@@ -984,7 +523,6 @@ EXPORT_SYMBOL(iwl_bg_scan_completed);
984void iwl_setup_scan_deferred_work(struct iwl_priv *priv) 523void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
985{ 524{
986 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 525 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
987 INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
988 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 526 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
989 INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); 527 INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
990 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); 528 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 4a6686fa6b36..85ed235ac901 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -29,57 +29,12 @@
29 29
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h>
32 33
33#include "iwl-dev.h" 34#include "iwl-dev.h"
34#include "iwl-core.h" 35#include "iwl-core.h"
35#include "iwl-sta.h" 36#include "iwl-sta.h"
36 37
37#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
38#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
39
40u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
41{
42 int i;
43 int start = 0;
44 int ret = IWL_INVALID_STATION;
45 unsigned long flags;
46
47 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
48 (priv->iw_mode == NL80211_IFTYPE_AP))
49 start = IWL_STA_ID;
50
51 if (is_broadcast_ether_addr(addr))
52 return priv->hw_params.bcast_sta_id;
53
54 spin_lock_irqsave(&priv->sta_lock, flags);
55 for (i = start; i < priv->hw_params.max_stations; i++)
56 if (priv->stations[i].used &&
57 (!compare_ether_addr(priv->stations[i].sta.sta.addr,
58 addr))) {
59 ret = i;
60 goto out;
61 }
62
63 IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
64 addr, priv->num_stations);
65
66 out:
67 spin_unlock_irqrestore(&priv->sta_lock, flags);
68 return ret;
69}
70EXPORT_SYMBOL(iwl_find_station);
71
72int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
73{
74 if (priv->iw_mode == NL80211_IFTYPE_STATION) {
75 return IWL_AP_ID;
76 } else {
77 u8 *da = ieee80211_get_DA(hdr);
78 return iwl_find_station(priv, da);
79 }
80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id);
82
83/* priv->sta_lock must be held */ 38/* priv->sta_lock must be held */
84static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 39static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
85{ 40{
@@ -132,7 +87,7 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
132 sta_id); 87 sta_id);
133 break; 88 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA: 89 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n", 90 IWL_ERR(priv, "Attempting to modify non-existing station %d\n",
136 sta_id); 91 sta_id);
137 break; 92 break;
138 default: 93 default:
@@ -158,13 +113,6 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
158 priv->stations[sta_id].sta.mode == 113 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 114 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr); 115 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags); 116 spin_unlock_irqrestore(&priv->sta_lock, flags);
169} 117}
170 118
@@ -190,6 +138,10 @@ int iwl_send_add_sta(struct iwl_priv *priv,
190 .flags = flags, 138 .flags = flags,
191 .data = data, 139 .data = data,
192 }; 140 };
141 u8 sta_id __maybe_unused = sta->sta.sta_id;
142
143 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
144 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
193 145
194 if (flags & CMD_ASYNC) 146 if (flags & CMD_ASYNC)
195 cmd.callback = iwl_add_sta_callback; 147 cmd.callback = iwl_add_sta_callback;
@@ -263,18 +215,19 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
263} 215}
264 216
265/** 217/**
266 * iwl_add_station - Add station to tables in driver and device 218 * iwl_prep_station - Prepare station information for addition
219 *
220 * should be called with sta_lock held
267 */ 221 */
268u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 222static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
269 struct ieee80211_sta_ht_cap *ht_info) 223 bool is_ap,
224 struct ieee80211_sta_ht_cap *ht_info)
270{ 225{
271 struct iwl_station_entry *station; 226 struct iwl_station_entry *station;
272 unsigned long flags_spin;
273 int i; 227 int i;
274 int sta_id = IWL_INVALID_STATION; 228 u8 sta_id = IWL_INVALID_STATION;
275 u16 rate; 229 u16 rate;
276 230
277 spin_lock_irqsave(&priv->sta_lock, flags_spin);
278 if (is_ap) 231 if (is_ap)
279 sta_id = IWL_AP_ID; 232 sta_id = IWL_AP_ID;
280 else if (is_broadcast_ether_addr(addr)) 233 else if (is_broadcast_ether_addr(addr))
@@ -292,20 +245,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
292 sta_id = i; 245 sta_id = i;
293 } 246 }
294 247
295 /* These two conditions have the same outcome, but keep them separate 248 /*
296 since they have different meanings */ 249 * These two conditions have the same outcome, but keep them
297 if (unlikely(sta_id == IWL_INVALID_STATION)) { 250 * separate
298 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 251 */
252 if (unlikely(sta_id == IWL_INVALID_STATION))
253 return sta_id;
254
255 /*
256 * uCode is not able to deal with multiple requests to add a
257 * station. Keep track if one is in progress so that we do not send
258 * another.
259 */
260 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
261 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
262 sta_id);
299 return sta_id; 263 return sta_id;
300 } 264 }
301 265
302 if (priv->stations[sta_id].used && 266 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
267 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
303 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { 268 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
304 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 269 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
270 sta_id, addr);
305 return sta_id; 271 return sta_id;
306 } 272 }
307 273
308
309 station = &priv->stations[sta_id]; 274 station = &priv->stations[sta_id];
310 station->used = IWL_STA_DRIVER_ACTIVE; 275 station->used = IWL_STA_DRIVER_ACTIVE;
311 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", 276 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
@@ -319,10 +284,12 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
319 station->sta.sta.sta_id = sta_id; 284 station->sta.sta.sta_id = sta_id;
320 station->sta.station_flags = 0; 285 station->sta.station_flags = 0;
321 286
322 /* BCAST station and IBSS stations do not work in HT mode */ 287 /*
323 if (sta_id != priv->hw_params.bcast_sta_id && 288 * OK to call unconditionally, since local stations (IBSS BSSID
324 priv->iw_mode != NL80211_IFTYPE_ADHOC) 289 * STA and broadcast STA) pass in a NULL ht_info, and mac80211
325 iwl_set_ht_add_station(priv, sta_id, ht_info); 290 * doesn't allow HT IBSS.
291 */
292 iwl_set_ht_add_station(priv, sta_id, ht_info);
326 293
327 /* 3945 only */ 294 /* 3945 only */
328 rate = (priv->band == IEEE80211_BAND_5GHZ) ? 295 rate = (priv->band == IEEE80211_BAND_5GHZ) ?
@@ -330,86 +297,221 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
330 /* Turn on both antennas for the station... */ 297 /* Turn on both antennas for the station... */
331 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); 298 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
332 299
300 return sta_id;
301
302}
303
304#define STA_WAIT_TIMEOUT (HZ/2)
305
306/**
307 * iwl_add_station_common -
308 */
309int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
310 bool is_ap,
311 struct ieee80211_sta_ht_cap *ht_info,
312 u8 *sta_id_r)
313{
314 struct iwl_station_entry *station;
315 unsigned long flags_spin;
316 int ret = 0;
317 u8 sta_id;
318
319 *sta_id_r = 0;
320 spin_lock_irqsave(&priv->sta_lock, flags_spin);
321 sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
322 if (sta_id == IWL_INVALID_STATION) {
323 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
324 addr);
325 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
326 return -EINVAL;
327 }
328
329 /*
330 * uCode is not able to deal with multiple requests to add a
331 * station. Keep track if one is in progress so that we do not send
332 * another.
333 */
334 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
335 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
336 sta_id);
337 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
338 return -EEXIST;
339 }
340
341 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
342 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
343 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
344 sta_id, addr);
345 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
346 return -EEXIST;
347 }
348
349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
350 station = &priv->stations[sta_id];
333 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
334 352
335 /* Add station to device's station table */ 353 /* Add station to device's station table */
336 iwl_send_add_sta(priv, &station->sta, flags); 354 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC);
337 return sta_id; 355 if (ret) {
356 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
357 spin_lock_irqsave(&priv->sta_lock, flags_spin);
358 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
359 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
360 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
361 }
362 *sta_id_r = sta_id;
363 return ret;
364}
365EXPORT_SYMBOL(iwl_add_station_common);
366
367static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
368 u8 sta_id)
369{
370 int i, r;
371 struct iwl_link_quality_cmd *link_cmd;
372 u32 rate_flags;
373
374 link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
375 if (!link_cmd) {
376 IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
377 return NULL;
378 }
379 /* Set up the rate scaling to start at selected rate, fall back
380 * all the way down to 1M in IEEE order, and then spin on 1M */
381 if (priv->band == IEEE80211_BAND_5GHZ)
382 r = IWL_RATE_6M_INDEX;
383 else
384 r = IWL_RATE_1M_INDEX;
338 385
386 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
387 rate_flags = 0;
388 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
389 rate_flags |= RATE_MCS_CCK_MSK;
390
391 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
392 RATE_MCS_ANT_POS;
393
394 link_cmd->rs_table[i].rate_n_flags =
395 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
396 r = iwl_get_prev_ieee_rate(r);
397 }
398
399 link_cmd->general_params.single_stream_ant_msk =
400 first_antenna(priv->hw_params.valid_tx_ant);
401
402 link_cmd->general_params.dual_stream_ant_msk =
403 priv->hw_params.valid_tx_ant &
404 ~first_antenna(priv->hw_params.valid_tx_ant);
405 if (!link_cmd->general_params.dual_stream_ant_msk) {
406 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
407 } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
408 link_cmd->general_params.dual_stream_ant_msk =
409 priv->hw_params.valid_tx_ant;
410 }
411
412 link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
413 link_cmd->agg_params.agg_time_limit =
414 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
415
416 link_cmd->sta_id = sta_id;
417
418 return link_cmd;
339} 419}
340EXPORT_SYMBOL(iwl_add_station);
341 420
342static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr) 421/*
422 * iwl_add_bssid_station - Add the special IBSS BSSID station
423 *
424 * Function sleeps.
425 */
426int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
427 u8 *sta_id_r)
343{ 428{
429 int ret;
430 u8 sta_id;
431 struct iwl_link_quality_cmd *link_cmd;
344 unsigned long flags; 432 unsigned long flags;
345 u8 sta_id = iwl_find_station(priv, addr);
346 433
347 BUG_ON(sta_id == IWL_INVALID_STATION); 434 if (*sta_id_r)
435 *sta_id_r = IWL_INVALID_STATION;
348 436
349 IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr); 437 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
438 if (ret) {
439 IWL_ERR(priv, "Unable to add station %pM\n", addr);
440 return ret;
441 }
442
443 if (sta_id_r)
444 *sta_id_r = sta_id;
350 445
351 spin_lock_irqsave(&priv->sta_lock, flags); 446 spin_lock_irqsave(&priv->sta_lock, flags);
447 priv->stations[sta_id].used |= IWL_STA_LOCAL;
448 spin_unlock_irqrestore(&priv->sta_lock, flags);
352 449
353 /* Ucode must be active and driver must be non active */ 450 if (init_rs) {
354 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) 451 /* Set up default rate scaling table in device's station table */
355 IWL_ERR(priv, "removed non active STA %d\n", sta_id); 452 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
453 if (!link_cmd) {
454 IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
455 addr);
456 return -ENOMEM;
457 }
356 458
357 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; 459 ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
460 if (ret)
461 IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
358 462
359 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); 463 spin_lock_irqsave(&priv->sta_lock, flags);
360 spin_unlock_irqrestore(&priv->sta_lock, flags); 464 priv->stations[sta_id].lq = link_cmd;
465 spin_unlock_irqrestore(&priv->sta_lock, flags);
466 }
467
468 return 0;
361} 469}
470EXPORT_SYMBOL(iwl_add_bssid_station);
362 471
363static void iwl_remove_sta_callback(struct iwl_priv *priv, 472/**
364 struct iwl_device_cmd *cmd, 473 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
365 struct iwl_rx_packet *pkt) 474 *
475 * priv->sta_lock must be held
476 */
477static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
366{ 478{
367 struct iwl_rem_sta_cmd *rm_sta = 479 /* Ucode must be active and driver must be non active */
368 (struct iwl_rem_sta_cmd *)cmd->cmd.payload; 480 if ((priv->stations[sta_id].used &
369 const u8 *addr = rm_sta->addr; 481 (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != IWL_STA_UCODE_ACTIVE)
482 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
370 483
371 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 484 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
372 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
373 pkt->hdr.flags);
374 return;
375 }
376 485
377 switch (pkt->u.rem_sta.status) { 486 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
378 case REM_STA_SUCCESS_MSK: 487 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
379 iwl_sta_ucode_deactivate(priv, addr);
380 break;
381 default:
382 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
383 break;
384 }
385} 488}
386 489
387static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, 490static int iwl_send_remove_station(struct iwl_priv *priv,
388 u8 flags) 491 struct iwl_station_entry *station)
389{ 492{
390 struct iwl_rx_packet *pkt; 493 struct iwl_rx_packet *pkt;
391 int ret; 494 int ret;
392 495
496 unsigned long flags_spin;
393 struct iwl_rem_sta_cmd rm_sta_cmd; 497 struct iwl_rem_sta_cmd rm_sta_cmd;
394 498
395 struct iwl_host_cmd cmd = { 499 struct iwl_host_cmd cmd = {
396 .id = REPLY_REMOVE_STA, 500 .id = REPLY_REMOVE_STA,
397 .len = sizeof(struct iwl_rem_sta_cmd), 501 .len = sizeof(struct iwl_rem_sta_cmd),
398 .flags = flags, 502 .flags = CMD_SYNC,
399 .data = &rm_sta_cmd, 503 .data = &rm_sta_cmd,
400 }; 504 };
401 505
402 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 506 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
403 rm_sta_cmd.num_sta = 1; 507 rm_sta_cmd.num_sta = 1;
404 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 508 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN);
509
510 cmd.flags |= CMD_WANT_SKB;
405 511
406 if (flags & CMD_ASYNC)
407 cmd.callback = iwl_remove_sta_callback;
408 else
409 cmd.flags |= CMD_WANT_SKB;
410 ret = iwl_send_cmd(priv, &cmd); 512 ret = iwl_send_cmd(priv, &cmd);
411 513
412 if (ret || (flags & CMD_ASYNC)) 514 if (ret)
413 return ret; 515 return ret;
414 516
415 pkt = (struct iwl_rx_packet *)cmd.reply_page; 517 pkt = (struct iwl_rx_packet *)cmd.reply_page;
@@ -422,7 +524,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
422 if (!ret) { 524 if (!ret) {
423 switch (pkt->u.rem_sta.status) { 525 switch (pkt->u.rem_sta.status) {
424 case REM_STA_SUCCESS_MSK: 526 case REM_STA_SUCCESS_MSK:
425 iwl_sta_ucode_deactivate(priv, addr); 527 spin_lock_irqsave(&priv->sta_lock, flags_spin);
528 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id);
529 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
426 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 530 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
427 break; 531 break;
428 default: 532 default:
@@ -439,45 +543,48 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
439/** 543/**
440 * iwl_remove_station - Remove driver's knowledge of station. 544 * iwl_remove_station - Remove driver's knowledge of station.
441 */ 545 */
442int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) 546int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
547 const u8 *addr)
443{ 548{
444 int sta_id = IWL_INVALID_STATION; 549 struct iwl_station_entry *station;
445 int i, ret = -EINVAL;
446 unsigned long flags; 550 unsigned long flags;
447 551
448 spin_lock_irqsave(&priv->sta_lock, flags); 552 if (!iwl_is_ready(priv)) {
553 IWL_DEBUG_INFO(priv,
554 "Unable to remove station %pM, device not ready.\n",
555 addr);
556 /*
557 * It is typical for stations to be removed when we are
558 * going down. Return success since device will be down
559 * soon anyway
560 */
561 return 0;
562 }
449 563
450 if (is_ap) 564 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
451 sta_id = IWL_AP_ID; 565 sta_id, addr);
452 else if (is_broadcast_ether_addr(addr))
453 sta_id = priv->hw_params.bcast_sta_id;
454 else
455 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
456 if (priv->stations[i].used &&
457 !compare_ether_addr(priv->stations[i].sta.sta.addr,
458 addr)) {
459 sta_id = i;
460 break;
461 }
462 566
463 if (unlikely(sta_id == IWL_INVALID_STATION)) 567 if (WARN_ON(sta_id == IWL_INVALID_STATION))
464 goto out; 568 return -EINVAL;
465 569
466 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 570 spin_lock_irqsave(&priv->sta_lock, flags);
467 sta_id, addr);
468 571
469 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 572 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
470 IWL_ERR(priv, "Removing %pM but non DRIVER active\n", 573 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
471 addr); 574 addr);
472 goto out; 575 goto out_err;
473 } 576 }
474 577
475 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 578 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
476 IWL_ERR(priv, "Removing %pM but non UCODE active\n", 579 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
477 addr); 580 addr);
478 goto out; 581 goto out_err;
479 } 582 }
480 583
584 if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
585 kfree(priv->stations[sta_id].lq);
586 priv->stations[sta_id].lq = NULL;
587 }
481 588
482 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 589 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
483 590
@@ -485,47 +592,112 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
485 592
486 BUG_ON(priv->num_stations < 0); 593 BUG_ON(priv->num_stations < 0);
487 594
595 station = &priv->stations[sta_id];
488 spin_unlock_irqrestore(&priv->sta_lock, flags); 596 spin_unlock_irqrestore(&priv->sta_lock, flags);
489 597
490 ret = iwl_send_remove_station(priv, addr, CMD_ASYNC); 598 return iwl_send_remove_station(priv, station);
491 return ret; 599out_err:
492out:
493 spin_unlock_irqrestore(&priv->sta_lock, flags); 600 spin_unlock_irqrestore(&priv->sta_lock, flags);
494 return ret; 601 return -EINVAL;
495} 602}
603EXPORT_SYMBOL_GPL(iwl_remove_station);
496 604
497/** 605/**
498 * iwl_clear_stations_table - Clear the driver's station table 606 * iwl_clear_ucode_stations - clear ucode station table bits
499 * 607 *
500 * NOTE: This does not clear or otherwise alter the device's station table. 608 * This function clears all the bits in the driver indicating
609 * which stations are active in the ucode. Call when something
610 * other than explicit station management would cause this in
611 * the ucode, e.g. unassociated RXON.
501 */ 612 */
502void iwl_clear_stations_table(struct iwl_priv *priv) 613void iwl_clear_ucode_stations(struct iwl_priv *priv)
503{ 614{
504 unsigned long flags;
505 int i; 615 int i;
616 unsigned long flags_spin;
617 bool cleared = false;
506 618
507 spin_lock_irqsave(&priv->sta_lock, flags); 619 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
508 620
509 if (iwl_is_alive(priv) && 621 spin_lock_irqsave(&priv->sta_lock, flags_spin);
510 !test_bit(STATUS_EXIT_PENDING, &priv->status) && 622 for (i = 0; i < priv->hw_params.max_stations; i++) {
511 iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) 623 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
512 IWL_ERR(priv, "Couldn't clear the station table\n"); 624 IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
625 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
626 cleared = true;
627 }
628 }
629 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
630
631 if (!cleared)
632 IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
633}
634EXPORT_SYMBOL(iwl_clear_ucode_stations);
635
636/**
637 * iwl_restore_stations() - Restore driver known stations to device
638 *
639 * All stations considered active by driver, but not present in ucode, is
640 * restored.
641 *
642 * Function sleeps.
643 */
644void iwl_restore_stations(struct iwl_priv *priv)
645{
646 struct iwl_station_entry *station;
647 unsigned long flags_spin;
648 int i;
649 bool found = false;
650 int ret;
513 651
514 priv->num_stations = 0; 652 if (!iwl_is_ready(priv)) {
515 memset(priv->stations, 0, sizeof(priv->stations)); 653 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
654 return;
655 }
516 656
517 /* clean ucode key table bit map */ 657 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
518 priv->ucode_key_table = 0; 658 spin_lock_irqsave(&priv->sta_lock, flags_spin);
659 for (i = 0; i < priv->hw_params.max_stations; i++) {
660 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
661 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
662 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
663 priv->stations[i].sta.sta.addr);
664 priv->stations[i].sta.mode = 0;
665 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
666 found = true;
667 }
668 }
519 669
520 /* keep track of static keys */ 670 for (i = 0; i < priv->hw_params.max_stations; i++) {
521 for (i = 0; i < WEP_KEYS_MAX ; i++) { 671 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
522 if (priv->wep_keys[i].key_size) 672 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
523 set_bit(i, &priv->ucode_key_table); 673 station = &priv->stations[i];
674 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
675 if (ret) {
676 IWL_ERR(priv, "Adding station %pM failed.\n",
677 station->sta.sta.addr);
678 spin_lock_irqsave(&priv->sta_lock, flags_spin);
679 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
680 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
682 }
683 /*
684 * Rate scaling has already been initialized, send
685 * current LQ command
686 */
687 if (station->lq)
688 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true);
689 spin_lock_irqsave(&priv->sta_lock, flags_spin);
690 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
691 }
524 } 692 }
525 693
526 spin_unlock_irqrestore(&priv->sta_lock, flags); 694 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
695 if (!found)
696 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
697 else
698 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
527} 699}
528EXPORT_SYMBOL(iwl_clear_stations_table); 700EXPORT_SYMBOL(iwl_restore_stations);
529 701
530int iwl_get_free_ucode_key_index(struct iwl_priv *priv) 702int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
531{ 703{
@@ -539,7 +711,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
539} 711}
540EXPORT_SYMBOL(iwl_get_free_ucode_key_index); 712EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
541 713
542int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) 714static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
543{ 715{
544 int i, not_empty = 0; 716 int i, not_empty = 0;
545 u8 buff[sizeof(struct iwl_wep_cmd) + 717 u8 buff[sizeof(struct iwl_wep_cmd) +
@@ -549,9 +721,11 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
549 struct iwl_host_cmd cmd = { 721 struct iwl_host_cmd cmd = {
550 .id = REPLY_WEPKEY, 722 .id = REPLY_WEPKEY,
551 .data = wep_cmd, 723 .data = wep_cmd,
552 .flags = CMD_ASYNC, 724 .flags = CMD_SYNC,
553 }; 725 };
554 726
727 might_sleep();
728
555 memset(wep_cmd, 0, cmd_size + 729 memset(wep_cmd, 0, cmd_size +
556 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); 730 (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX));
557 731
@@ -581,33 +755,34 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
581 else 755 else
582 return 0; 756 return 0;
583} 757}
584EXPORT_SYMBOL(iwl_send_static_wepkey_cmd); 758
759int iwl_restore_default_wep_keys(struct iwl_priv *priv)
760{
761 WARN_ON(!mutex_is_locked(&priv->mutex));
762
763 return iwl_send_static_wepkey_cmd(priv, 0);
764}
765EXPORT_SYMBOL(iwl_restore_default_wep_keys);
585 766
586int iwl_remove_default_wep_key(struct iwl_priv *priv, 767int iwl_remove_default_wep_key(struct iwl_priv *priv,
587 struct ieee80211_key_conf *keyconf) 768 struct ieee80211_key_conf *keyconf)
588{ 769{
589 int ret; 770 int ret;
590 unsigned long flags;
591 771
592 spin_lock_irqsave(&priv->sta_lock, flags); 772 WARN_ON(!mutex_is_locked(&priv->mutex));
773
593 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", 774 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
594 keyconf->keyidx); 775 keyconf->keyidx);
595 776
596 if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
597 IWL_ERR(priv, "index %d not used in uCode key table.\n",
598 keyconf->keyidx);
599
600 priv->default_wep_key--;
601 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); 777 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
602 if (iwl_is_rfkill(priv)) { 778 if (iwl_is_rfkill(priv)) {
603 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); 779 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
604 spin_unlock_irqrestore(&priv->sta_lock, flags); 780 /* but keys in device are clear anyway so return success */
605 return 0; 781 return 0;
606 } 782 }
607 ret = iwl_send_static_wepkey_cmd(priv, 1); 783 ret = iwl_send_static_wepkey_cmd(priv, 1);
608 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", 784 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
609 keyconf->keyidx, ret); 785 keyconf->keyidx, ret);
610 spin_unlock_irqrestore(&priv->sta_lock, flags);
611 786
612 return ret; 787 return ret;
613} 788}
@@ -617,7 +792,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
617 struct ieee80211_key_conf *keyconf) 792 struct ieee80211_key_conf *keyconf)
618{ 793{
619 int ret; 794 int ret;
620 unsigned long flags; 795
796 WARN_ON(!mutex_is_locked(&priv->mutex));
621 797
622 if (keyconf->keylen != WEP_KEY_LEN_128 && 798 if (keyconf->keylen != WEP_KEY_LEN_128 &&
623 keyconf->keylen != WEP_KEY_LEN_64) { 799 keyconf->keylen != WEP_KEY_LEN_64) {
@@ -629,13 +805,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
629 keyconf->hw_key_idx = HW_KEY_DEFAULT; 805 keyconf->hw_key_idx = HW_KEY_DEFAULT;
630 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; 806 priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
631 807
632 spin_lock_irqsave(&priv->sta_lock, flags);
633 priv->default_wep_key++;
634
635 if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
636 IWL_ERR(priv, "index %d already used in uCode key table.\n",
637 keyconf->keyidx);
638
639 priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; 808 priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
640 memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, 809 memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
641 keyconf->keylen); 810 keyconf->keylen);
@@ -643,7 +812,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
643 ret = iwl_send_static_wepkey_cmd(priv, 0); 812 ret = iwl_send_static_wepkey_cmd(priv, 0);
644 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", 813 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
645 keyconf->keylen, keyconf->keyidx, ret); 814 keyconf->keylen, keyconf->keyidx, ret);
646 spin_unlock_irqrestore(&priv->sta_lock, flags);
647 815
648 return ret; 816 return ret;
649} 817}
@@ -798,18 +966,23 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
798 966
799void iwl_update_tkip_key(struct iwl_priv *priv, 967void iwl_update_tkip_key(struct iwl_priv *priv,
800 struct ieee80211_key_conf *keyconf, 968 struct ieee80211_key_conf *keyconf,
801 const u8 *addr, u32 iv32, u16 *phase1key) 969 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
802{ 970{
803 u8 sta_id = IWL_INVALID_STATION; 971 u8 sta_id;
804 unsigned long flags; 972 unsigned long flags;
805 int i; 973 int i;
806 974
807 sta_id = iwl_find_station(priv, addr); 975 if (sta) {
808 if (sta_id == IWL_INVALID_STATION) { 976 sta_id = iwl_sta_id(sta);
809 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 977
810 addr); 978 if (sta_id == IWL_INVALID_STATION) {
811 return; 979 IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
812 } 980 sta->addr);
981 return;
982 }
983 } else
984 sta_id = priv->hw_params.bcast_sta_id;
985
813 986
814 if (iwl_scan_cancel(priv)) { 987 if (iwl_scan_cancel(priv)) {
815 /* cancel scan failed, just live w/ bad key and rely 988 /* cancel scan failed, just live w/ bad key and rely
@@ -885,7 +1058,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
885 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1058 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
886 1059
887 if (iwl_is_rfkill(priv)) { 1060 if (iwl_is_rfkill(priv)) {
888 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n"); 1061 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
889 spin_unlock_irqrestore(&priv->sta_lock, flags); 1062 spin_unlock_irqrestore(&priv->sta_lock, flags);
890 return 0; 1063 return 0;
891 } 1064 }
@@ -948,253 +1121,149 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
948} 1121}
949#endif 1122#endif
950 1123
951int iwl_send_lq_cmd(struct iwl_priv *priv,
952 struct iwl_link_quality_cmd *lq, u8 flags)
953{
954 struct iwl_host_cmd cmd = {
955 .id = REPLY_TX_LINK_QUALITY_CMD,
956 .len = sizeof(struct iwl_link_quality_cmd),
957 .flags = flags,
958 .data = lq,
959 };
960
961 if ((lq->sta_id == 0xFF) &&
962 (priv->iw_mode == NL80211_IFTYPE_ADHOC))
963 return -EINVAL;
964
965 if (lq->sta_id == 0xFF)
966 lq->sta_id = IWL_AP_ID;
967
968 iwl_dump_lq_cmd(priv, lq);
969
970 if (iwl_is_associated(priv) && priv->assoc_station_added)
971 return iwl_send_cmd(priv, &cmd);
972
973 return 0;
974}
975EXPORT_SYMBOL(iwl_send_lq_cmd);
976
977/** 1124/**
978 * iwl_sta_init_lq - Initialize a station's hardware rate table 1125 * is_lq_table_valid() - Test one aspect of LQ cmd for validity
979 *
980 * The uCode's station table contains a table of fallback rates
981 * for automatic fallback during transmission.
982 *
983 * NOTE: This sets up a default set of values. These will be replaced later
984 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
985 * rc80211_simple.
986 * 1126 *
987 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before 1127 * It sometimes happens when a HT rate has been in use and we
988 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, 1128 * loose connectivity with AP then mac80211 will first tell us that the
989 * which requires station table entry to exist). 1129 * current channel is not HT anymore before removing the station. In such a
1130 * scenario the RXON flags will be updated to indicate we are not
1131 * communicating HT anymore, but the LQ command may still contain HT rates.
1132 * Test for this to prevent driver from sending LQ command between the time
1133 * RXON flags are updated and when LQ command is updated.
990 */ 1134 */
991static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap) 1135static bool is_lq_table_valid(struct iwl_priv *priv,
1136 struct iwl_link_quality_cmd *lq)
992{ 1137{
993 int i, r; 1138 int i;
994 struct iwl_link_quality_cmd link_cmd = { 1139 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
995 .reserved1 = 0,
996 };
997 u32 rate_flags;
998 1140
999 /* Set up the rate scaling to start at selected rate, fall back 1141 if (ht_conf->is_ht)
1000 * all the way down to 1M in IEEE order, and then spin on 1M */ 1142 return true;
1001 if (is_ap)
1002 r = IWL_RATE_54M_INDEX;
1003 else if (priv->band == IEEE80211_BAND_5GHZ)
1004 r = IWL_RATE_6M_INDEX;
1005 else
1006 r = IWL_RATE_1M_INDEX;
1007 1143
1144 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
1145 priv->active_rxon.channel);
1008 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 1146 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1009 rate_flags = 0; 1147 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
1010 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) 1148 IWL_DEBUG_INFO(priv,
1011 rate_flags |= RATE_MCS_CCK_MSK; 1149 "index %d of LQ expects HT channel\n",
1012 1150 i);
1013 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << 1151 return false;
1014 RATE_MCS_ANT_POS; 1152 }
1015
1016 link_cmd.rs_table[i].rate_n_flags =
1017 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1018 r = iwl_get_prev_ieee_rate(r);
1019 } 1153 }
1020 1154 return true;
1021 link_cmd.general_params.single_stream_ant_msk =
1022 first_antenna(priv->hw_params.valid_tx_ant);
1023 link_cmd.general_params.dual_stream_ant_msk = 3;
1024 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1025 link_cmd.agg_params.agg_time_limit =
1026 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1027
1028 /* Update the rate scaling for control frame Tx to AP */
1029 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
1030
1031 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1032 sizeof(link_cmd), &link_cmd, NULL);
1033} 1155}
1034 1156
1035/** 1157/**
1036 * iwl_rxon_add_station - add station into station table. 1158 * iwl_send_lq_cmd() - Send link quality command
1159 * @init: This command is sent as part of station initialization right
1160 * after station has been added.
1037 * 1161 *
1038 * there is only one AP station with id= IWL_AP_ID 1162 * The link quality command is sent as the last step of station creation.
1039 * NOTE: mutex must be held before calling this function 1163 * This is the special case in which init is set and we call a callback in
1164 * this case to clear the state indicating that station creation is in
1165 * progress.
1040 */ 1166 */
1041int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) 1167int iwl_send_lq_cmd(struct iwl_priv *priv,
1168 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
1042{ 1169{
1043 struct ieee80211_sta *sta; 1170 int ret = 0;
1044 struct ieee80211_sta_ht_cap ht_config; 1171 unsigned long flags_spin;
1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1046 u8 sta_id;
1047 1172
1048 /* 1173 struct iwl_host_cmd cmd = {
1049 * Set HT capabilities. It is ok to set this struct even if not using 1174 .id = REPLY_TX_LINK_QUALITY_CMD,
1050 * HT config: the priv->current_ht_config.is_ht flag will just be false 1175 .len = sizeof(struct iwl_link_quality_cmd),
1051 */ 1176 .flags = flags,
1052 rcu_read_lock(); 1177 .data = lq,
1053 sta = ieee80211_find_sta(priv->vif, addr); 1178 };
1054 if (sta) {
1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1056 cur_ht_config = &ht_config;
1057 }
1058 rcu_read_unlock();
1059 1179
1060 /* Add station to device's station table */ 1180 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); 1181 return -EINVAL;
1062 1182
1063 /* Set up default rate scaling table in device's station table */ 1183 iwl_dump_lq_cmd(priv, lq);
1064 iwl_sta_init_lq(priv, addr, is_ap); 1184 BUG_ON(init && (cmd.flags & CMD_ASYNC));
1065 1185
1066 return sta_id; 1186 if (is_lq_table_valid(priv, lq))
1187 ret = iwl_send_cmd(priv, &cmd);
1188 else
1189 ret = -EINVAL;
1190
1191 if (cmd.flags & CMD_ASYNC)
1192 return ret;
1193
1194 if (init) {
1195 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d\n",
1196 lq->sta_id);
1197 spin_lock_irqsave(&priv->sta_lock, flags_spin);
1198 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1199 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
1200 }
1201 return ret;
1067} 1202}
1068EXPORT_SYMBOL(iwl_rxon_add_station); 1203EXPORT_SYMBOL(iwl_send_lq_cmd);
1069 1204
1070/** 1205/**
1071 * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table 1206 * iwl_alloc_bcast_station - add broadcast station into driver's station table.
1072 * 1207 *
1073 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before 1208 * This adds the broadcast station into the driver's station table
1074 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, 1209 * and marks it driver active, so that it will be restored to the
1075 * which requires station table entry to exist). 1210 * device at the next best time.
1076 */ 1211 */
1077static void iwl_sta_init_bcast_lq(struct iwl_priv *priv) 1212int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq)
1078{ 1213{
1079 int i, r; 1214 struct iwl_link_quality_cmd *link_cmd;
1080 struct iwl_link_quality_cmd link_cmd = { 1215 unsigned long flags;
1081 .reserved1 = 0, 1216 u8 sta_id;
1082 };
1083 u32 rate_flags;
1084
1085 /* Set up the rate scaling to start at selected rate, fall back
1086 * all the way down to 1M in IEEE order, and then spin on 1M */
1087 if (priv->band == IEEE80211_BAND_5GHZ)
1088 r = IWL_RATE_6M_INDEX;
1089 else
1090 r = IWL_RATE_1M_INDEX;
1091
1092 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1093 rate_flags = 0;
1094 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1095 rate_flags |= RATE_MCS_CCK_MSK;
1096 1217
1097 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << 1218 spin_lock_irqsave(&priv->sta_lock, flags);
1098 RATE_MCS_ANT_POS; 1219 sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL);
1220 if (sta_id == IWL_INVALID_STATION) {
1221 IWL_ERR(priv, "Unable to prepare broadcast station\n");
1222 spin_unlock_irqrestore(&priv->sta_lock, flags);
1099 1223
1100 link_cmd.rs_table[i].rate_n_flags = 1224 return -EINVAL;
1101 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1102 r = iwl_get_prev_ieee_rate(r);
1103 } 1225 }
1104 1226
1105 link_cmd.general_params.single_stream_ant_msk = 1227 priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
1106 first_antenna(priv->hw_params.valid_tx_ant); 1228 priv->stations[sta_id].used |= IWL_STA_BCAST;
1107 link_cmd.general_params.dual_stream_ant_msk = 3; 1229 spin_unlock_irqrestore(&priv->sta_lock, flags);
1108 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1109 link_cmd.agg_params.agg_time_limit =
1110 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1111
1112 /* Update the rate scaling for control frame Tx to AP */
1113 link_cmd.sta_id = priv->hw_params.bcast_sta_id;
1114
1115 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1116 sizeof(link_cmd), &link_cmd, NULL);
1117}
1118
1119 1230
1120/** 1231 if (init_lq) {
1121 * iwl_add_bcast_station - add broadcast station into station table. 1232 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
1122 */ 1233 if (!link_cmd) {
1123void iwl_add_bcast_station(struct iwl_priv *priv) 1234 IWL_ERR(priv,
1124{ 1235 "Unable to initialize rate scaling for bcast station.\n");
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1236 return -ENOMEM;
1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1237 }
1127 1238
1128 /* Set up default rate scaling table in device's station table */ 1239 spin_lock_irqsave(&priv->sta_lock, flags);
1129 iwl_sta_init_bcast_lq(priv); 1240 priv->stations[sta_id].lq = link_cmd;
1130} 1241 spin_unlock_irqrestore(&priv->sta_lock, flags);
1131EXPORT_SYMBOL(iwl_add_bcast_station); 1242 }
1132 1243
1133/** 1244 return 0;
1134 * iwl3945_add_bcast_station - add broadcast station into station table.
1135 */
1136void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1140} 1245}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station); 1246EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
1142 1247
1143/** 1248void iwl_dealloc_bcast_station(struct iwl_priv *priv)
1144 * iwl_get_sta_id - Find station's index within station table
1145 *
1146 * If new IBSS station, create new entry in station table
1147 */
1148int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1149{ 1249{
1150 int sta_id; 1250 unsigned long flags;
1151 __le16 fc = hdr->frame_control; 1251 int i;
1152
1153 /* If this frame is broadcast or management, use broadcast station id */
1154 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
1155 return priv->hw_params.bcast_sta_id;
1156
1157 switch (priv->iw_mode) {
1158
1159 /* If we are a client station in a BSS network, use the special
1160 * AP station entry (that's the only station we communicate with) */
1161 case NL80211_IFTYPE_STATION:
1162 return IWL_AP_ID;
1163
1164 /* If we are an AP, then find the station, or use BCAST */
1165 case NL80211_IFTYPE_AP:
1166 sta_id = iwl_find_station(priv, hdr->addr1);
1167 if (sta_id != IWL_INVALID_STATION)
1168 return sta_id;
1169 return priv->hw_params.bcast_sta_id;
1170
1171 /* If this frame is going out to an IBSS network, find the station,
1172 * or create a new station table entry */
1173 case NL80211_IFTYPE_ADHOC:
1174 sta_id = iwl_find_station(priv, hdr->addr1);
1175 if (sta_id != IWL_INVALID_STATION)
1176 return sta_id;
1177
1178 /* Create new station table entry */
1179 sta_id = iwl_add_station(priv, hdr->addr1, false,
1180 CMD_ASYNC, NULL);
1181
1182 if (sta_id != IWL_INVALID_STATION)
1183 return sta_id;
1184
1185 IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
1186 "Defaulting to broadcast...\n",
1187 hdr->addr1);
1188 iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
1189 return priv->hw_params.bcast_sta_id;
1190 1252
1191 default: 1253 spin_lock_irqsave(&priv->sta_lock, flags);
1192 IWL_WARN(priv, "Unknown mode of operation: %d\n", 1254 for (i = 0; i < priv->hw_params.max_stations; i++) {
1193 priv->iw_mode); 1255 if (!(priv->stations[i].used & IWL_STA_BCAST))
1194 return priv->hw_params.bcast_sta_id; 1256 continue;
1257
1258 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
1259 priv->num_stations--;
1260 BUG_ON(priv->num_stations < 0);
1261 kfree(priv->stations[i].lq);
1262 priv->stations[i].lq = NULL;
1195 } 1263 }
1264 spin_unlock_irqrestore(&priv->sta_lock, flags);
1196} 1265}
1197EXPORT_SYMBOL(iwl_get_sta_id); 1266EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);
1198 1267
1199/** 1268/**
1200 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table 1269 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
@@ -1214,13 +1283,13 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1214} 1283}
1215EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1284EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1216 1285
1217int iwl_sta_rx_agg_start(struct iwl_priv *priv, 1286int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
1218 const u8 *addr, int tid, u16 ssn) 1287 int tid, u16 ssn)
1219{ 1288{
1220 unsigned long flags; 1289 unsigned long flags;
1221 int sta_id; 1290 int sta_id;
1222 1291
1223 sta_id = iwl_find_station(priv, addr); 1292 sta_id = iwl_sta_id(sta);
1224 if (sta_id == IWL_INVALID_STATION) 1293 if (sta_id == IWL_INVALID_STATION)
1225 return -ENXIO; 1294 return -ENXIO;
1226 1295
@@ -1233,16 +1302,17 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
1233 spin_unlock_irqrestore(&priv->sta_lock, flags); 1302 spin_unlock_irqrestore(&priv->sta_lock, flags);
1234 1303
1235 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1304 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
1236 CMD_ASYNC); 1305 CMD_ASYNC);
1237} 1306}
1238EXPORT_SYMBOL(iwl_sta_rx_agg_start); 1307EXPORT_SYMBOL(iwl_sta_rx_agg_start);
1239 1308
1240int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid) 1309int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1310 int tid)
1241{ 1311{
1242 unsigned long flags; 1312 unsigned long flags;
1243 int sta_id; 1313 int sta_id;
1244 1314
1245 sta_id = iwl_find_station(priv, addr); 1315 sta_id = iwl_sta_id(sta);
1246 if (sta_id == IWL_INVALID_STATION) { 1316 if (sta_id == IWL_INVALID_STATION) {
1247 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); 1317 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1248 return -ENXIO; 1318 return -ENXIO;
@@ -1291,3 +1361,22 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1291 1361
1292 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1362 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1293} 1363}
1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1365
1366int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1367 struct ieee80211_vif *vif,
1368 struct ieee80211_sta *sta)
1369{
1370 struct iwl_priv *priv = hw->priv;
1371 struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
1372 int ret;
1373
1374 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
1375 sta->addr);
1376 ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
1377 if (ret)
1378 IWL_ERR(priv, "Error removing station %pM\n",
1379 sta->addr);
1380 return ret;
1381}
1382EXPORT_SYMBOL(iwl_mac_sta_remove);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 2dc35fe28f56..c2a453a1a991 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -29,44 +29,82 @@
29#ifndef __iwl_sta_h__ 29#ifndef __iwl_sta_h__
30#define __iwl_sta_h__ 30#define __iwl_sta_h__
31 31
32#include "iwl-dev.h"
33
32#define HW_KEY_DYNAMIC 0 34#define HW_KEY_DYNAMIC 0
33#define HW_KEY_DEFAULT 1 35#define HW_KEY_DEFAULT 1
34 36
35/** 37#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
36 * iwl_find_station - Find station id for a given BSSID 38#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
37 * @bssid: MAC address of station ID to find 39#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
38 */ 40 being activated */
39u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid); 41#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211;
42 (this is for the IBSS BSSID stations) */
43#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */
44
40 45
41int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);
42int iwl_remove_default_wep_key(struct iwl_priv *priv, 46int iwl_remove_default_wep_key(struct iwl_priv *priv,
43 struct ieee80211_key_conf *key); 47 struct ieee80211_key_conf *key);
44int iwl_set_default_wep_key(struct iwl_priv *priv, 48int iwl_set_default_wep_key(struct iwl_priv *priv,
45 struct ieee80211_key_conf *key); 49 struct ieee80211_key_conf *key);
50int iwl_restore_default_wep_keys(struct iwl_priv *priv);
46int iwl_set_dynamic_key(struct iwl_priv *priv, 51int iwl_set_dynamic_key(struct iwl_priv *priv,
47 struct ieee80211_key_conf *key, u8 sta_id); 52 struct ieee80211_key_conf *key, u8 sta_id);
48int iwl_remove_dynamic_key(struct iwl_priv *priv, 53int iwl_remove_dynamic_key(struct iwl_priv *priv,
49 struct ieee80211_key_conf *key, u8 sta_id); 54 struct ieee80211_key_conf *key, u8 sta_id);
50void iwl_update_tkip_key(struct iwl_priv *priv, 55void iwl_update_tkip_key(struct iwl_priv *priv,
51 struct ieee80211_key_conf *keyconf, 56 struct ieee80211_key_conf *keyconf,
52 const u8 *addr, u32 iv32, u16 *phase1key); 57 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
53 58
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 59void iwl_restore_stations(struct iwl_priv *priv);
55void iwl_add_bcast_station(struct iwl_priv *priv); 60void iwl_clear_ucode_stations(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv); 61int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq);
57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 62void iwl_dealloc_bcast_station(struct iwl_priv *priv);
58void iwl_clear_stations_table(struct iwl_priv *priv);
59int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 63int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
60int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
61int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
62int iwl_send_add_sta(struct iwl_priv *priv, 64int iwl_send_add_sta(struct iwl_priv *priv,
63 struct iwl_addsta_cmd *sta, u8 flags); 65 struct iwl_addsta_cmd *sta, u8 flags);
64u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 66int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
65 struct ieee80211_sta_ht_cap *ht_info); 67 u8 *sta_id_r);
68int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
69 bool is_ap,
70 struct ieee80211_sta_ht_cap *ht_info,
71 u8 *sta_id_r);
72int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
73 const u8 *addr);
74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
75 struct ieee80211_sta *sta);
66void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
67int iwl_sta_rx_agg_start(struct iwl_priv *priv, 77int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
68 const u8 *addr, int tid, u16 ssn); 78 int tid, u16 ssn);
69int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid); 79int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
80 int tid);
70void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); 81void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
71void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); 82void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
83
84/**
85 * iwl_clear_driver_stations - clear knowledge of all stations from driver
86 * @priv: iwl priv struct
87 *
88 * This is called during iwl_down() to make sure that in the case
89 * we're coming there from a hardware restart mac80211 will be
90 * able to reconfigure stations -- if we're getting there in the
91 * normal down flow then the stations will already be cleared.
92 */
93static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
94{
95 unsigned long flags;
96
97 spin_lock_irqsave(&priv->sta_lock, flags);
98 memset(priv->stations, 0, sizeof(priv->stations));
99 priv->num_stations = 0;
100 spin_unlock_irqrestore(&priv->sta_lock, flags);
101}
102
103static inline int iwl_sta_id(struct ieee80211_sta *sta)
104{
105 if (WARN_ON(!sta))
106 return IWL_INVALID_STATION;
107
108 return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
109}
72#endif /* __iwl_sta_h__ */ 110#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 8dd0c036d547..1ece2ea09773 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -38,47 +38,6 @@
38#include "iwl-io.h" 38#include "iwl-io.h"
39#include "iwl-helpers.h" 39#include "iwl-helpers.h"
40 40
41static const u16 default_tid_to_tx_fifo[] = {
42 IWL_TX_FIFO_AC1,
43 IWL_TX_FIFO_AC0,
44 IWL_TX_FIFO_AC0,
45 IWL_TX_FIFO_AC1,
46 IWL_TX_FIFO_AC2,
47 IWL_TX_FIFO_AC2,
48 IWL_TX_FIFO_AC3,
49 IWL_TX_FIFO_AC3,
50 IWL_TX_FIFO_NONE,
51 IWL_TX_FIFO_NONE,
52 IWL_TX_FIFO_NONE,
53 IWL_TX_FIFO_NONE,
54 IWL_TX_FIFO_NONE,
55 IWL_TX_FIFO_NONE,
56 IWL_TX_FIFO_NONE,
57 IWL_TX_FIFO_NONE,
58 IWL_TX_FIFO_AC3
59};
60
61static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
62 struct iwl_dma_ptr *ptr, size_t size)
63{
64 ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,
65 GFP_KERNEL);
66 if (!ptr->addr)
67 return -ENOMEM;
68 ptr->size = size;
69 return 0;
70}
71
72static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
73 struct iwl_dma_ptr *ptr)
74{
75 if (unlikely(!ptr->addr))
76 return;
77
78 dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
79 memset(ptr, 0, sizeof(*ptr));
80}
81
82/** 41/**
83 * iwl_txq_update_write_ptr - Send new write index to hardware 42 * iwl_txq_update_write_ptr - Send new write index to hardware
84 */ 43 */
@@ -310,6 +269,8 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
310 q->high_mark = 2; 269 q->high_mark = 2;
311 270
312 q->write_ptr = q->read_ptr = 0; 271 q->write_ptr = q->read_ptr = 0;
272 q->last_read_ptr = 0;
273 q->repeat_same_read_ptr = 0;
313 274
314 return 0; 275 return 0;
315} 276}
@@ -454,611 +415,6 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
454} 415}
455EXPORT_SYMBOL(iwl_tx_queue_reset); 416EXPORT_SYMBOL(iwl_tx_queue_reset);
456 417
457/**
458 * iwl_hw_txq_ctx_free - Free TXQ Context
459 *
460 * Destroy all TX DMA queues and structures
461 */
462void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
463{
464 int txq_id;
465
466 /* Tx queues */
467 if (priv->txq) {
468 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
469 if (txq_id == IWL_CMD_QUEUE_NUM)
470 iwl_cmd_queue_free(priv);
471 else
472 iwl_tx_queue_free(priv, txq_id);
473 }
474 iwl_free_dma_ptr(priv, &priv->kw);
475
476 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
477
478 /* free tx queue structure */
479 iwl_free_txq_mem(priv);
480}
481EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
482
483/**
484 * iwl_txq_ctx_alloc - allocate TX queue context
485 * Allocate all Tx DMA structures and initialize them
486 *
487 * @param priv
488 * @return error code
489 */
490int iwl_txq_ctx_alloc(struct iwl_priv *priv)
491{
492 int ret;
493 int txq_id, slots_num;
494 unsigned long flags;
495
496 /* Free all tx/cmd queues and keep-warm buffer */
497 iwl_hw_txq_ctx_free(priv);
498
499 ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
500 priv->hw_params.scd_bc_tbls_size);
501 if (ret) {
502 IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
503 goto error_bc_tbls;
504 }
505 /* Alloc keep-warm buffer */
506 ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
507 if (ret) {
508 IWL_ERR(priv, "Keep Warm allocation failed\n");
509 goto error_kw;
510 }
511
512 /* allocate tx queue structure */
513 ret = iwl_alloc_txq_mem(priv);
514 if (ret)
515 goto error;
516
517 spin_lock_irqsave(&priv->lock, flags);
518
519 /* Turn off all Tx DMA fifos */
520 priv->cfg->ops->lib->txq_set_sched(priv, 0);
521
522 /* Tell NIC where to find the "keep warm" buffer */
523 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
524
525 spin_unlock_irqrestore(&priv->lock, flags);
526
527 /* Alloc and init all Tx queues, including the command queue (#4) */
528 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
529 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
530 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
531 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
532 txq_id);
533 if (ret) {
534 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
535 goto error;
536 }
537 }
538
539 return ret;
540
541 error:
542 iwl_hw_txq_ctx_free(priv);
543 iwl_free_dma_ptr(priv, &priv->kw);
544 error_kw:
545 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
546 error_bc_tbls:
547 return ret;
548}
549
550void iwl_txq_ctx_reset(struct iwl_priv *priv)
551{
552 int txq_id, slots_num;
553 unsigned long flags;
554
555 spin_lock_irqsave(&priv->lock, flags);
556
557 /* Turn off all Tx DMA fifos */
558 priv->cfg->ops->lib->txq_set_sched(priv, 0);
559
560 /* Tell NIC where to find the "keep warm" buffer */
561 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
562
563 spin_unlock_irqrestore(&priv->lock, flags);
564
565 /* Alloc and init all Tx queues, including the command queue (#4) */
566 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
567 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
568 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
569 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
570 }
571}
572
573/**
574 * iwl_txq_ctx_stop - Stop all Tx DMA channels
575 */
576void iwl_txq_ctx_stop(struct iwl_priv *priv)
577{
578 int ch;
579 unsigned long flags;
580
581 /* Turn off all Tx DMA fifos */
582 spin_lock_irqsave(&priv->lock, flags);
583
584 priv->cfg->ops->lib->txq_set_sched(priv, 0);
585
586 /* Stop each Tx DMA channel, and wait for it to be idle */
587 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
588 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
589 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
590 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
591 1000);
592 }
593 spin_unlock_irqrestore(&priv->lock, flags);
594}
595EXPORT_SYMBOL(iwl_txq_ctx_stop);
596
597/*
598 * handle build REPLY_TX command notification.
599 */
600static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
601 struct iwl_tx_cmd *tx_cmd,
602 struct ieee80211_tx_info *info,
603 struct ieee80211_hdr *hdr,
604 u8 std_id)
605{
606 __le16 fc = hdr->frame_control;
607 __le32 tx_flags = tx_cmd->tx_flags;
608
609 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
610 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
611 tx_flags |= TX_CMD_FLG_ACK_MSK;
612 if (ieee80211_is_mgmt(fc))
613 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
614 if (ieee80211_is_probe_resp(fc) &&
615 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
616 tx_flags |= TX_CMD_FLG_TSF_MSK;
617 } else {
618 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
619 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
620 }
621
622 if (ieee80211_is_back_req(fc))
623 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
624
625
626 tx_cmd->sta_id = std_id;
627 if (ieee80211_has_morefrags(fc))
628 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
629
630 if (ieee80211_is_data_qos(fc)) {
631 u8 *qc = ieee80211_get_qos_ctl(hdr);
632 tx_cmd->tid_tspec = qc[0] & 0xf;
633 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
634 } else {
635 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
636 }
637
638 priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
639
640 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
641 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
642
643 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
644 if (ieee80211_is_mgmt(fc)) {
645 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
646 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
647 else
648 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
649 } else {
650 tx_cmd->timeout.pm_frame_timeout = 0;
651 }
652
653 tx_cmd->driver_txop = 0;
654 tx_cmd->tx_flags = tx_flags;
655 tx_cmd->next_frame_len = 0;
656}
657
658#define RTS_HCCA_RETRY_LIMIT 3
659#define RTS_DFAULT_RETRY_LIMIT 60
660
661static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
662 struct iwl_tx_cmd *tx_cmd,
663 struct ieee80211_tx_info *info,
664 __le16 fc, int is_hcca)
665{
666 u32 rate_flags;
667 int rate_idx;
668 u8 rts_retry_limit;
669 u8 data_retry_limit;
670 u8 rate_plcp;
671
672 /* Set retry limit on DATA packets and Probe Responses*/
673 if (ieee80211_is_probe_resp(fc))
674 data_retry_limit = 3;
675 else
676 data_retry_limit = IWL_DEFAULT_TX_RETRY;
677 tx_cmd->data_retry_limit = data_retry_limit;
678
679 /* Set retry limit on RTS packets */
680 rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT :
681 RTS_DFAULT_RETRY_LIMIT;
682 if (data_retry_limit < rts_retry_limit)
683 rts_retry_limit = data_retry_limit;
684 tx_cmd->rts_retry_limit = rts_retry_limit;
685
686 /* DATA packets will use the uCode station table for rate/antenna
687 * selection */
688 if (ieee80211_is_data(fc)) {
689 tx_cmd->initial_rate_index = 0;
690 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
691 return;
692 }
693
694 /**
695 * If the current TX rate stored in mac80211 has the MCS bit set, it's
696 * not really a TX rate. Thus, we use the lowest supported rate for
697 * this band. Also use the lowest supported rate if the stored rate
698 * index is invalid.
699 */
700 rate_idx = info->control.rates[0].idx;
701 if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
702 (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
703 rate_idx = rate_lowest_index(&priv->bands[info->band],
704 info->control.sta);
705 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
706 if (info->band == IEEE80211_BAND_5GHZ)
707 rate_idx += IWL_FIRST_OFDM_RATE;
708 /* Get PLCP rate for tx_cmd->rate_n_flags */
709 rate_plcp = iwl_rates[rate_idx].plcp;
710 /* Zero out flags for this packet */
711 rate_flags = 0;
712
713 /* Set CCK flag as needed */
714 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
715 rate_flags |= RATE_MCS_CCK_MSK;
716
717 /* Set up RTS and CTS flags for certain packets */
718 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
719 case cpu_to_le16(IEEE80211_STYPE_AUTH):
720 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
721 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
722 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
723 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
724 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
725 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
726 }
727 break;
728 default:
729 break;
730 }
731
732 /* Set up antennas */
733 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
734 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
735
736 /* Set the rate in the TX cmd */
737 tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
738}
739
740static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
741 struct ieee80211_tx_info *info,
742 struct iwl_tx_cmd *tx_cmd,
743 struct sk_buff *skb_frag,
744 int sta_id)
745{
746 struct ieee80211_key_conf *keyconf = info->control.hw_key;
747
748 switch (keyconf->alg) {
749 case ALG_CCMP:
750 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
751 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
752 if (info->flags & IEEE80211_TX_CTL_AMPDU)
753 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
754 IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
755 break;
756
757 case ALG_TKIP:
758 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
759 ieee80211_get_tkip_key(keyconf, skb_frag,
760 IEEE80211_TKIP_P2_KEY, tx_cmd->key);
761 IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
762 break;
763
764 case ALG_WEP:
765 tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
766 (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
767
768 if (keyconf->keylen == WEP_KEY_LEN_128)
769 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
770
771 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
772
773 IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
774 "with key %d\n", keyconf->keyidx);
775 break;
776
777 default:
778 IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
779 break;
780 }
781}
782
783/*
784 * start REPLY_TX command process
785 */
786int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
787{
788 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
789 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
790 struct ieee80211_sta *sta = info->control.sta;
791 struct iwl_station_priv *sta_priv = NULL;
792 struct iwl_tx_queue *txq;
793 struct iwl_queue *q;
794 struct iwl_device_cmd *out_cmd;
795 struct iwl_cmd_meta *out_meta;
796 struct iwl_tx_cmd *tx_cmd;
797 int swq_id, txq_id;
798 dma_addr_t phys_addr;
799 dma_addr_t txcmd_phys;
800 dma_addr_t scratch_phys;
801 u16 len, len_org, firstlen, secondlen;
802 u16 seq_number = 0;
803 __le16 fc;
804 u8 hdr_len;
805 u8 sta_id;
806 u8 wait_write_ptr = 0;
807 u8 tid = 0;
808 u8 *qc = NULL;
809 unsigned long flags;
810
811 spin_lock_irqsave(&priv->lock, flags);
812 if (iwl_is_rfkill(priv)) {
813 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
814 goto drop_unlock;
815 }
816
817 fc = hdr->frame_control;
818
819#ifdef CONFIG_IWLWIFI_DEBUG
820 if (ieee80211_is_auth(fc))
821 IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
822 else if (ieee80211_is_assoc_req(fc))
823 IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
824 else if (ieee80211_is_reassoc_req(fc))
825 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
826#endif
827
828 /* drop all non-injected data frame if we are not associated */
829 if (ieee80211_is_data(fc) &&
830 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
831 (!iwl_is_associated(priv) ||
832 ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
833 !priv->assoc_station_added)) {
834 IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
835 goto drop_unlock;
836 }
837
838 hdr_len = ieee80211_hdrlen(fc);
839
840 /* Find (or create) index into station table for destination station */
841 if (info->flags & IEEE80211_TX_CTL_INJECTED)
842 sta_id = priv->hw_params.bcast_sta_id;
843 else
844 sta_id = iwl_get_sta_id(priv, hdr);
845 if (sta_id == IWL_INVALID_STATION) {
846 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
847 hdr->addr1);
848 goto drop_unlock;
849 }
850
851 IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
852
853 if (sta)
854 sta_priv = (void *)sta->drv_priv;
855
856 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id &&
857 sta_priv->asleep) {
858 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
859 /*
860 * This sends an asynchronous command to the device,
861 * but we can rely on it being processed before the
862 * next frame is processed -- and the next frame to
863 * this station is the one that will consume this
864 * counter.
865 * For now set the counter to just 1 since we do not
866 * support uAPSD yet.
867 */
868 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
869 }
870
871 txq_id = skb_get_queue_mapping(skb);
872 if (ieee80211_is_data_qos(fc)) {
873 qc = ieee80211_get_qos_ctl(hdr);
874 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
875 if (unlikely(tid >= MAX_TID_COUNT))
876 goto drop_unlock;
877 seq_number = priv->stations[sta_id].tid[tid].seq_number;
878 seq_number &= IEEE80211_SCTL_SEQ;
879 hdr->seq_ctrl = hdr->seq_ctrl &
880 cpu_to_le16(IEEE80211_SCTL_FRAG);
881 hdr->seq_ctrl |= cpu_to_le16(seq_number);
882 seq_number += 0x10;
883 /* aggregation is on for this <sta,tid> */
884 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
885 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {
886 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
887 }
888 }
889
890 txq = &priv->txq[txq_id];
891 swq_id = txq->swq_id;
892 q = &txq->q;
893
894 if (unlikely(iwl_queue_space(q) < q->high_mark))
895 goto drop_unlock;
896
897 if (ieee80211_is_data_qos(fc))
898 priv->stations[sta_id].tid[tid].tfds_in_queue++;
899
900 /* Set up driver data for this TFD */
901 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
902 txq->txb[q->write_ptr].skb[0] = skb;
903
904 /* Set up first empty entry in queue's array of Tx/cmd buffers */
905 out_cmd = txq->cmd[q->write_ptr];
906 out_meta = &txq->meta[q->write_ptr];
907 tx_cmd = &out_cmd->cmd.tx;
908 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
909 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
910
911 /*
912 * Set up the Tx-command (not MAC!) header.
913 * Store the chosen Tx queue and TFD index within the sequence field;
914 * after Tx, uCode's Tx response will return this value so driver can
915 * locate the frame within the tx queue and do post-tx processing.
916 */
917 out_cmd->hdr.cmd = REPLY_TX;
918 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
919 INDEX_TO_SEQ(q->write_ptr)));
920
921 /* Copy MAC header from skb into command buffer */
922 memcpy(tx_cmd->hdr, hdr, hdr_len);
923
924
925 /* Total # bytes to be transmitted */
926 len = (u16)skb->len;
927 tx_cmd->len = cpu_to_le16(len);
928
929 if (info->control.hw_key)
930 iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
931
932 /* TODO need this for burst mode later on */
933 iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
934 iwl_dbg_log_tx_data_frame(priv, len, hdr);
935
936 /* set is_hcca to 0; it probably will never be implemented */
937 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
938
939 iwl_update_stats(priv, true, fc, len);
940 /*
941 * Use the first empty entry in this queue's command buffer array
942 * to contain the Tx command and MAC header concatenated together
943 * (payload data will be in another buffer).
944 * Size of this varies, due to varying MAC header length.
945 * If end is not dword aligned, we'll have 2 extra bytes at the end
946 * of the MAC header (device reads on dword boundaries).
947 * We'll tell device about this padding later.
948 */
949 len = sizeof(struct iwl_tx_cmd) +
950 sizeof(struct iwl_cmd_header) + hdr_len;
951
952 len_org = len;
953 firstlen = len = (len + 3) & ~3;
954
955 if (len_org != len)
956 len_org = 1;
957 else
958 len_org = 0;
959
960 /* Tell NIC about any 2-byte padding after MAC header */
961 if (len_org)
962 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
963
964 /* Physical address of this Tx command's header (not MAC header!),
965 * within command buffer array. */
966 txcmd_phys = pci_map_single(priv->pci_dev,
967 &out_cmd->hdr, len,
968 PCI_DMA_BIDIRECTIONAL);
969 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
970 pci_unmap_len_set(out_meta, len, len);
971 /* Add buffer containing Tx command and MAC(!) header to TFD's
972 * first entry */
973 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
974 txcmd_phys, len, 1, 0);
975
976 if (!ieee80211_has_morefrags(hdr->frame_control)) {
977 txq->need_update = 1;
978 if (qc)
979 priv->stations[sta_id].tid[tid].seq_number = seq_number;
980 } else {
981 wait_write_ptr = 1;
982 txq->need_update = 0;
983 }
984
985 /* Set up TFD's 2nd entry to point directly to remainder of skb,
986 * if any (802.11 null frames have no payload). */
987 secondlen = len = skb->len - hdr_len;
988 if (len) {
989 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
990 len, PCI_DMA_TODEVICE);
991 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
992 phys_addr, len,
993 0, 0);
994 }
995
996 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
997 offsetof(struct iwl_tx_cmd, scratch);
998
999 len = sizeof(struct iwl_tx_cmd) +
1000 sizeof(struct iwl_cmd_header) + hdr_len;
1001 /* take back ownership of DMA buffer to enable update */
1002 pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
1003 len, PCI_DMA_BIDIRECTIONAL);
1004 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1005 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1006
1007 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
1008 le16_to_cpu(out_cmd->hdr.sequence));
1009 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
1010 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
1011 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
1012
1013 /* Set up entry for this TFD in Tx byte-count array */
1014 if (info->flags & IEEE80211_TX_CTL_AMPDU)
1015 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
1016 le16_to_cpu(tx_cmd->len));
1017
1018 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
1019 len, PCI_DMA_BIDIRECTIONAL);
1020
1021 trace_iwlwifi_dev_tx(priv,
1022 &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
1023 sizeof(struct iwl_tfd),
1024 &out_cmd->hdr, firstlen,
1025 skb->data + hdr_len, secondlen);
1026
1027 /* Tell device the write index *just past* this latest filled TFD */
1028 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
1029 iwl_txq_update_write_ptr(priv, txq);
1030 spin_unlock_irqrestore(&priv->lock, flags);
1031
1032 /*
1033 * At this point the frame is "transmitted" successfully
1034 * and we will get a TX status notification eventually,
1035 * regardless of the value of ret. "ret" only indicates
1036 * whether or not we should update the write pointer.
1037 */
1038
1039 /* avoid atomic ops if it isn't an associated client */
1040 if (sta_priv && sta_priv->client)
1041 atomic_inc(&sta_priv->pending_frames);
1042
1043 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
1044 if (wait_write_ptr) {
1045 spin_lock_irqsave(&priv->lock, flags);
1046 txq->need_update = 1;
1047 iwl_txq_update_write_ptr(priv, txq);
1048 spin_unlock_irqrestore(&priv->lock, flags);
1049 } else {
1050 iwl_stop_queue(priv, txq->swq_id);
1051 }
1052 }
1053
1054 return 0;
1055
1056drop_unlock:
1057 spin_unlock_irqrestore(&priv->lock, flags);
1058 return -1;
1059}
1060EXPORT_SYMBOL(iwl_tx_skb);
1061
1062/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 418/*************** HOST COMMAND QUEUE FUNCTIONS *****/
1063 419
1064/** 420/**
@@ -1192,61 +548,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1192 return idx; 548 return idx;
1193} 549}
1194 550
1195static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
1196{
1197 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1198 struct ieee80211_sta *sta;
1199 struct iwl_station_priv *sta_priv;
1200
1201 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
1202 if (sta) {
1203 sta_priv = (void *)sta->drv_priv;
1204 /* avoid atomic ops if this isn't a client */
1205 if (sta_priv->client &&
1206 atomic_dec_return(&sta_priv->pending_frames) == 0)
1207 ieee80211_sta_block_awake(priv->hw, sta, false);
1208 }
1209
1210 ieee80211_tx_status_irqsafe(priv->hw, skb);
1211}
1212
1213int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1214{
1215 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1216 struct iwl_queue *q = &txq->q;
1217 struct iwl_tx_info *tx_info;
1218 int nfreed = 0;
1219 struct ieee80211_hdr *hdr;
1220
1221 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1222 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
1223 "is out of range [0-%d] %d %d.\n", txq_id,
1224 index, q->n_bd, q->write_ptr, q->read_ptr);
1225 return 0;
1226 }
1227
1228 for (index = iwl_queue_inc_wrap(index, q->n_bd);
1229 q->read_ptr != index;
1230 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1231
1232 tx_info = &txq->txb[txq->q.read_ptr];
1233 iwl_tx_status(priv, tx_info->skb[0]);
1234
1235 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
1236 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1237 nfreed++;
1238 tx_info->skb[0] = NULL;
1239
1240 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1241 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1242
1243 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1244 }
1245 return nfreed;
1246}
1247EXPORT_SYMBOL(iwl_tx_queue_reclaim);
1248
1249
1250/** 551/**
1251 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd 552 * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
1252 * 553 *
@@ -1340,7 +641,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1340 641
1341 if (!(meta->flags & CMD_ASYNC)) { 642 if (!(meta->flags & CMD_ASYNC)) {
1342 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 643 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1343 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n", 644 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
1344 get_cmd_string(cmd->hdr.cmd)); 645 get_cmd_string(cmd->hdr.cmd));
1345 wake_up_interruptible(&priv->wait_command_queue); 646 wake_up_interruptible(&priv->wait_command_queue);
1346 } 647 }
@@ -1348,358 +649,37 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1348} 649}
1349EXPORT_SYMBOL(iwl_tx_cmd_complete); 650EXPORT_SYMBOL(iwl_tx_cmd_complete);
1350 651
1351/*
1352 * Find first available (lowest unused) Tx Queue, mark it "active".
1353 * Called only when finding queue for aggregation.
1354 * Should never return anything < 7, because they should already
1355 * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6).
1356 */
1357static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
1358{
1359 int txq_id;
1360
1361 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
1362 if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
1363 return txq_id;
1364 return -1;
1365}
1366
1367int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
1368{
1369 int sta_id;
1370 int tx_fifo;
1371 int txq_id;
1372 int ret;
1373 unsigned long flags;
1374 struct iwl_tid_data *tid_data;
1375
1376 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1377 tx_fifo = default_tid_to_tx_fifo[tid];
1378 else
1379 return -EINVAL;
1380
1381 IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
1382 __func__, ra, tid);
1383
1384 sta_id = iwl_find_station(priv, ra);
1385 if (sta_id == IWL_INVALID_STATION) {
1386 IWL_ERR(priv, "Start AGG on invalid station\n");
1387 return -ENXIO;
1388 }
1389 if (unlikely(tid >= MAX_TID_COUNT))
1390 return -EINVAL;
1391
1392 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
1393 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
1394 return -ENXIO;
1395 }
1396
1397 txq_id = iwl_txq_ctx_activate_free(priv);
1398 if (txq_id == -1) {
1399 IWL_ERR(priv, "No free aggregation queue available\n");
1400 return -ENXIO;
1401 }
1402
1403 spin_lock_irqsave(&priv->sta_lock, flags);
1404 tid_data = &priv->stations[sta_id].tid[tid];
1405 *ssn = SEQ_TO_SN(tid_data->seq_number);
1406 tid_data->agg.txq_id = txq_id;
1407 priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id);
1408 spin_unlock_irqrestore(&priv->sta_lock, flags);
1409
1410 ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
1411 sta_id, tid, *ssn);
1412 if (ret)
1413 return ret;
1414
1415 if (tid_data->tfds_in_queue == 0) {
1416 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1417 tid_data->agg.state = IWL_AGG_ON;
1418 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1419 } else {
1420 IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
1421 tid_data->tfds_in_queue);
1422 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1423 }
1424 return ret;
1425}
1426EXPORT_SYMBOL(iwl_tx_agg_start);
1427
1428int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1429{
1430 int tx_fifo_id, txq_id, sta_id, ssn = -1;
1431 struct iwl_tid_data *tid_data;
1432 int write_ptr, read_ptr;
1433 unsigned long flags;
1434
1435 if (!ra) {
1436 IWL_ERR(priv, "ra = NULL\n");
1437 return -EINVAL;
1438 }
1439
1440 if (unlikely(tid >= MAX_TID_COUNT))
1441 return -EINVAL;
1442
1443 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1444 tx_fifo_id = default_tid_to_tx_fifo[tid];
1445 else
1446 return -EINVAL;
1447
1448 sta_id = iwl_find_station(priv, ra);
1449
1450 if (sta_id == IWL_INVALID_STATION) {
1451 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1452 return -ENXIO;
1453 }
1454
1455 if (priv->stations[sta_id].tid[tid].agg.state ==
1456 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1457 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1458 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1459 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1460 return 0;
1461 }
1462
1463 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1464 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1465
1466 tid_data = &priv->stations[sta_id].tid[tid];
1467 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1468 txq_id = tid_data->agg.txq_id;
1469 write_ptr = priv->txq[txq_id].q.write_ptr;
1470 read_ptr = priv->txq[txq_id].q.read_ptr;
1471
1472 /* The queue is not empty */
1473 if (write_ptr != read_ptr) {
1474 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1475 priv->stations[sta_id].tid[tid].agg.state =
1476 IWL_EMPTYING_HW_QUEUE_DELBA;
1477 return 0;
1478 }
1479
1480 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1481 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1482
1483 spin_lock_irqsave(&priv->lock, flags);
1484 /*
1485 * the only reason this call can fail is queue number out of range,
1486 * which can happen if uCode is reloaded and all the station
1487 * information are lost. if it is outside the range, there is no need
1488 * to deactivate the uCode queue, just return "success" to allow
1489 * mac80211 to clean up it own data.
1490 */
1491 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
1492 tx_fifo_id);
1493 spin_unlock_irqrestore(&priv->lock, flags);
1494
1495 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
1496
1497 return 0;
1498}
1499EXPORT_SYMBOL(iwl_tx_agg_stop);
1500
1501int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
1502{
1503 struct iwl_queue *q = &priv->txq[txq_id].q;
1504 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1505 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1506
1507 switch (priv->stations[sta_id].tid[tid].agg.state) {
1508 case IWL_EMPTYING_HW_QUEUE_DELBA:
1509 /* We are reclaiming the last packet of the */
1510 /* aggregated HW queue */
1511 if ((txq_id == tid_data->agg.txq_id) &&
1512 (q->read_ptr == q->write_ptr)) {
1513 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1514 int tx_fifo = default_tid_to_tx_fifo[tid];
1515 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1516 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1517 ssn, tx_fifo);
1518 tid_data->agg.state = IWL_AGG_OFF;
1519 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1520 }
1521 break;
1522 case IWL_EMPTYING_HW_QUEUE_ADDBA:
1523 /* We are reclaiming the last packet of the queue */
1524 if (tid_data->tfds_in_queue == 0) {
1525 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
1526 tid_data->agg.state = IWL_AGG_ON;
1527 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid);
1528 }
1529 break;
1530 }
1531 return 0;
1532}
1533EXPORT_SYMBOL(iwl_txq_check_empty);
1534
1535/**
1536 * iwl_tx_status_reply_compressed_ba - Update tx status from block-ack
1537 *
1538 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1539 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1540 */
1541static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1542 struct iwl_ht_agg *agg,
1543 struct iwl_compressed_ba_resp *ba_resp)
1544
1545{
1546 int i, sh, ack;
1547 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1548 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1549 u64 bitmap;
1550 int successes = 0;
1551 struct ieee80211_tx_info *info;
1552
1553 if (unlikely(!agg->wait_for_ba)) {
1554 IWL_ERR(priv, "Received BA when not expected\n");
1555 return -EINVAL;
1556 }
1557
1558 /* Mark that the expected block-ack response arrived */
1559 agg->wait_for_ba = 0;
1560 IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
1561
1562 /* Calculate shift to align block-ack bits with our Tx window bits */
1563 sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
1564 if (sh < 0) /* tbw something is wrong with indices */
1565 sh += 0x100;
1566
1567 /* don't use 64-bit values for now */
1568 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1569
1570 if (agg->frame_count > (64 - sh)) {
1571 IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
1572 return -1;
1573 }
1574
1575 /* check for success or failure according to the
1576 * transmitted bitmap and block-ack bitmap */
1577 bitmap &= agg->bitmap;
1578
1579 /* For each frame attempted in aggregation,
1580 * update driver's record of tx frame's status. */
1581 for (i = 0; i < agg->frame_count ; i++) {
1582 ack = bitmap & (1ULL << i);
1583 successes += !!ack;
1584 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1585 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
1586 agg->start_idx + i);
1587 }
1588
1589 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
1590 memset(&info->status, 0, sizeof(info->status));
1591 info->flags |= IEEE80211_TX_STAT_ACK;
1592 info->flags |= IEEE80211_TX_STAT_AMPDU;
1593 info->status.ampdu_ack_map = successes;
1594 info->status.ampdu_ack_len = agg->frame_count;
1595 iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1596
1597 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1598
1599 return 0;
1600}
1601
1602/**
1603 * iwl_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1604 *
1605 * Handles block-acknowledge notification from device, which reports success
1606 * of frames sent via aggregation.
1607 */
1608void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1609 struct iwl_rx_mem_buffer *rxb)
1610{
1611 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1612 struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1613 struct iwl_tx_queue *txq = NULL;
1614 struct iwl_ht_agg *agg;
1615 int index;
1616 int sta_id;
1617 int tid;
1618
1619 /* "flow" corresponds to Tx queue */
1620 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1621
1622 /* "ssn" is start of block-ack Tx window, corresponds to index
1623 * (in Tx queue's circular buffer) of first TFD/frame in window */
1624 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1625
1626 if (scd_flow >= priv->hw_params.max_txq_num) {
1627 IWL_ERR(priv,
1628 "BUG_ON scd_flow is bigger than number of queues\n");
1629 return;
1630 }
1631
1632 txq = &priv->txq[scd_flow];
1633 sta_id = ba_resp->sta_id;
1634 tid = ba_resp->tid;
1635 agg = &priv->stations[sta_id].tid[tid].agg;
1636
1637 /* Find index just before block-ack window */
1638 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1639
1640 /* TODO: Need to get this copy more safely - now good for debug */
1641
1642 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1643 "sta_id = %d\n",
1644 agg->wait_for_ba,
1645 (u8 *) &ba_resp->sta_addr_lo32,
1646 ba_resp->sta_id);
1647 IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
1648 "%d, scd_ssn = %d\n",
1649 ba_resp->tid,
1650 ba_resp->seq_ctl,
1651 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1652 ba_resp->scd_flow,
1653 ba_resp->scd_ssn);
1654 IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx \n",
1655 agg->start_idx,
1656 (unsigned long long)agg->bitmap);
1657
1658 /* Update driver's record of ACK vs. not for each frame in window */
1659 iwl_tx_status_reply_compressed_ba(priv, agg, ba_resp);
1660
1661 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1662 * block-ack window (we assume that they've been successfully
1663 * transmitted ... if not, it's too late anyway). */
1664 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1665 /* calculate mac80211 ampdu sw queue to wake */
1666 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1667 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1668
1669 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1670 priv->mac80211_registered &&
1671 (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
1672 iwl_wake_queue(priv, txq->swq_id);
1673
1674 iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
1675 }
1676}
1677EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
1678
1679#ifdef CONFIG_IWLWIFI_DEBUG 652#ifdef CONFIG_IWLWIFI_DEBUG
1680#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x 653#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
654#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
1681 655
1682const char *iwl_get_tx_fail_reason(u32 status) 656const char *iwl_get_tx_fail_reason(u32 status)
1683{ 657{
1684 switch (status & TX_STATUS_MSK) { 658 switch (status & TX_STATUS_MSK) {
1685 case TX_STATUS_SUCCESS: 659 case TX_STATUS_SUCCESS:
1686 return "SUCCESS"; 660 return "SUCCESS";
1687 TX_STATUS_ENTRY(SHORT_LIMIT); 661 TX_STATUS_POSTPONE(DELAY);
1688 TX_STATUS_ENTRY(LONG_LIMIT); 662 TX_STATUS_POSTPONE(FEW_BYTES);
1689 TX_STATUS_ENTRY(FIFO_UNDERRUN); 663 TX_STATUS_POSTPONE(BT_PRIO);
1690 TX_STATUS_ENTRY(MGMNT_ABORT); 664 TX_STATUS_POSTPONE(QUIET_PERIOD);
1691 TX_STATUS_ENTRY(NEXT_FRAG); 665 TX_STATUS_POSTPONE(CALC_TTAK);
1692 TX_STATUS_ENTRY(LIFE_EXPIRE); 666 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
1693 TX_STATUS_ENTRY(DEST_PS); 667 TX_STATUS_FAIL(SHORT_LIMIT);
1694 TX_STATUS_ENTRY(ABORTED); 668 TX_STATUS_FAIL(LONG_LIMIT);
1695 TX_STATUS_ENTRY(BT_RETRY); 669 TX_STATUS_FAIL(FIFO_UNDERRUN);
1696 TX_STATUS_ENTRY(STA_INVALID); 670 TX_STATUS_FAIL(DRAIN_FLOW);
1697 TX_STATUS_ENTRY(FRAG_DROPPED); 671 TX_STATUS_FAIL(RFKILL_FLUSH);
1698 TX_STATUS_ENTRY(TID_DISABLE); 672 TX_STATUS_FAIL(LIFE_EXPIRE);
1699 TX_STATUS_ENTRY(FRAME_FLUSHED); 673 TX_STATUS_FAIL(DEST_PS);
1700 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); 674 TX_STATUS_FAIL(HOST_ABORTED);
1701 TX_STATUS_ENTRY(TX_LOCKED); 675 TX_STATUS_FAIL(BT_RETRY);
1702 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); 676 TX_STATUS_FAIL(STA_INVALID);
677 TX_STATUS_FAIL(FRAG_DROPPED);
678 TX_STATUS_FAIL(TID_DISABLE);
679 TX_STATUS_FAIL(FIFO_FLUSHED);
680 TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
681 TX_STATUS_FAIL(FW_DROP);
682 TX_STATUS_FAIL(STA_COLOR_MISMATCH_DROP);
1703 } 683 }
1704 684
1705 return "UNKNOWN"; 685 return "UNKNOWN";
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index b74a56c48d26..3e5bffb6034f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -352,11 +352,11 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
352 352
353static void iwl3945_unset_hw_params(struct iwl_priv *priv) 353static void iwl3945_unset_hw_params(struct iwl_priv *priv)
354{ 354{
355 if (priv->shared_virt) 355 if (priv->_3945.shared_virt)
356 dma_free_coherent(&priv->pci_dev->dev, 356 dma_free_coherent(&priv->pci_dev->dev,
357 sizeof(struct iwl3945_shared), 357 sizeof(struct iwl3945_shared),
358 priv->shared_virt, 358 priv->_3945.shared_virt,
359 priv->shared_phys); 359 priv->_3945.shared_phys);
360} 360}
361 361
362static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, 362static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
@@ -505,24 +505,15 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
505 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); 505 IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
506#endif 506#endif
507 507
508 /* drop all non-injected data frame if we are not associated */
509 if (ieee80211_is_data(fc) &&
510 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
511 (!iwl_is_associated(priv) ||
512 ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
513 IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
514 goto drop_unlock;
515 }
516
517 spin_unlock_irqrestore(&priv->lock, flags); 508 spin_unlock_irqrestore(&priv->lock, flags);
518 509
519 hdr_len = ieee80211_hdrlen(fc); 510 hdr_len = ieee80211_hdrlen(fc);
520 511
521 /* Find (or create) index into station table for destination station */ 512 /* Find index into station table for destination station */
522 if (info->flags & IEEE80211_TX_CTL_INJECTED) 513 if (!info->control.sta)
523 sta_id = priv->hw_params.bcast_sta_id; 514 sta_id = priv->hw_params.bcast_sta_id;
524 else 515 else
525 sta_id = iwl_get_sta_id(priv, hdr); 516 sta_id = iwl_sta_id(info->control.sta);
526 if (sta_id == IWL_INVALID_STATION) { 517 if (sta_id == IWL_INVALID_STATION) {
527 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
528 hdr->addr1); 519 hdr->addr1);
@@ -607,9 +598,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
607 txq->need_update = 0; 598 txq->need_update = 0;
608 } 599 }
609 600
610 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", 601 IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
611 le16_to_cpu(out_cmd->hdr.sequence)); 602 le16_to_cpu(out_cmd->hdr.sequence));
612 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags)); 603 IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
613 iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); 604 iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd));
614 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, 605 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr,
615 ieee80211_hdrlen(fc)); 606 ieee80211_hdrlen(fc));
@@ -754,7 +745,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
754 if (iwl_is_associated(priv)) 745 if (iwl_is_associated(priv))
755 add_time = 746 add_time =
756 iwl3945_usecs_to_beacons( 747 iwl3945_usecs_to_beacons(
757 le64_to_cpu(params->start_time) - priv->last_tsf, 748 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
758 le16_to_cpu(priv->rxon_timing.beacon_interval)); 749 le16_to_cpu(priv->rxon_timing.beacon_interval));
759 750
760 memset(&spectrum, 0, sizeof(spectrum)); 751 memset(&spectrum, 0, sizeof(spectrum));
@@ -768,7 +759,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
768 759
769 if (iwl_is_associated(priv)) 760 if (iwl_is_associated(priv))
770 spectrum.start_time = 761 spectrum.start_time =
771 iwl3945_add_beacon_time(priv->last_beacon_time, 762 iwl3945_add_beacon_time(priv->_3945.last_beacon_time,
772 add_time, 763 add_time,
773 le16_to_cpu(priv->rxon_timing.beacon_interval)); 764 le16_to_cpu(priv->rxon_timing.beacon_interval));
774 else 765 else
@@ -857,7 +848,6 @@ static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
857#endif 848#endif
858 849
859 IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); 850 IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
860 return;
861} 851}
862 852
863static void iwl3945_bg_beacon_update(struct work_struct *work) 853static void iwl3945_bg_beacon_update(struct work_struct *work)
@@ -966,7 +956,7 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
966 * statistics request from the host as well as for the periodic 956 * statistics request from the host as well as for the periodic
967 * statistics notifications (after received beacons) from the uCode. 957 * statistics notifications (after received beacons) from the uCode.
968 */ 958 */
969 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 959 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics;
970 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 960 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
971 961
972 iwl_setup_rx_scan_handlers(priv); 962 iwl_setup_rx_scan_handlers(priv);
@@ -1613,9 +1603,6 @@ static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1613 return pos; 1603 return pos;
1614} 1604}
1615 1605
1616/* For sanity check only. Actual size is determined by uCode, typ. 512 */
1617#define IWL3945_MAX_EVENT_LOG_SIZE (512)
1618
1619#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1606#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1620 1607
1621int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, 1608int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
@@ -1642,16 +1629,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1642 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 1629 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
1643 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 1630 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
1644 1631
1645 if (capacity > IWL3945_MAX_EVENT_LOG_SIZE) { 1632 if (capacity > priv->cfg->max_event_log_size) {
1646 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 1633 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
1647 capacity, IWL3945_MAX_EVENT_LOG_SIZE); 1634 capacity, priv->cfg->max_event_log_size);
1648 capacity = IWL3945_MAX_EVENT_LOG_SIZE; 1635 capacity = priv->cfg->max_event_log_size;
1649 } 1636 }
1650 1637
1651 if (next_entry > IWL3945_MAX_EVENT_LOG_SIZE) { 1638 if (next_entry > priv->cfg->max_event_log_size) {
1652 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 1639 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
1653 next_entry, IWL3945_MAX_EVENT_LOG_SIZE); 1640 next_entry, priv->cfg->max_event_log_size);
1654 next_entry = IWL3945_MAX_EVENT_LOG_SIZE; 1641 next_entry = priv->cfg->max_event_log_size;
1655 } 1642 }
1656 1643
1657 size = num_wraps ? capacity : next_entry; 1644 size = num_wraps ? capacity : next_entry;
@@ -1860,7 +1847,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1860static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, 1847static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1861 enum ieee80211_band band, 1848 enum ieee80211_band band,
1862 u8 is_active, u8 n_probes, 1849 u8 is_active, u8 n_probes,
1863 struct iwl3945_scan_channel *scan_ch) 1850 struct iwl3945_scan_channel *scan_ch,
1851 struct ieee80211_vif *vif)
1864{ 1852{
1865 struct ieee80211_channel *chan; 1853 struct ieee80211_channel *chan;
1866 const struct ieee80211_supported_band *sband; 1854 const struct ieee80211_supported_band *sband;
@@ -1874,7 +1862,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1874 return 0; 1862 return 0;
1875 1863
1876 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 1864 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1877 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1865 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1878 1866
1879 if (passive_dwell <= active_dwell) 1867 if (passive_dwell <= active_dwell)
1880 passive_dwell = active_dwell + 1; 1868 passive_dwell = active_dwell + 1;
@@ -1947,7 +1935,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1947 added++; 1935 added++;
1948 } 1936 }
1949 1937
1950 IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added); 1938 IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
1951 return added; 1939 return added;
1952} 1940}
1953 1941
@@ -2122,6 +2110,28 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
2122 iwl_write32(priv, CSR_RESET, 0); 2110 iwl_write32(priv, CSR_RESET, 0);
2123} 2111}
2124 2112
2113#define IWL3945_UCODE_GET(item) \
2114static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\
2115{ \
2116 return le32_to_cpu(ucode->u.v1.item); \
2117}
2118
2119static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2120{
2121 return 24;
2122}
2123
2124static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode)
2125{
2126 return (u8 *) ucode->u.v1.data;
2127}
2128
2129IWL3945_UCODE_GET(inst_size);
2130IWL3945_UCODE_GET(data_size);
2131IWL3945_UCODE_GET(init_size);
2132IWL3945_UCODE_GET(init_data_size);
2133IWL3945_UCODE_GET(boot_size);
2134
2125/** 2135/**
2126 * iwl3945_read_ucode - Read uCode images from disk file. 2136 * iwl3945_read_ucode - Read uCode images from disk file.
2127 * 2137 *
@@ -2170,7 +2180,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2170 goto error; 2180 goto error;
2171 2181
2172 /* Make sure that we got at least our header! */ 2182 /* Make sure that we got at least our header! */
2173 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { 2183 if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) {
2174 IWL_ERR(priv, "File size way too small!\n"); 2184 IWL_ERR(priv, "File size way too small!\n");
2175 ret = -EINVAL; 2185 ret = -EINVAL;
2176 goto err_release; 2186 goto err_release;
@@ -2181,13 +2191,12 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2181 2191
2182 priv->ucode_ver = le32_to_cpu(ucode->ver); 2192 priv->ucode_ver = le32_to_cpu(ucode->ver);
2183 api_ver = IWL_UCODE_API(priv->ucode_ver); 2193 api_ver = IWL_UCODE_API(priv->ucode_ver);
2184 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver); 2194 inst_size = iwl3945_ucode_get_inst_size(ucode);
2185 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver); 2195 data_size = iwl3945_ucode_get_data_size(ucode);
2186 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver); 2196 init_size = iwl3945_ucode_get_init_size(ucode);
2187 init_data_size = 2197 init_data_size = iwl3945_ucode_get_init_data_size(ucode);
2188 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver); 2198 boot_size = iwl3945_ucode_get_boot_size(ucode);
2189 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver); 2199 src = iwl3945_ucode_get_data(ucode);
2190 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
2191 2200
2192 /* api_ver should match the api version forming part of the 2201 /* api_ver should match the api version forming part of the
2193 * firmware filename ... but we don't check for that and only rely 2202 * firmware filename ... but we don't check for that and only rely
@@ -2236,7 +2245,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2236 2245
2237 2246
2238 /* Verify size of file vs. image size info in file's header */ 2247 /* Verify size of file vs. image size info in file's header */
2239 if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) + 2248 if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) +
2240 inst_size + data_size + init_size + 2249 inst_size + data_size + init_size +
2241 init_data_size + boot_size) { 2250 init_data_size + boot_size) {
2242 2251
@@ -2490,8 +2499,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2490 goto restart; 2499 goto restart;
2491 } 2500 }
2492 2501
2493 iwl_clear_stations_table(priv);
2494
2495 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2502 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2496 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2503 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
2497 2504
@@ -2513,13 +2520,19 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2513 /* After the ALIVE response, we can send commands to 3945 uCode */ 2520 /* After the ALIVE response, we can send commands to 3945 uCode */
2514 set_bit(STATUS_ALIVE, &priv->status); 2521 set_bit(STATUS_ALIVE, &priv->status);
2515 2522
2523 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2524 /* Enable timer to monitor the driver queues */
2525 mod_timer(&priv->monitor_recover,
2526 jiffies +
2527 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2528 }
2529
2516 if (iwl_is_rfkill(priv)) 2530 if (iwl_is_rfkill(priv))
2517 return; 2531 return;
2518 2532
2519 ieee80211_wake_queues(priv->hw); 2533 ieee80211_wake_queues(priv->hw);
2520 2534
2521 priv->active_rate = priv->rates_mask; 2535 priv->active_rate = IWL_RATES_MASK;
2522 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
2523 2536
2524 iwl_power_update_mode(priv, true); 2537 iwl_power_update_mode(priv, true);
2525 2538
@@ -2531,11 +2544,11 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2531 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2544 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2532 } else { 2545 } else {
2533 /* Initialize our rx_config data */ 2546 /* Initialize our rx_config data */
2534 iwl_connection_init_rx_config(priv, priv->iw_mode); 2547 iwl_connection_init_rx_config(priv, NULL);
2535 } 2548 }
2536 2549
2537 /* Configure Bluetooth device coexistence support */ 2550 /* Configure Bluetooth device coexistence support */
2538 iwl_send_bt_config(priv); 2551 priv->cfg->ops->hcmd->send_bt_config(priv);
2539 2552
2540 /* Configure the adapter for unassociated operation */ 2553 /* Configure the adapter for unassociated operation */
2541 iwlcore_commit_rxon(priv); 2554 iwlcore_commit_rxon(priv);
@@ -2548,17 +2561,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2548 set_bit(STATUS_READY, &priv->status); 2561 set_bit(STATUS_READY, &priv->status);
2549 wake_up_interruptible(&priv->wait_command_queue); 2562 wake_up_interruptible(&priv->wait_command_queue);
2550 2563
2551 /* reassociate for ADHOC mode */
2552 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
2553 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
2554 priv->vif);
2555 if (beacon)
2556 iwl_mac_beacon_update(priv->hw, beacon);
2557 }
2558
2559 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2560 iwl_set_mode(priv, priv->iw_mode);
2561
2562 return; 2564 return;
2563 2565
2564 restart: 2566 restart:
@@ -2580,7 +2582,10 @@ static void __iwl3945_down(struct iwl_priv *priv)
2580 if (!exit_pending) 2582 if (!exit_pending)
2581 set_bit(STATUS_EXIT_PENDING, &priv->status); 2583 set_bit(STATUS_EXIT_PENDING, &priv->status);
2582 2584
2583 iwl_clear_stations_table(priv); 2585 /* Station information will now be cleared in device */
2586 iwl_clear_ucode_stations(priv);
2587 iwl_dealloc_bcast_station(priv);
2588 iwl_clear_driver_stations(priv);
2584 2589
2585 /* Unblock any waiting calls */ 2590 /* Unblock any waiting calls */
2586 wake_up_interruptible_all(&priv->wait_command_queue); 2591 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2661,6 +2666,10 @@ static int __iwl3945_up(struct iwl_priv *priv)
2661{ 2666{
2662 int rc, i; 2667 int rc, i;
2663 2668
2669 rc = iwl_alloc_bcast_station(priv, false);
2670 if (rc)
2671 return rc;
2672
2664 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 2673 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2665 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); 2674 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
2666 return -EIO; 2675 return -EIO;
@@ -2714,12 +2723,10 @@ static int __iwl3945_up(struct iwl_priv *priv)
2714 2723
2715 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2724 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2716 2725
2717 iwl_clear_stations_table(priv);
2718
2719 /* load bootstrap state machine, 2726 /* load bootstrap state machine,
2720 * load bootstrap program into processor's memory, 2727 * load bootstrap program into processor's memory,
2721 * prepare to load the "initialize" uCode */ 2728 * prepare to load the "initialize" uCode */
2722 priv->cfg->ops->lib->load_ucode(priv); 2729 rc = priv->cfg->ops->lib->load_ucode(priv);
2723 2730
2724 if (rc) { 2731 if (rc) {
2725 IWL_ERR(priv, 2732 IWL_ERR(priv,
@@ -2787,7 +2794,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
2787static void iwl3945_rfkill_poll(struct work_struct *data) 2794static void iwl3945_rfkill_poll(struct work_struct *data)
2788{ 2795{
2789 struct iwl_priv *priv = 2796 struct iwl_priv *priv =
2790 container_of(data, struct iwl_priv, rfkill_poll.work); 2797 container_of(data, struct iwl_priv, _3945.rfkill_poll.work);
2791 bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); 2798 bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status);
2792 bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) 2799 bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL)
2793 & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); 2800 & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
@@ -2806,22 +2813,18 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
2806 2813
2807 /* Keep this running, even if radio now enabled. This will be 2814 /* Keep this running, even if radio now enabled. This will be
2808 * cancelled in mac_start() if system decides to start again */ 2815 * cancelled in mac_start() if system decides to start again */
2809 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 2816 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
2810 round_jiffies_relative(2 * HZ)); 2817 round_jiffies_relative(2 * HZ));
2811 2818
2812} 2819}
2813 2820
2814#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 2821void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2815static void iwl3945_bg_request_scan(struct work_struct *data)
2816{ 2822{
2817 struct iwl_priv *priv =
2818 container_of(data, struct iwl_priv, request_scan);
2819 struct iwl_host_cmd cmd = { 2823 struct iwl_host_cmd cmd = {
2820 .id = REPLY_SCAN_CMD, 2824 .id = REPLY_SCAN_CMD,
2821 .len = sizeof(struct iwl3945_scan_cmd), 2825 .len = sizeof(struct iwl3945_scan_cmd),
2822 .flags = CMD_SIZE_HUGE, 2826 .flags = CMD_SIZE_HUGE,
2823 }; 2827 };
2824 int rc = 0;
2825 struct iwl3945_scan_cmd *scan; 2828 struct iwl3945_scan_cmd *scan;
2826 struct ieee80211_conf *conf = NULL; 2829 struct ieee80211_conf *conf = NULL;
2827 u8 n_probes = 0; 2830 u8 n_probes = 0;
@@ -2830,8 +2833,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2830 2833
2831 conf = ieee80211_get_hw_conf(priv->hw); 2834 conf = ieee80211_get_hw_conf(priv->hw);
2832 2835
2833 mutex_lock(&priv->mutex);
2834
2835 cancel_delayed_work(&priv->scan_check); 2836 cancel_delayed_work(&priv->scan_check);
2836 2837
2837 if (!iwl_is_ready(priv)) { 2838 if (!iwl_is_ready(priv)) {
@@ -2849,7 +2850,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2849 if (test_bit(STATUS_SCAN_HW, &priv->status)) { 2850 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
2850 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " 2851 IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
2851 "Ignoring second request.\n"); 2852 "Ignoring second request.\n");
2852 rc = -EIO;
2853 goto done; 2853 goto done;
2854 } 2854 }
2855 2855
@@ -2875,20 +2875,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2875 goto done; 2875 goto done;
2876 } 2876 }
2877 2877
2878 if (!priv->scan_bands) { 2878 if (!priv->scan_cmd) {
2879 IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n"); 2879 priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
2880 goto done; 2880 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
2881 } 2881 if (!priv->scan_cmd) {
2882 2882 IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
2883 if (!priv->scan) {
2884 priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) +
2885 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
2886 if (!priv->scan) {
2887 rc = -ENOMEM;
2888 goto done; 2883 goto done;
2889 } 2884 }
2890 } 2885 }
2891 scan = priv->scan; 2886 scan = priv->scan_cmd;
2892 memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); 2887 memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE);
2893 2888
2894 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 2889 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
@@ -2904,7 +2899,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2904 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 2899 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
2905 2900
2906 spin_lock_irqsave(&priv->lock, flags); 2901 spin_lock_irqsave(&priv->lock, flags);
2907 interval = priv->beacon_int; 2902 interval = vif ? vif->bss_conf.beacon_int : 0;
2908 spin_unlock_irqrestore(&priv->lock, flags); 2903 spin_unlock_irqrestore(&priv->lock, flags);
2909 2904
2910 scan->suspend_time = 0; 2905 scan->suspend_time = 0;
@@ -2927,7 +2922,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2927 scan_suspend_time, interval); 2922 scan_suspend_time, interval);
2928 } 2923 }
2929 2924
2930 if (priv->scan_request->n_ssids) { 2925 if (priv->is_internal_short_scan) {
2926 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
2927 } else if (priv->scan_request->n_ssids) {
2931 int i, p = 0; 2928 int i, p = 0;
2932 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 2929 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
2933 for (i = 0; i < priv->scan_request->n_ssids; i++) { 2930 for (i = 0; i < priv->scan_request->n_ssids; i++) {
@@ -2955,12 +2952,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2955 2952
2956 /* flags + rate selection */ 2953 /* flags + rate selection */
2957 2954
2958 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { 2955 switch (priv->scan_band) {
2956 case IEEE80211_BAND_2GHZ:
2959 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 2957 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
2960 scan->tx_cmd.rate = IWL_RATE_1M_PLCP; 2958 scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
2961 scan->good_CRC_th = 0; 2959 scan->good_CRC_th = 0;
2962 band = IEEE80211_BAND_2GHZ; 2960 band = IEEE80211_BAND_2GHZ;
2963 } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { 2961 break;
2962 case IEEE80211_BAND_5GHZ:
2964 scan->tx_cmd.rate = IWL_RATE_6M_PLCP; 2963 scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
2965 /* 2964 /*
2966 * If active scaning is requested but a certain channel 2965 * If active scaning is requested but a certain channel
@@ -2970,27 +2969,32 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2970 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : 2969 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
2971 IWL_GOOD_CRC_TH_DISABLED; 2970 IWL_GOOD_CRC_TH_DISABLED;
2972 band = IEEE80211_BAND_5GHZ; 2971 band = IEEE80211_BAND_5GHZ;
2973 } else { 2972 break;
2974 IWL_WARN(priv, "Invalid scan band count\n"); 2973 default:
2974 IWL_WARN(priv, "Invalid scan band\n");
2975 goto done; 2975 goto done;
2976 } 2976 }
2977 2977
2978 scan->tx_cmd.len = cpu_to_le16( 2978 if (!priv->is_internal_short_scan) {
2979 scan->tx_cmd.len = cpu_to_le16(
2979 iwl_fill_probe_req(priv, 2980 iwl_fill_probe_req(priv,
2980 (struct ieee80211_mgmt *)scan->data, 2981 (struct ieee80211_mgmt *)scan->data,
2981 priv->scan_request->ie, 2982 priv->scan_request->ie,
2982 priv->scan_request->ie_len, 2983 priv->scan_request->ie_len,
2983 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2984 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2984 2985 } else {
2986 scan->tx_cmd.len = cpu_to_le16(
2987 iwl_fill_probe_req(priv,
2988 (struct ieee80211_mgmt *)scan->data,
2989 NULL, 0,
2990 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
2991 }
2985 /* select Rx antennas */ 2992 /* select Rx antennas */
2986 scan->flags |= iwl3945_get_antenna_flags(priv); 2993 scan->flags |= iwl3945_get_antenna_flags(priv);
2987 2994
2988 if (iwl_is_monitor_mode(priv))
2989 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
2990
2991 scan->channel_count = 2995 scan->channel_count =
2992 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, 2996 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
2993 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 2997 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
2994 2998
2995 if (scan->channel_count == 0) { 2999 if (scan->channel_count == 0) {
2996 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 3000 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
@@ -3003,14 +3007,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
3003 scan->len = cpu_to_le16(cmd.len); 3007 scan->len = cpu_to_le16(cmd.len);
3004 3008
3005 set_bit(STATUS_SCAN_HW, &priv->status); 3009 set_bit(STATUS_SCAN_HW, &priv->status);
3006 rc = iwl_send_cmd_sync(priv, &cmd); 3010 if (iwl_send_cmd_sync(priv, &cmd))
3007 if (rc)
3008 goto done; 3011 goto done;
3009 3012
3010 queue_delayed_work(priv->workqueue, &priv->scan_check, 3013 queue_delayed_work(priv->workqueue, &priv->scan_check,
3011 IWL_SCAN_CHECK_WATCHDOG); 3014 IWL_SCAN_CHECK_WATCHDOG);
3012 3015
3013 mutex_unlock(&priv->mutex);
3014 return; 3016 return;
3015 3017
3016 done: 3018 done:
@@ -3024,7 +3026,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
3024 3026
3025 /* inform mac80211 scan aborted */ 3027 /* inform mac80211 scan aborted */
3026 queue_work(priv->workqueue, &priv->scan_completed); 3028 queue_work(priv->workqueue, &priv->scan_completed);
3027 mutex_unlock(&priv->mutex);
3028} 3029}
3029 3030
3030static void iwl3945_bg_restart(struct work_struct *data) 3031static void iwl3945_bg_restart(struct work_struct *data)
@@ -3066,28 +3067,25 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
3066 mutex_unlock(&priv->mutex); 3067 mutex_unlock(&priv->mutex);
3067} 3068}
3068 3069
3069#define IWL_DELAY_NEXT_SCAN (HZ*2) 3070void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3070
3071void iwl3945_post_associate(struct iwl_priv *priv)
3072{ 3071{
3073 int rc = 0; 3072 int rc = 0;
3074 struct ieee80211_conf *conf = NULL; 3073 struct ieee80211_conf *conf = NULL;
3075 3074
3076 if (priv->iw_mode == NL80211_IFTYPE_AP) { 3075 if (!vif || !priv->is_open)
3076 return;
3077
3078 if (vif->type == NL80211_IFTYPE_AP) {
3077 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3079 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3078 return; 3080 return;
3079 } 3081 }
3080 3082
3081
3082 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3083 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3083 priv->assoc_id, priv->active_rxon.bssid_addr); 3084 vif->bss_conf.aid, priv->active_rxon.bssid_addr);
3084 3085
3085 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3086 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3086 return; 3087 return;
3087 3088
3088 if (!priv->vif || !priv->is_open)
3089 return;
3090
3091 iwl_scan_cancel_timeout(priv, 200); 3089 iwl_scan_cancel_timeout(priv, 200);
3092 3090
3093 conf = ieee80211_get_hw_conf(priv->hw); 3091 conf = ieee80211_get_hw_conf(priv->hw);
@@ -3096,7 +3094,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3096 iwlcore_commit_rxon(priv); 3094 iwlcore_commit_rxon(priv);
3097 3095
3098 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3096 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3099 iwl_setup_rxon_timing(priv); 3097 iwl_setup_rxon_timing(priv, vif);
3100 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3098 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3101 sizeof(priv->rxon_timing), &priv->rxon_timing); 3099 sizeof(priv->rxon_timing), &priv->rxon_timing);
3102 if (rc) 3100 if (rc)
@@ -3105,57 +3103,40 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3105 3103
3106 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3104 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3107 3105
3108 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3106 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3109 3107
3110 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3108 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3111 priv->assoc_id, priv->beacon_int); 3109 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3112 3110
3113 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3111 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3114 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3112 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3115 else 3113 else
3116 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3114 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3117 3115
3118 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3116 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3119 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3117 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
3120 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3118 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3121 else 3119 else
3122 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3120 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3123 3121
3124 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3122 if (vif->type == NL80211_IFTYPE_ADHOC)
3125 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3123 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3126
3127 } 3124 }
3128 3125
3129 iwlcore_commit_rxon(priv); 3126 iwlcore_commit_rxon(priv);
3130 3127
3131 switch (priv->iw_mode) { 3128 switch (vif->type) {
3132 case NL80211_IFTYPE_STATION: 3129 case NL80211_IFTYPE_STATION:
3133 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); 3130 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
3134 break; 3131 break;
3135
3136 case NL80211_IFTYPE_ADHOC: 3132 case NL80211_IFTYPE_ADHOC:
3137
3138 priv->assoc_id = 1;
3139 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
3140 iwl3945_sync_sta(priv, IWL_STA_ID,
3141 (priv->band == IEEE80211_BAND_5GHZ) ?
3142 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
3143 CMD_ASYNC);
3144 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
3145 iwl3945_send_beacon_cmd(priv); 3133 iwl3945_send_beacon_cmd(priv);
3146
3147 break; 3134 break;
3148
3149 default: 3135 default:
3150 IWL_ERR(priv, "%s Should not be called in %d mode\n", 3136 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3151 __func__, priv->iw_mode); 3137 __func__, vif->type);
3152 break; 3138 break;
3153 } 3139 }
3154
3155 iwl_activate_qos(priv, 0);
3156
3157 /* we have just associated, don't start scan too early */
3158 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
3159} 3140}
3160 3141
3161/***************************************************************************** 3142/*****************************************************************************
@@ -3214,7 +3195,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
3214 3195
3215 /* ucode is running and will send rfkill notifications, 3196 /* ucode is running and will send rfkill notifications,
3216 * no need to poll the killswitch state anymore */ 3197 * no need to poll the killswitch state anymore */
3217 cancel_delayed_work(&priv->rfkill_poll); 3198 cancel_delayed_work(&priv->_3945.rfkill_poll);
3218 3199
3219 iwl_led_start(priv); 3200 iwl_led_start(priv);
3220 3201
@@ -3255,7 +3236,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
3255 flush_workqueue(priv->workqueue); 3236 flush_workqueue(priv->workqueue);
3256 3237
3257 /* start polling the killswitch state again */ 3238 /* start polling the killswitch state again */
3258 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 3239 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
3259 round_jiffies_relative(2 * HZ)); 3240 round_jiffies_relative(2 * HZ));
3260 3241
3261 IWL_DEBUG_MAC80211(priv, "leave\n"); 3242 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3277,7 +3258,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3277 return NETDEV_TX_OK; 3258 return NETDEV_TX_OK;
3278} 3259}
3279 3260
3280void iwl3945_config_ap(struct iwl_priv *priv) 3261void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3281{ 3262{
3282 int rc = 0; 3263 int rc = 0;
3283 3264
@@ -3293,7 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3293 3274
3294 /* RXON Timing */ 3275 /* RXON Timing */
3295 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3276 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3296 iwl_setup_rxon_timing(priv); 3277 iwl_setup_rxon_timing(priv, vif);
3297 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3278 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3298 sizeof(priv->rxon_timing), 3279 sizeof(priv->rxon_timing),
3299 &priv->rxon_timing); 3280 &priv->rxon_timing);
@@ -3301,9 +3282,10 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3301 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3282 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3302 "Attempting to continue.\n"); 3283 "Attempting to continue.\n");
3303 3284
3304 /* FIXME: what should be the assoc_id for AP? */ 3285 priv->staging_rxon.assoc_id = 0;
3305 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3286
3306 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3287 if (vif->bss_conf.assoc_capability &
3288 WLAN_CAPABILITY_SHORT_PREAMBLE)
3307 priv->staging_rxon.flags |= 3289 priv->staging_rxon.flags |=
3308 RXON_FLG_SHORT_PREAMBLE_MSK; 3290 RXON_FLG_SHORT_PREAMBLE_MSK;
3309 else 3291 else
@@ -3311,22 +3293,21 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3311 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3293 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3312 3294
3313 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3295 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3314 if (priv->assoc_capability & 3296 if (vif->bss_conf.assoc_capability &
3315 WLAN_CAPABILITY_SHORT_SLOT_TIME) 3297 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3316 priv->staging_rxon.flags |= 3298 priv->staging_rxon.flags |=
3317 RXON_FLG_SHORT_SLOT_MSK; 3299 RXON_FLG_SHORT_SLOT_MSK;
3318 else 3300 else
3319 priv->staging_rxon.flags &= 3301 priv->staging_rxon.flags &=
3320 ~RXON_FLG_SHORT_SLOT_MSK; 3302 ~RXON_FLG_SHORT_SLOT_MSK;
3321 3303
3322 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3304 if (vif->type == NL80211_IFTYPE_ADHOC)
3323 priv->staging_rxon.flags &= 3305 priv->staging_rxon.flags &=
3324 ~RXON_FLG_SHORT_SLOT_MSK; 3306 ~RXON_FLG_SHORT_SLOT_MSK;
3325 } 3307 }
3326 /* restore RXON assoc */ 3308 /* restore RXON assoc */
3327 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3309 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3328 iwlcore_commit_rxon(priv); 3310 iwlcore_commit_rxon(priv);
3329 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
3330 } 3311 }
3331 iwl3945_send_beacon_cmd(priv); 3312 iwl3945_send_beacon_cmd(priv);
3332 3313
@@ -3341,7 +3322,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3341 struct ieee80211_key_conf *key) 3322 struct ieee80211_key_conf *key)
3342{ 3323{
3343 struct iwl_priv *priv = hw->priv; 3324 struct iwl_priv *priv = hw->priv;
3344 const u8 *addr;
3345 int ret = 0; 3325 int ret = 0;
3346 u8 sta_id = IWL_INVALID_STATION; 3326 u8 sta_id = IWL_INVALID_STATION;
3347 u8 static_key; 3327 u8 static_key;
@@ -3353,21 +3333,24 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3353 return -EOPNOTSUPP; 3333 return -EOPNOTSUPP;
3354 } 3334 }
3355 3335
3356 addr = sta ? sta->addr : iwl_bcast_addr;
3357 static_key = !iwl_is_associated(priv); 3336 static_key = !iwl_is_associated(priv);
3358 3337
3359 if (!static_key) { 3338 if (!static_key) {
3360 sta_id = iwl_find_station(priv, addr); 3339 if (!sta) {
3361 if (sta_id == IWL_INVALID_STATION) { 3340 sta_id = priv->hw_params.bcast_sta_id;
3362 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 3341 } else {
3363 addr); 3342 sta_id = iwl_sta_id(sta);
3364 return -EINVAL; 3343 if (sta_id == IWL_INVALID_STATION) {
3344 IWL_DEBUG_MAC80211(priv,
3345 "leave - %pM not in station map.\n",
3346 sta->addr);
3347 return -EINVAL;
3348 }
3365 } 3349 }
3366 } 3350 }
3367 3351
3368 mutex_lock(&priv->mutex); 3352 mutex_lock(&priv->mutex);
3369 iwl_scan_cancel_timeout(priv, 100); 3353 iwl_scan_cancel_timeout(priv, 100);
3370 mutex_unlock(&priv->mutex);
3371 3354
3372 switch (cmd) { 3355 switch (cmd) {
3373 case SET_KEY: 3356 case SET_KEY:
@@ -3388,11 +3371,45 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3388 ret = -EINVAL; 3371 ret = -EINVAL;
3389 } 3372 }
3390 3373
3374 mutex_unlock(&priv->mutex);
3391 IWL_DEBUG_MAC80211(priv, "leave\n"); 3375 IWL_DEBUG_MAC80211(priv, "leave\n");
3392 3376
3393 return ret; 3377 return ret;
3394} 3378}
3395 3379
3380static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3381 struct ieee80211_vif *vif,
3382 struct ieee80211_sta *sta)
3383{
3384 struct iwl_priv *priv = hw->priv;
3385 struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv;
3386 int ret;
3387 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
3388 u8 sta_id;
3389
3390 sta_priv->common.sta_id = IWL_INVALID_STATION;
3391
3392 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3393 sta->addr);
3394
3395 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3396 &sta_id);
3397 if (ret) {
3398 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3399 sta->addr, ret);
3400 /* Should we return success if return code is EEXIST ? */
3401 return ret;
3402 }
3403
3404 sta_priv->common.sta_id = sta_id;
3405
3406 /* Initialize rate scaling */
3407 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
3408 sta->addr);
3409 iwl3945_rs_rate_init(priv, sta, sta_id);
3410
3411 return 0;
3412}
3396/***************************************************************************** 3413/*****************************************************************************
3397 * 3414 *
3398 * sysfs attributes 3415 * sysfs attributes
@@ -3592,7 +3609,7 @@ static ssize_t store_measurement(struct device *d,
3592 struct iwl_priv *priv = dev_get_drvdata(d); 3609 struct iwl_priv *priv = dev_get_drvdata(d);
3593 struct ieee80211_measurement_params params = { 3610 struct ieee80211_measurement_params params = {
3594 .channel = le16_to_cpu(priv->active_rxon.channel), 3611 .channel = le16_to_cpu(priv->active_rxon.channel),
3595 .start_time = cpu_to_le64(priv->last_tsf), 3612 .start_time = cpu_to_le64(priv->_3945.last_tsf),
3596 .duration = cpu_to_le16(1), 3613 .duration = cpu_to_le16(1),
3597 }; 3614 };
3598 u8 type = IWL_MEASURE_BASIC; 3615 u8 type = IWL_MEASURE_BASIC;
@@ -3656,44 +3673,6 @@ static ssize_t show_channels(struct device *d,
3656 3673
3657static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); 3674static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
3658 3675
3659static ssize_t show_statistics(struct device *d,
3660 struct device_attribute *attr, char *buf)
3661{
3662 struct iwl_priv *priv = dev_get_drvdata(d);
3663 u32 size = sizeof(struct iwl3945_notif_statistics);
3664 u32 len = 0, ofs = 0;
3665 u8 *data = (u8 *)&priv->statistics_39;
3666 int rc = 0;
3667
3668 if (!iwl_is_alive(priv))
3669 return -EAGAIN;
3670
3671 mutex_lock(&priv->mutex);
3672 rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
3673 mutex_unlock(&priv->mutex);
3674
3675 if (rc) {
3676 len = sprintf(buf,
3677 "Error sending statistics request: 0x%08X\n", rc);
3678 return len;
3679 }
3680
3681 while (size && (PAGE_SIZE - len)) {
3682 hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
3683 PAGE_SIZE - len, 1);
3684 len = strlen(buf);
3685 if (PAGE_SIZE - len)
3686 buf[len++] = '\n';
3687
3688 ofs += 16;
3689 size -= min(size, 16U);
3690 }
3691
3692 return len;
3693}
3694
3695static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
3696
3697static ssize_t show_antenna(struct device *d, 3676static ssize_t show_antenna(struct device *d,
3698 struct device_attribute *attr, char *buf) 3677 struct device_attribute *attr, char *buf)
3699{ 3678{
@@ -3775,14 +3754,21 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3775 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3754 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
3776 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); 3755 INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
3777 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); 3756 INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
3778 INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); 3757 INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
3779 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 3758 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
3780 INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
3781 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 3759 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
3760 INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
3782 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); 3761 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
3783 3762
3784 iwl3945_hw_setup_deferred_work(priv); 3763 iwl3945_hw_setup_deferred_work(priv);
3785 3764
3765 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3766 init_timer(&priv->monitor_recover);
3767 priv->monitor_recover.data = (unsigned long)priv;
3768 priv->monitor_recover.function =
3769 priv->cfg->ops->lib->recover_from_tx_stall;
3770 }
3771
3786 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3772 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3787 iwl3945_irq_tasklet, (unsigned long)priv); 3773 iwl3945_irq_tasklet, (unsigned long)priv);
3788} 3774}
@@ -3794,7 +3780,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3794 cancel_delayed_work_sync(&priv->init_alive_start); 3780 cancel_delayed_work_sync(&priv->init_alive_start);
3795 cancel_delayed_work(&priv->scan_check); 3781 cancel_delayed_work(&priv->scan_check);
3796 cancel_delayed_work(&priv->alive_start); 3782 cancel_delayed_work(&priv->alive_start);
3783 cancel_work_sync(&priv->start_internal_scan);
3797 cancel_work_sync(&priv->beacon_update); 3784 cancel_work_sync(&priv->beacon_update);
3785 if (priv->cfg->ops->lib->recover_from_tx_stall)
3786 del_timer_sync(&priv->monitor_recover);
3798} 3787}
3799 3788
3800static struct attribute *iwl3945_sysfs_entries[] = { 3789static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3805,7 +3794,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3805 &dev_attr_filter_flags.attr, 3794 &dev_attr_filter_flags.attr,
3806 &dev_attr_measurement.attr, 3795 &dev_attr_measurement.attr,
3807 &dev_attr_retry_rate.attr, 3796 &dev_attr_retry_rate.attr,
3808 &dev_attr_statistics.attr,
3809 &dev_attr_status.attr, 3797 &dev_attr_status.attr,
3810 &dev_attr_temperature.attr, 3798 &dev_attr_temperature.attr,
3811 &dev_attr_tx_power.attr, 3799 &dev_attr_tx_power.attr,
@@ -3832,7 +3820,9 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3832 .conf_tx = iwl_mac_conf_tx, 3820 .conf_tx = iwl_mac_conf_tx,
3833 .reset_tsf = iwl_mac_reset_tsf, 3821 .reset_tsf = iwl_mac_reset_tsf,
3834 .bss_info_changed = iwl_bss_info_changed, 3822 .bss_info_changed = iwl_bss_info_changed,
3835 .hw_scan = iwl_mac_hw_scan 3823 .hw_scan = iwl_mac_hw_scan,
3824 .sta_add = iwl3945_mac_sta_add,
3825 .sta_remove = iwl_mac_sta_remove,
3836}; 3826};
3837 3827
3838static int iwl3945_init_drv(struct iwl_priv *priv) 3828static int iwl3945_init_drv(struct iwl_priv *priv)
@@ -3851,9 +3841,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3851 mutex_init(&priv->mutex); 3841 mutex_init(&priv->mutex);
3852 mutex_init(&priv->sync_cmd_mutex); 3842 mutex_init(&priv->sync_cmd_mutex);
3853 3843
3854 /* Clear the driver's (not device's) station table */
3855 iwl_clear_stations_table(priv);
3856
3857 priv->ieee_channels = NULL; 3844 priv->ieee_channels = NULL;
3858 priv->ieee_rates = NULL; 3845 priv->ieee_rates = NULL;
3859 priv->band = IEEE80211_BAND_2GHZ; 3846 priv->band = IEEE80211_BAND_2GHZ;
@@ -3861,12 +3848,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3861 priv->iw_mode = NL80211_IFTYPE_STATION; 3848 priv->iw_mode = NL80211_IFTYPE_STATION;
3862 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3849 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3863 3850
3864 iwl_reset_qos(priv);
3865
3866 priv->qos_data.qos_active = 0;
3867 priv->qos_data.qos_cap.val = 0;
3868
3869 priv->rates_mask = IWL_RATES_MASK;
3870 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3851 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
3871 3852
3872 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3853 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
@@ -3902,6 +3883,8 @@ err:
3902 return ret; 3883 return ret;
3903} 3884}
3904 3885
3886#define IWL3945_MAX_PROBE_REQUEST 200
3887
3905static int iwl3945_setup_mac(struct iwl_priv *priv) 3888static int iwl3945_setup_mac(struct iwl_priv *priv)
3906{ 3889{
3907 int ret; 3890 int ret;
@@ -3909,10 +3892,10 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3909 3892
3910 hw->rate_control_algorithm = "iwl-3945-rs"; 3893 hw->rate_control_algorithm = "iwl-3945-rs";
3911 hw->sta_data_size = sizeof(struct iwl3945_sta_priv); 3894 hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
3895 hw->vif_data_size = sizeof(struct iwl_vif_priv);
3912 3896
3913 /* Tell mac80211 our characteristics */ 3897 /* Tell mac80211 our characteristics */
3914 hw->flags = IEEE80211_HW_SIGNAL_DBM | 3898 hw->flags = IEEE80211_HW_SIGNAL_DBM |
3915 IEEE80211_HW_NOISE_DBM |
3916 IEEE80211_HW_SPECTRUM_MGMT; 3899 IEEE80211_HW_SPECTRUM_MGMT;
3917 3900
3918 if (!priv->cfg->broken_powersave) 3901 if (!priv->cfg->broken_powersave)
@@ -3928,7 +3911,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3928 3911
3929 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; 3912 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
3930 /* we create the 802.11 header and a zero-length SSID element */ 3913 /* we create the 802.11 header and a zero-length SSID element */
3931 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 3914 hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2;
3932 3915
3933 /* Default value; 4 EDCA QOS priorities */ 3916 /* Default value; 4 EDCA QOS priorities */
3934 hw->queues = 4; 3917 hw->queues = 4;
@@ -4131,7 +4114,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4131 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); 4114 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
4132 4115
4133 /* Start monitoring the killswitch */ 4116 /* Start monitoring the killswitch */
4134 queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 4117 queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll,
4135 2 * HZ); 4118 2 * HZ);
4136 4119
4137 return 0; 4120 return 0;
@@ -4205,7 +4188,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4205 4188
4206 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 4189 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
4207 4190
4208 cancel_delayed_work_sync(&priv->rfkill_poll); 4191 cancel_delayed_work_sync(&priv->_3945.rfkill_poll);
4209 4192
4210 iwl3945_dealloc_ucode_pci(priv); 4193 iwl3945_dealloc_ucode_pci(priv);
4211 4194
@@ -4214,7 +4197,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4214 iwl3945_hw_txq_ctx_free(priv); 4197 iwl3945_hw_txq_ctx_free(priv);
4215 4198
4216 iwl3945_unset_hw_params(priv); 4199 iwl3945_unset_hw_params(priv);
4217 iwl_clear_stations_table(priv);
4218 4200
4219 /*netif_stop_queue(dev); */ 4201 /*netif_stop_queue(dev); */
4220 flush_workqueue(priv->workqueue); 4202 flush_workqueue(priv->workqueue);
@@ -4236,7 +4218,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4236 4218
4237 iwl_free_channel_map(priv); 4219 iwl_free_channel_map(priv);
4238 iwlcore_free_geos(priv); 4220 iwlcore_free_geos(priv);
4239 kfree(priv->scan); 4221 kfree(priv->scan_cmd);
4240 if (priv->ibss_beacon) 4222 if (priv->ibss_beacon)
4241 dev_kfree_skb(priv->ibss_beacon); 4223 dev_kfree_skb(priv->ibss_beacon);
4242 4224
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index b9d34a766964..03f998d098c5 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -17,7 +17,7 @@ config IWM
17config IWM_DEBUG 17config IWM_DEBUG
18 bool "Enable full debugging output in iwmc3200wifi" 18 bool "Enable full debugging output in iwmc3200wifi"
19 depends on IWM && DEBUG_FS 19 depends on IWM && DEBUG_FS
20 ---help--- 20 help
21 This option will enable debug tracing and setting for iwm 21 This option will enable debug tracing and setting for iwm
22 22
23 You can set the debug level and module through debugfs. By 23 You can set the debug level and module through debugfs. By
@@ -30,3 +30,10 @@ config IWM_DEBUG
30 Or, if you want the full debug, for all modules: 30 Or, if you want the full debug, for all modules:
31 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level 31 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level
32 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules 32 echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules
33
34config IWM_TRACING
35 bool "Enable event tracing for iwmc3200wifi"
36 depends on IWM && EVENT_TRACING
37 help
38 Say Y here to trace all the commands and responses between
39 the driver and firmware (including TX/RX frames) with ftrace.
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index d34291b652d3..cdc7e07ba113 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -3,3 +3,8 @@ iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o 3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
6iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
7
8CFLAGS_trace.o := -I$(src)
9
10ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/iwmc3200wifi/bus.h b/drivers/net/wireless/iwmc3200wifi/bus.h
index 836663eec257..62edd5888a7b 100644
--- a/drivers/net/wireless/iwmc3200wifi/bus.h
+++ b/drivers/net/wireless/iwmc3200wifi/bus.h
@@ -31,7 +31,7 @@ struct iwm_if_ops {
31 int (*disable)(struct iwm_priv *iwm); 31 int (*disable)(struct iwm_priv *iwm);
32 int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); 32 int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count);
33 33
34 int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); 34 void (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir);
35 void (*debugfs_exit)(struct iwm_priv *iwm); 35 void (*debugfs_exit)(struct iwm_priv *iwm);
36 36
37 const char *umac_name; 37 const char *umac_name;
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index a1d45cce0ebc..902e95f70f6e 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -264,7 +264,7 @@ static int iwm_cfg80211_get_station(struct wiphy *wiphy,
264int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) 264int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
265{ 265{
266 struct wiphy *wiphy = iwm_to_wiphy(iwm); 266 struct wiphy *wiphy = iwm_to_wiphy(iwm);
267 struct iwm_bss_info *bss, *next; 267 struct iwm_bss_info *bss;
268 struct iwm_umac_notif_bss_info *umac_bss; 268 struct iwm_umac_notif_bss_info *umac_bss;
269 struct ieee80211_mgmt *mgmt; 269 struct ieee80211_mgmt *mgmt;
270 struct ieee80211_channel *channel; 270 struct ieee80211_channel *channel;
@@ -272,7 +272,7 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
272 s32 signal; 272 s32 signal;
273 int freq; 273 int freq;
274 274
275 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) { 275 list_for_each_entry(bss, &iwm->bss_list, node) {
276 umac_bss = bss->bss; 276 umac_bss = bss->bss;
277 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); 277 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
278 278
@@ -726,23 +726,26 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
726 CFG_POWER_INDEX, iwm->conf.power_index); 726 CFG_POWER_INDEX, iwm->conf.power_index);
727} 727}
728 728
729int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, 729static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
730 struct cfg80211_pmksa *pmksa) 730 struct net_device *netdev,
731 struct cfg80211_pmksa *pmksa)
731{ 732{
732 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 733 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
733 734
734 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); 735 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
735} 736}
736 737
737int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, 738static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
738 struct cfg80211_pmksa *pmksa) 739 struct net_device *netdev,
740 struct cfg80211_pmksa *pmksa)
739{ 741{
740 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 742 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
741 743
742 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); 744 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
743} 745}
744 746
745int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) 747static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
748 struct net_device *netdev)
746{ 749{
747 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 750 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
748 struct cfg80211_pmksa pmksa; 751 struct cfg80211_pmksa pmksa;
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 42df7262f9f7..330c7d9cf101 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -507,7 +507,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
507 return ret; 507 return ret;
508 } 508 }
509 509
510 /* When succeding, the send_target routine returns the seq number */ 510 /* When succeeding, the send_target routine returns the seq number */
511 seq_num = ret; 511 seq_num = ret;
512 512
513 ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, 513 ret = wait_event_interruptible_timeout(iwm->nonwifi_queue,
@@ -782,10 +782,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
782 return 0; 782 return 0;
783} 783}
784 784
785int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) 785int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
786{ 786{
787 struct iwm_umac_invalidate_profile invalid; 787 struct iwm_umac_invalidate_profile invalid;
788 int ret;
789 788
790 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; 789 invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
791 invalid.hdr.buf_size = 790 invalid.hdr.buf_size =
@@ -794,7 +793,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
794 793
795 invalid.reason = WLAN_REASON_UNSPECIFIED; 794 invalid.reason = WLAN_REASON_UNSPECIFIED;
796 795
797 ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); 796 return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
797}
798
799int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
800{
801 int ret;
802
803 ret = __iwm_invalidate_mlme_profile(iwm);
798 if (ret) 804 if (ret)
799 return ret; 805 return ret;
800 806
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 3dfd9f0e9003..7e16bcf59978 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
488 void *payload, u16 payload_size); 488 void *payload, u16 payload_size);
489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); 489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
490int iwm_send_mlme_profile(struct iwm_priv *iwm); 490int iwm_send_mlme_profile(struct iwm_priv *iwm);
491int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
491int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); 492int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
492int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); 493int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
493int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); 494int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
index e35c9b693d1f..a0c13a49ab3c 100644
--- a/drivers/net/wireless/iwmc3200wifi/debug.h
+++ b/drivers/net/wireless/iwmc3200wifi/debug.h
@@ -113,13 +113,10 @@ struct iwm_debugfs {
113}; 113};
114 114
115#ifdef CONFIG_IWM_DEBUG 115#ifdef CONFIG_IWM_DEBUG
116int iwm_debugfs_init(struct iwm_priv *iwm); 116void iwm_debugfs_init(struct iwm_priv *iwm);
117void iwm_debugfs_exit(struct iwm_priv *iwm); 117void iwm_debugfs_exit(struct iwm_priv *iwm);
118#else 118#else
119static inline int iwm_debugfs_init(struct iwm_priv *iwm) 119static inline void iwm_debugfs_init(struct iwm_priv *iwm) {}
120{
121 return 0;
122}
123static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} 120static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {}
124#endif 121#endif
125 122
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index cbb81befdb55..53b0b7711f02 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -48,12 +48,11 @@ static struct {
48 48
49#define add_dbg_module(dbg, name, id, initlevel) \ 49#define add_dbg_module(dbg, name, id, initlevel) \
50do { \ 50do { \
51 struct dentry *d; \
52 dbg.dbg_module[id] = (initlevel); \ 51 dbg.dbg_module[id] = (initlevel); \
53 d = debugfs_create_x8(name, 0600, dbg.dbgdir, \ 52 dbg.dbg_module_dentries[id] = \
54 &(dbg.dbg_module[id])); \ 53 debugfs_create_x8(name, 0600, \
55 if (!IS_ERR(d)) \ 54 dbg.dbgdir, \
56 dbg.dbg_module_dentries[id] = d; \ 55 &(dbg.dbg_module[id])); \
57} while (0) 56} while (0)
58 57
59static int iwm_debugfs_u32_read(void *data, u64 *val) 58static int iwm_debugfs_u32_read(void *data, u64 *val)
@@ -266,7 +265,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
266 size_t count, loff_t *ppos) 265 size_t count, loff_t *ppos)
267{ 266{
268 struct iwm_priv *iwm = filp->private_data; 267 struct iwm_priv *iwm = filp->private_data;
269 struct iwm_rx_ticket_node *ticket, *next; 268 struct iwm_rx_ticket_node *ticket;
270 char *buf; 269 char *buf;
271 int buf_len = 4096, i; 270 int buf_len = 4096, i;
272 size_t len = 0; 271 size_t len = 0;
@@ -281,7 +280,8 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
281 if (!buf) 280 if (!buf)
282 return -ENOMEM; 281 return -ENOMEM;
283 282
284 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { 283 spin_lock(&iwm->ticket_lock);
284 list_for_each_entry(ticket, &iwm->rx_tickets, node) {
285 len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", 285 len += snprintf(buf + len, buf_len - len, "Ticket #%d\n",
286 ticket->ticket->id); 286 ticket->ticket->id);
287 len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", 287 len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n",
@@ -289,14 +289,17 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
289 len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", 289 len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n",
290 ticket->ticket->flags); 290 ticket->ticket->flags);
291 } 291 }
292 spin_unlock(&iwm->ticket_lock);
292 293
293 for (i = 0; i < IWM_RX_ID_HASH; i++) { 294 for (i = 0; i < IWM_RX_ID_HASH; i++) {
294 struct iwm_rx_packet *packet, *nxt; 295 struct iwm_rx_packet *packet;
295 struct list_head *pkt_list = &iwm->rx_packets[i]; 296 struct list_head *pkt_list = &iwm->rx_packets[i];
297
296 if (!list_empty(pkt_list)) { 298 if (!list_empty(pkt_list)) {
297 len += snprintf(buf + len, buf_len - len, 299 len += snprintf(buf + len, buf_len - len,
298 "Packet hash #%d\n", i); 300 "Packet hash #%d\n", i);
299 list_for_each_entry_safe(packet, nxt, pkt_list, node) { 301 spin_lock(&iwm->packet_lock[i]);
302 list_for_each_entry(packet, pkt_list, node) {
300 len += snprintf(buf + len, buf_len - len, 303 len += snprintf(buf + len, buf_len - len,
301 "\tPacket id: %d\n", 304 "\tPacket id: %d\n",
302 packet->id); 305 packet->id);
@@ -304,6 +307,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
304 "\tPacket length: %lu\n", 307 "\tPacket length: %lu\n",
305 packet->pkt_size); 308 packet->pkt_size);
306 } 309 }
310 spin_unlock(&iwm->packet_lock[i]);
307 } 311 }
308 } 312 }
309 313
@@ -418,89 +422,29 @@ static const struct file_operations iwm_debugfs_fw_err_fops = {
418 .read = iwm_debugfs_fw_err_read, 422 .read = iwm_debugfs_fw_err_read,
419}; 423};
420 424
421int iwm_debugfs_init(struct iwm_priv *iwm) 425void iwm_debugfs_init(struct iwm_priv *iwm)
422{ 426{
423 int i, result; 427 int i;
424 char devdir[16];
425 428
426 iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); 429 iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
427 result = PTR_ERR(iwm->dbg.rootdir); 430 iwm->dbg.devdir = debugfs_create_dir(wiphy_name(iwm_to_wiphy(iwm)),
428 if (!result || IS_ERR(iwm->dbg.rootdir)) { 431 iwm->dbg.rootdir);
429 if (result == -ENODEV) {
430 IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not "
431 "enabled in kernel config\n");
432 result = 0; /* No debugfs support */
433 }
434 IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result);
435 goto error;
436 }
437
438 snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm)));
439
440 iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir);
441 result = PTR_ERR(iwm->dbg.devdir);
442 if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) {
443 IWM_ERR(iwm, "Couldn't create devdir: %d\n", result);
444 goto error;
445 }
446
447 iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); 432 iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir);
448 result = PTR_ERR(iwm->dbg.dbgdir);
449 if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) {
450 IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result);
451 goto error;
452 }
453
454 iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); 433 iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir);
455 result = PTR_ERR(iwm->dbg.rxdir);
456 if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) {
457 IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result);
458 goto error;
459 }
460
461 iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); 434 iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir);
462 result = PTR_ERR(iwm->dbg.txdir);
463 if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) {
464 IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result);
465 goto error;
466 }
467
468 iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); 435 iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir);
469 result = PTR_ERR(iwm->dbg.busdir); 436 if (iwm->bus_ops->debugfs_init)
470 if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) { 437 iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir);
471 IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result);
472 goto error;
473 }
474
475 if (iwm->bus_ops->debugfs_init) {
476 result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir);
477 if (result < 0) {
478 IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result);
479 goto error;
480 }
481 }
482
483 438
484 iwm->dbg.dbg_level = IWM_DL_NONE; 439 iwm->dbg.dbg_level = IWM_DL_NONE;
485 iwm->dbg.dbg_level_dentry = 440 iwm->dbg.dbg_level_dentry =
486 debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, 441 debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm,
487 &fops_iwm_dbg_level); 442 &fops_iwm_dbg_level);
488 result = PTR_ERR(iwm->dbg.dbg_level_dentry);
489 if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) {
490 IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result);
491 goto error;
492 }
493
494 443
495 iwm->dbg.dbg_modules = IWM_DM_DEFAULT; 444 iwm->dbg.dbg_modules = IWM_DM_DEFAULT;
496 iwm->dbg.dbg_modules_dentry = 445 iwm->dbg.dbg_modules_dentry =
497 debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, 446 debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm,
498 &fops_iwm_dbg_modules); 447 &fops_iwm_dbg_modules);
499 result = PTR_ERR(iwm->dbg.dbg_modules_dentry);
500 if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) {
501 IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result);
502 goto error;
503 }
504 448
505 for (i = 0; i < __IWM_DM_NR; i++) 449 for (i = 0; i < __IWM_DM_NR; i++)
506 add_dbg_module(iwm->dbg, iwm_debug_module[i].name, 450 add_dbg_module(iwm->dbg, iwm_debug_module[i].name,
@@ -509,44 +453,15 @@ int iwm_debugfs_init(struct iwm_priv *iwm)
509 iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, 453 iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200,
510 iwm->dbg.txdir, iwm, 454 iwm->dbg.txdir, iwm,
511 &iwm_debugfs_txq_fops); 455 &iwm_debugfs_txq_fops);
512 result = PTR_ERR(iwm->dbg.txq_dentry);
513 if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) {
514 IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result);
515 goto error;
516 }
517
518 iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, 456 iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200,
519 iwm->dbg.txdir, iwm, 457 iwm->dbg.txdir, iwm,
520 &iwm_debugfs_tx_credit_fops); 458 &iwm_debugfs_tx_credit_fops);
521 result = PTR_ERR(iwm->dbg.tx_credit_dentry);
522 if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) {
523 IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result);
524 goto error;
525 }
526
527 iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, 459 iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200,
528 iwm->dbg.rxdir, iwm, 460 iwm->dbg.rxdir, iwm,
529 &iwm_debugfs_rx_ticket_fops); 461 &iwm_debugfs_rx_ticket_fops);
530 result = PTR_ERR(iwm->dbg.rx_ticket_dentry);
531 if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) {
532 IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result);
533 goto error;
534 }
535
536 iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, 462 iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200,
537 iwm->dbg.dbgdir, iwm, 463 iwm->dbg.dbgdir, iwm,
538 &iwm_debugfs_fw_err_fops); 464 &iwm_debugfs_fw_err_fops);
539 result = PTR_ERR(iwm->dbg.fw_err_dentry);
540 if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) {
541 IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result);
542 goto error;
543 }
544
545
546 return 0;
547
548 error:
549 return result;
550} 465}
551 466
552void iwm_debugfs_exit(struct iwm_priv *iwm) 467void iwm_debugfs_exit(struct iwm_priv *iwm)
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index 229de990379c..9531b18cf72a 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -105,6 +105,7 @@
105#include "hal.h" 105#include "hal.h"
106#include "umac.h" 106#include "umac.h"
107#include "debug.h" 107#include "debug.h"
108#include "trace.h"
108 109
109static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, 110static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
110 struct iwm_nonwifi_cmd *cmd, 111 struct iwm_nonwifi_cmd *cmd,
@@ -207,9 +208,9 @@ void iwm_cmd_flush(struct iwm_priv *iwm)
207 208
208struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) 209struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
209{ 210{
210 struct iwm_wifi_cmd *cmd, *next; 211 struct iwm_wifi_cmd *cmd;
211 212
212 list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending) 213 list_for_each_entry(cmd, &iwm->wifi_pending_cmd, pending)
213 if (cmd->seq_num == seq_num) { 214 if (cmd->seq_num == seq_num) {
214 list_del(&cmd->pending); 215 list_del(&cmd->pending);
215 return cmd; 216 return cmd;
@@ -218,12 +219,12 @@ struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
218 return NULL; 219 return NULL;
219} 220}
220 221
221struct iwm_nonwifi_cmd * 222struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm,
222iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode) 223 u8 seq_num, u8 cmd_opcode)
223{ 224{
224 struct iwm_nonwifi_cmd *cmd, *next; 225 struct iwm_nonwifi_cmd *cmd;
225 226
226 list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) 227 list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending)
227 if ((cmd->seq_num == seq_num) && 228 if ((cmd->seq_num == seq_num) &&
228 (cmd->udma_cmd.opcode == cmd_opcode) && 229 (cmd->udma_cmd.opcode == cmd_opcode) &&
229 (cmd->resp_received)) { 230 (cmd->resp_received)) {
@@ -277,6 +278,7 @@ static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm,
277 udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, 278 udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr,
278 udma_cmd->op1_sz, udma_cmd->op2); 279 udma_cmd->op1_sz, udma_cmd->op2);
279 280
281 trace_iwm_tx_nonwifi_cmd(iwm, udma_hdr);
280 return iwm_bus_send_chunk(iwm, buf->start, buf->len); 282 return iwm_bus_send_chunk(iwm, buf->start, buf->len);
281} 283}
282 284
@@ -363,6 +365,7 @@ static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm,
363 return ret; 365 return ret;
364 } 366 }
365 367
368 trace_iwm_tx_wifi_cmd(iwm, umac_hdr);
366 return iwm_bus_send_chunk(iwm, buf->start, buf->len); 369 return iwm_bus_send_chunk(iwm, buf->start, buf->len);
367} 370}
368 371
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h
index 0adfdc85765d..c20936d9b6b7 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.h
+++ b/drivers/net/wireless/iwmc3200wifi/hal.h
@@ -75,7 +75,8 @@ do { \
75 75
76 76
77/* UDMA IN OP CODE -- cmd bits [3:0] */ 77/* UDMA IN OP CODE -- cmd bits [3:0] */
78#define UDMA_IN_OPCODE_MASK 0xF 78#define UDMA_HDI_IN_NW_CMD_OPCODE_POS 0
79#define UDMA_HDI_IN_NW_CMD_OPCODE_SEED 0xF
79 80
80#define UDMA_IN_OPCODE_GENERAL_RESP 0x0 81#define UDMA_IN_OPCODE_GENERAL_RESP 0x0
81#define UDMA_IN_OPCODE_READ_RESP 0x1 82#define UDMA_IN_OPCODE_READ_RESP 0x1
@@ -130,7 +131,7 @@ do { \
130#define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ 131#define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
131 IWM_MAX_WIFI_HEADERS_SIZE) 132 IWM_MAX_WIFI_HEADERS_SIZE)
132 133
133#define IWM_HAL_CONCATENATE_BUF_SIZE 8192 134#define IWM_HAL_CONCATENATE_BUF_SIZE (32 * 1024)
134 135
135struct iwm_wifi_cmd_buff { 136struct iwm_wifi_cmd_buff {
136 u16 len; 137 u16 len;
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 79ffa3b98d73..13266c3842f8 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -48,6 +48,7 @@
48#include "umac.h" 48#include "umac.h"
49#include "lmac.h" 49#include "lmac.h"
50#include "eeprom.h" 50#include "eeprom.h"
51#include "trace.h"
51 52
52#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" 53#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation"
53#define IWM_AUTHOR "<ilw@linux.intel.com>" 54#define IWM_AUTHOR "<ilw@linux.intel.com>"
@@ -268,7 +269,9 @@ struct iwm_priv {
268 269
269 struct sk_buff_head rx_list; 270 struct sk_buff_head rx_list;
270 struct list_head rx_tickets; 271 struct list_head rx_tickets;
272 spinlock_t ticket_lock;
271 struct list_head rx_packets[IWM_RX_ID_HASH]; 273 struct list_head rx_packets[IWM_RX_ID_HASH];
274 spinlock_t packet_lock[IWM_RX_ID_HASH];
272 struct workqueue_struct *rx_wq; 275 struct workqueue_struct *rx_wq;
273 struct work_struct rx_worker; 276 struct work_struct rx_worker;
274 277
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 23856d359e12..362002735b12 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -277,8 +277,11 @@ int iwm_priv_init(struct iwm_priv *iwm)
277 277
278 skb_queue_head_init(&iwm->rx_list); 278 skb_queue_head_init(&iwm->rx_list);
279 INIT_LIST_HEAD(&iwm->rx_tickets); 279 INIT_LIST_HEAD(&iwm->rx_tickets);
280 for (i = 0; i < IWM_RX_ID_HASH; i++) 280 spin_lock_init(&iwm->ticket_lock);
281 for (i = 0; i < IWM_RX_ID_HASH; i++) {
281 INIT_LIST_HEAD(&iwm->rx_packets[i]); 282 INIT_LIST_HEAD(&iwm->rx_packets[i]);
283 spin_lock_init(&iwm->packet_lock[i]);
284 }
282 285
283 INIT_WORK(&iwm->rx_worker, iwm_rx_worker); 286 INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
284 287
@@ -424,9 +427,9 @@ int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
424static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, 427static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
425 u8 source) 428 u8 source)
426{ 429{
427 struct iwm_notif *notif, *next; 430 struct iwm_notif *notif;
428 431
429 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { 432 list_for_each_entry(notif, &iwm->pending_notif, pending) {
430 if ((notif->cmd_id == cmd) && (notif->src == source)) { 433 if ((notif->cmd_id == cmd) && (notif->src == source)) {
431 list_del(&notif->pending); 434 list_del(&notif->pending);
432 return notif; 435 return notif;
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 3257d4fad835..e1184deca559 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -343,15 +343,17 @@ static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node)
343static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) 343static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id)
344{ 344{
345 u8 id_hash = IWM_RX_ID_GET_HASH(id); 345 u8 id_hash = IWM_RX_ID_GET_HASH(id);
346 struct list_head *packet_list; 346 struct iwm_rx_packet *packet;
347 struct iwm_rx_packet *packet, *next;
348
349 packet_list = &iwm->rx_packets[id_hash];
350 347
351 list_for_each_entry_safe(packet, next, packet_list, node) 348 spin_lock(&iwm->packet_lock[id_hash]);
352 if (packet->id == id) 349 list_for_each_entry(packet, &iwm->rx_packets[id_hash], node)
350 if (packet->id == id) {
351 list_del(&packet->node);
352 spin_unlock(&iwm->packet_lock[id_hash]);
353 return packet; 353 return packet;
354 }
354 355
356 spin_unlock(&iwm->packet_lock[id_hash]);
355 return NULL; 357 return NULL;
356} 358}
357 359
@@ -389,18 +391,22 @@ void iwm_rx_free(struct iwm_priv *iwm)
389 struct iwm_rx_packet *packet, *np; 391 struct iwm_rx_packet *packet, *np;
390 int i; 392 int i;
391 393
394 spin_lock(&iwm->ticket_lock);
392 list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { 395 list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) {
393 list_del(&ticket->node); 396 list_del(&ticket->node);
394 iwm_rx_ticket_node_free(ticket); 397 iwm_rx_ticket_node_free(ticket);
395 } 398 }
399 spin_unlock(&iwm->ticket_lock);
396 400
397 for (i = 0; i < IWM_RX_ID_HASH; i++) { 401 for (i = 0; i < IWM_RX_ID_HASH; i++) {
402 spin_lock(&iwm->packet_lock[i]);
398 list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], 403 list_for_each_entry_safe(packet, np, &iwm->rx_packets[i],
399 node) { 404 node) {
400 list_del(&packet->node); 405 list_del(&packet->node);
401 kfree_skb(packet->skb); 406 kfree_skb(packet->skb);
402 kfree(packet); 407 kfree(packet);
403 } 408 }
409 spin_unlock(&iwm->packet_lock[i]);
404 } 410 }
405} 411}
406 412
@@ -425,10 +431,13 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
425 return PTR_ERR(ticket_node); 431 return PTR_ERR(ticket_node);
426 432
427 IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n", 433 IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
428 ticket->action == IWM_RX_TICKET_RELEASE ? 434 __le16_to_cpu(ticket->action) ==
435 IWM_RX_TICKET_RELEASE ?
429 "RELEASE" : "DROP", 436 "RELEASE" : "DROP",
430 ticket->id); 437 ticket->id);
438 spin_lock(&iwm->ticket_lock);
431 list_add_tail(&ticket_node->node, &iwm->rx_tickets); 439 list_add_tail(&ticket_node->node, &iwm->rx_tickets);
440 spin_unlock(&iwm->ticket_lock);
432 441
433 /* 442 /*
434 * We received an Rx ticket, most likely there's 443 * We received an Rx ticket, most likely there's
@@ -461,6 +470,7 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
461 struct iwm_rx_packet *packet; 470 struct iwm_rx_packet *packet;
462 u16 id, buf_offset; 471 u16 id, buf_offset;
463 u32 packet_size; 472 u32 packet_size;
473 u8 id_hash;
464 474
465 IWM_DBG_RX(iwm, DBG, "\n"); 475 IWM_DBG_RX(iwm, DBG, "\n");
466 476
@@ -478,7 +488,10 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
478 if (IS_ERR(packet)) 488 if (IS_ERR(packet))
479 return PTR_ERR(packet); 489 return PTR_ERR(packet);
480 490
481 list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]); 491 id_hash = IWM_RX_ID_GET_HASH(id);
492 spin_lock(&iwm->packet_lock[id_hash]);
493 list_add_tail(&packet->node, &iwm->rx_packets[id_hash]);
494 spin_unlock(&iwm->packet_lock[id_hash]);
482 495
483 /* We might (unlikely) have received the packet _after_ the ticket */ 496 /* We might (unlikely) have received the packet _after_ the ticket */
484 queue_work(iwm->rx_wq, &iwm->rx_worker); 497 queue_work(iwm->rx_wq, &iwm->rx_worker);
@@ -519,6 +532,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
519 unsigned long buf_size, 532 unsigned long buf_size,
520 struct iwm_wifi_cmd *cmd) 533 struct iwm_wifi_cmd *cmd)
521{ 534{
535 struct wiphy *wiphy = iwm_to_wiphy(iwm);
536 struct ieee80211_channel *chan;
522 struct iwm_umac_notif_assoc_complete *complete = 537 struct iwm_umac_notif_assoc_complete *complete =
523 (struct iwm_umac_notif_assoc_complete *)buf; 538 (struct iwm_umac_notif_assoc_complete *)buf;
524 539
@@ -527,6 +542,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
527 542
528 switch (le32_to_cpu(complete->status)) { 543 switch (le32_to_cpu(complete->status)) {
529 case UMAC_ASSOC_COMPLETE_SUCCESS: 544 case UMAC_ASSOC_COMPLETE_SUCCESS:
545 chan = ieee80211_get_channel(wiphy,
546 ieee80211_channel_to_frequency(complete->channel));
547 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
548 /* Associated to a unallowed channel, disassociate. */
549 __iwm_invalidate_mlme_profile(iwm);
550 IWM_WARN(iwm, "Couldn't associate with %pM due to "
551 "channel %d is disabled. Check your local "
552 "regulatory setting.\n",
553 complete->bssid, complete->channel);
554 goto failure;
555 }
556
530 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 557 set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
531 memcpy(iwm->bssid, complete->bssid, ETH_ALEN); 558 memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
532 iwm->channel = complete->channel; 559 iwm->channel = complete->channel;
@@ -563,6 +590,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
563 GFP_KERNEL); 590 GFP_KERNEL);
564 break; 591 break;
565 case UMAC_ASSOC_COMPLETE_FAILURE: 592 case UMAC_ASSOC_COMPLETE_FAILURE:
593 failure:
566 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 594 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
567 memset(iwm->bssid, 0, ETH_ALEN); 595 memset(iwm->bssid, 0, ETH_ALEN);
568 iwm->channel = 0; 596 iwm->channel = 0;
@@ -757,7 +785,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
757 (struct iwm_umac_notif_bss_info *)buf; 785 (struct iwm_umac_notif_bss_info *)buf;
758 struct ieee80211_channel *channel; 786 struct ieee80211_channel *channel;
759 struct ieee80211_supported_band *band; 787 struct ieee80211_supported_band *band;
760 struct iwm_bss_info *bss, *next; 788 struct iwm_bss_info *bss;
761 s32 signal; 789 s32 signal;
762 int freq; 790 int freq;
763 u16 frame_len = le16_to_cpu(umac_bss->frame_len); 791 u16 frame_len = le16_to_cpu(umac_bss->frame_len);
@@ -776,7 +804,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
776 IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); 804 IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi);
777 IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); 805 IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len);
778 806
779 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) 807 list_for_each_entry(bss, &iwm->bss_list, node)
780 if (bss->bss->table_idx == umac_bss->table_idx) 808 if (bss->bss->table_idx == umac_bss->table_idx)
781 break; 809 break;
782 810
@@ -843,16 +871,15 @@ static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf,
843 int i; 871 int i;
844 872
845 for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { 873 for (i = 0; i < le32_to_cpu(bss_rm->count); i++) {
846 table_idx = (le16_to_cpu(bss_rm->entries[i]) 874 table_idx = le16_to_cpu(bss_rm->entries[i]) &
847 & IWM_BSS_REMOVE_INDEX_MSK); 875 IWM_BSS_REMOVE_INDEX_MSK;
848 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) 876 list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
849 if (bss->bss->table_idx == cpu_to_le16(table_idx)) { 877 if (bss->bss->table_idx == cpu_to_le16(table_idx)) {
850 struct ieee80211_mgmt *mgmt; 878 struct ieee80211_mgmt *mgmt;
851 879
852 mgmt = (struct ieee80211_mgmt *) 880 mgmt = (struct ieee80211_mgmt *)
853 (bss->bss->frame_buf); 881 (bss->bss->frame_buf);
854 IWM_DBG_MLME(iwm, ERR, 882 IWM_DBG_MLME(iwm, ERR, "BSS removed: %pM\n",
855 "BSS removed: %pM\n",
856 mgmt->bssid); 883 mgmt->bssid);
857 list_del(&bss->node); 884 list_del(&bss->node);
858 kfree(bss->bss); 885 kfree(bss->bss);
@@ -1224,18 +1251,24 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
1224 u8 source, cmd_id; 1251 u8 source, cmd_id;
1225 u16 seq_num; 1252 u16 seq_num;
1226 u32 count; 1253 u32 count;
1227 u8 resp;
1228 1254
1229 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; 1255 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
1230 cmd_id = wifi_hdr->sw_hdr.cmd.cmd; 1256 cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
1231
1232 source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); 1257 source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
1233 if (source >= IWM_SRC_NUM) { 1258 if (source >= IWM_SRC_NUM) {
1234 IWM_CRIT(iwm, "invalid source %d\n", source); 1259 IWM_CRIT(iwm, "invalid source %d\n", source);
1235 return -EINVAL; 1260 return -EINVAL;
1236 } 1261 }
1237 1262
1238 count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT)); 1263 if (cmd_id == REPLY_RX_MPDU_CMD)
1264 trace_iwm_rx_packet(iwm, buf, buf_size);
1265 else if ((cmd_id == UMAC_NOTIFY_OPCODE_RX_TICKET) &&
1266 (source == UMAC_HDI_IN_SOURCE_FW))
1267 trace_iwm_rx_ticket(iwm, buf, buf_size);
1268 else
1269 trace_iwm_rx_wifi_cmd(iwm, wifi_hdr);
1270
1271 count = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT);
1239 count += sizeof(struct iwm_umac_wifi_in_hdr) - 1272 count += sizeof(struct iwm_umac_wifi_in_hdr) -
1240 sizeof(struct iwm_dev_cmd_hdr); 1273 sizeof(struct iwm_dev_cmd_hdr);
1241 if (count > buf_size) { 1274 if (count > buf_size) {
@@ -1243,8 +1276,6 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
1243 return -EINVAL; 1276 return -EINVAL;
1244 } 1277 }
1245 1278
1246 resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS);
1247
1248 seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); 1279 seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
1249 1280
1250 IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", 1281 IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n",
@@ -1317,8 +1348,9 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
1317{ 1348{
1318 u8 seq_num; 1349 u8 seq_num;
1319 struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; 1350 struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf;
1320 struct iwm_nonwifi_cmd *cmd, *next; 1351 struct iwm_nonwifi_cmd *cmd;
1321 1352
1353 trace_iwm_rx_nonwifi_cmd(iwm, buf, buf_size);
1322 seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); 1354 seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
1323 1355
1324 /* 1356 /*
@@ -1329,7 +1361,7 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
1329 * That means we only support synchronised non wifi command response 1361 * That means we only support synchronised non wifi command response
1330 * schemes. 1362 * schemes.
1331 */ 1363 */
1332 list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) 1364 list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending)
1333 if (cmd->seq_num == seq_num) { 1365 if (cmd->seq_num == seq_num) {
1334 cmd->resp_received = 1; 1366 cmd->resp_received = 1;
1335 cmd->buf.len = buf_size; 1367 cmd->buf.len = buf_size;
@@ -1648,6 +1680,7 @@ void iwm_rx_worker(struct work_struct *work)
1648 * We stop whenever a ticket is missing its packet, as we're 1680 * We stop whenever a ticket is missing its packet, as we're
1649 * supposed to send the packets in order. 1681 * supposed to send the packets in order.
1650 */ 1682 */
1683 spin_lock(&iwm->ticket_lock);
1651 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { 1684 list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
1652 struct iwm_rx_packet *packet = 1685 struct iwm_rx_packet *packet =
1653 iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); 1686 iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id));
@@ -1656,12 +1689,12 @@ void iwm_rx_worker(struct work_struct *work)
1656 IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " 1689 IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d "
1657 "to be handled first\n", 1690 "to be handled first\n",
1658 le16_to_cpu(ticket->ticket->id)); 1691 le16_to_cpu(ticket->ticket->id));
1659 return; 1692 break;
1660 } 1693 }
1661 1694
1662 list_del(&ticket->node); 1695 list_del(&ticket->node);
1663 list_del(&packet->node);
1664 iwm_rx_process_packet(iwm, packet, ticket); 1696 iwm_rx_process_packet(iwm, packet, ticket);
1665 } 1697 }
1698 spin_unlock(&iwm->ticket_lock);
1666} 1699}
1667 1700
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index 1eafd6dec3fd..edcb52330cf5 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -366,21 +366,13 @@ static const struct file_operations iwm_debugfs_sdio_fops = {
366 .read = iwm_debugfs_sdio_read, 366 .read = iwm_debugfs_sdio_read,
367}; 367};
368 368
369static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) 369static void if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir)
370{ 370{
371 int result;
372 struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); 371 struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
373 372
374 hw->cccr_dentry = debugfs_create_file("cccr", 0200, 373 hw->cccr_dentry = debugfs_create_file("cccr", 0200,
375 parent_dir, iwm, 374 parent_dir, iwm,
376 &iwm_debugfs_sdio_fops); 375 &iwm_debugfs_sdio_fops);
377 result = PTR_ERR(hw->cccr_dentry);
378 if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) {
379 IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result);
380 return result;
381 }
382
383 return 0;
384} 376}
385 377
386static void if_sdio_debugfs_exit(struct iwm_priv *iwm) 378static void if_sdio_debugfs_exit(struct iwm_priv *iwm)
@@ -440,11 +432,7 @@ static int iwm_sdio_probe(struct sdio_func *func,
440 hw = iwm_private(iwm); 432 hw = iwm_private(iwm);
441 hw->iwm = iwm; 433 hw->iwm = iwm;
442 434
443 ret = iwm_debugfs_init(iwm); 435 iwm_debugfs_init(iwm);
444 if (ret < 0) {
445 IWM_ERR(iwm, "Debugfs registration failed\n");
446 goto if_free;
447 }
448 436
449 sdio_set_drvdata(func, hw); 437 sdio_set_drvdata(func, hw);
450 438
@@ -473,7 +461,6 @@ static int iwm_sdio_probe(struct sdio_func *func,
473 destroy_workqueue(hw->isr_wq); 461 destroy_workqueue(hw->isr_wq);
474 debugfs_exit: 462 debugfs_exit:
475 iwm_debugfs_exit(iwm); 463 iwm_debugfs_exit(iwm);
476 if_free:
477 iwm_if_free(iwm); 464 iwm_if_free(iwm);
478 return ret; 465 return ret;
479} 466}
@@ -492,8 +479,6 @@ static void iwm_sdio_remove(struct sdio_func *func)
492 sdio_set_drvdata(func, NULL); 479 sdio_set_drvdata(func, NULL);
493 480
494 dev_info(dev, "IWM SDIO remove\n"); 481 dev_info(dev, "IWM SDIO remove\n");
495
496 return;
497} 482}
498 483
499static const struct sdio_device_id iwm_sdio_ids[] = { 484static const struct sdio_device_id iwm_sdio_ids[] = {
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.c b/drivers/net/wireless/iwmc3200wifi/trace.c
new file mode 100644
index 000000000000..904d36f22311
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/trace.c
@@ -0,0 +1,3 @@
1#include "iwm.h"
2#define CREATE_TRACE_POINTS
3#include "trace.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h
new file mode 100644
index 000000000000..abb4805fa8df
--- /dev/null
+++ b/drivers/net/wireless/iwmc3200wifi/trace.h
@@ -0,0 +1,283 @@
1#if !defined(__IWM_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
2#define __IWM_TRACE_H__
3
4#include <linux/tracepoint.h>
5
6#if !defined(CONFIG_IWM_TRACING)
7#undef TRACE_EVENT
8#define TRACE_EVENT(name, proto, ...) \
9static inline void trace_ ## name(proto) {}
10#endif
11
12#undef TRACE_SYSTEM
13#define TRACE_SYSTEM iwm
14
15#define IWM_ENTRY __array(char, ndev_name, 16)
16#define IWM_ASSIGN strlcpy(__entry->ndev_name, iwm_to_ndev(iwm)->name, 16)
17#define IWM_PR_FMT "%s"
18#define IWM_PR_ARG __entry->ndev_name
19
20TRACE_EVENT(iwm_tx_nonwifi_cmd,
21 TP_PROTO(struct iwm_priv *iwm, struct iwm_udma_out_nonwifi_hdr *hdr),
22
23 TP_ARGS(iwm, hdr),
24
25 TP_STRUCT__entry(
26 IWM_ENTRY
27 __field(u8, opcode)
28 __field(u8, resp)
29 __field(u8, eot)
30 __field(u8, hw)
31 __field(u16, seq)
32 __field(u32, addr)
33 __field(u32, op1)
34 __field(u32, op2)
35 ),
36
37 TP_fast_assign(
38 IWM_ASSIGN;
39 __entry->opcode = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE);
40 __entry->resp = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP);
41 __entry->eot = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT);
42 __entry->hw = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW);
43 __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM);
44 __entry->addr = le32_to_cpu(hdr->addr);
45 __entry->op1 = le32_to_cpu(hdr->op1_sz);
46 __entry->op2 = le32_to_cpu(hdr->op2);
47 ),
48
49 TP_printk(
50 IWM_PR_FMT " Tx TARGET CMD: opcode 0x%x, resp %d, eot %d, "
51 "hw %d, seq 0x%x, addr 0x%x, op1 0x%x, op2 0x%x",
52 IWM_PR_ARG, __entry->opcode, __entry->resp, __entry->eot,
53 __entry->hw, __entry->seq, __entry->addr, __entry->op1,
54 __entry->op2
55 )
56);
57
58TRACE_EVENT(iwm_tx_wifi_cmd,
59 TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_out_hdr *hdr),
60
61 TP_ARGS(iwm, hdr),
62
63 TP_STRUCT__entry(
64 IWM_ENTRY
65 __field(u8, opcode)
66 __field(u8, lmac)
67 __field(u8, resp)
68 __field(u8, eot)
69 __field(u8, ra_tid)
70 __field(u8, credit_group)
71 __field(u8, color)
72 __field(u16, seq)
73 ),
74
75 TP_fast_assign(
76 IWM_ASSIGN;
77 __entry->opcode = hdr->sw_hdr.cmd.cmd;
78 __entry->lmac = 0;
79 __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
80 __entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ);
81 __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
82 __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
83 __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
84 __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
85 if (__entry->opcode == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH ||
86 __entry->opcode == UMAC_CMD_OPCODE_WIFI_IF_WRAPPER) {
87 __entry->lmac = 1;
88 __entry->opcode = ((struct iwm_lmac_hdr *)(hdr + 1))->id;
89 }
90 ),
91
92 TP_printk(
93 IWM_PR_FMT " Tx %cMAC CMD: opcode 0x%x, resp %d, eot %d, "
94 "seq 0x%x, sta_color 0x%x, ra_tid 0x%x, credit_group 0x%x",
95 IWM_PR_ARG, __entry->lmac ? 'L' : 'U', __entry->opcode,
96 __entry->resp, __entry->eot, __entry->seq, __entry->color,
97 __entry->ra_tid, __entry->credit_group
98 )
99);
100
101TRACE_EVENT(iwm_tx_packets,
102 TP_PROTO(struct iwm_priv *iwm, u8 *buf, int len),
103
104 TP_ARGS(iwm, buf, len),
105
106 TP_STRUCT__entry(
107 IWM_ENTRY
108 __field(u8, eot)
109 __field(u8, ra_tid)
110 __field(u8, credit_group)
111 __field(u8, color)
112 __field(u16, seq)
113 __field(u8, npkt)
114 __field(u32, bytes)
115 ),
116
117 TP_fast_assign(
118 struct iwm_umac_wifi_out_hdr *hdr =
119 (struct iwm_umac_wifi_out_hdr *)buf;
120
121 IWM_ASSIGN;
122 __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
123 __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
124 __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
125 __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
126 __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
127 __entry->npkt = 1;
128 __entry->bytes = len;
129
130 if (!__entry->eot) {
131 int count;
132 u8 *ptr = buf;
133
134 __entry->npkt = 0;
135 while (ptr < buf + len) {
136 count = GET_VAL32(hdr->sw_hdr.meta_data,
137 UMAC_FW_CMD_BYTE_COUNT);
138 ptr += ALIGN(sizeof(*hdr) + count, 16);
139 hdr = (struct iwm_umac_wifi_out_hdr *)ptr;
140 __entry->npkt++;
141 }
142 }
143 ),
144
145 TP_printk(
146 IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, "
147 "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes",
148 IWM_PR_ARG, !__entry->eot ? "concatenated " : "",
149 __entry->eot, __entry->seq, __entry->color, __entry->ra_tid,
150 __entry->credit_group, __entry->npkt, __entry->bytes
151 )
152);
153
154TRACE_EVENT(iwm_rx_nonwifi_cmd,
155 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
156
157 TP_ARGS(iwm, buf, len),
158
159 TP_STRUCT__entry(
160 IWM_ENTRY
161 __field(u8, opcode)
162 __field(u16, seq)
163 __field(u32, len)
164 ),
165
166 TP_fast_assign(
167 struct iwm_udma_in_hdr *hdr = buf;
168
169 IWM_ASSIGN;
170 __entry->opcode = GET_VAL32(hdr->cmd, UDMA_HDI_IN_NW_CMD_OPCODE);
171 __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
172 __entry->len = len;
173 ),
174
175 TP_printk(
176 IWM_PR_FMT " Rx TARGET RESP: opcode 0x%x, seq 0x%x, len 0x%x",
177 IWM_PR_ARG, __entry->opcode, __entry->seq, __entry->len
178 )
179);
180
181TRACE_EVENT(iwm_rx_wifi_cmd,
182 TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_in_hdr *hdr),
183
184 TP_ARGS(iwm, hdr),
185
186 TP_STRUCT__entry(
187 IWM_ENTRY
188 __field(u8, cmd)
189 __field(u8, source)
190 __field(u16, seq)
191 __field(u32, count)
192 ),
193
194 TP_fast_assign(
195 IWM_ASSIGN;
196 __entry->cmd = hdr->sw_hdr.cmd.cmd;
197 __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
198 __entry->count = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT);
199 __entry->seq = le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
200 ),
201
202 TP_printk(
203 IWM_PR_FMT " Rx %s RESP: cmd 0x%x, seq 0x%x, count 0x%x",
204 IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? "LMAC" :
205 __entry->source == UMAC_HDI_IN_SOURCE_FW ? "UMAC" : "UDMA",
206 __entry->cmd, __entry->seq, __entry->count
207 )
208);
209
210#define iwm_ticket_action_symbol \
211 { IWM_RX_TICKET_DROP, "DROP" }, \
212 { IWM_RX_TICKET_RELEASE, "RELEASE" }, \
213 { IWM_RX_TICKET_SNIFFER, "SNIFFER" }, \
214 { IWM_RX_TICKET_ENQUEUE, "ENQUEUE" }
215
216TRACE_EVENT(iwm_rx_ticket,
217 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
218
219 TP_ARGS(iwm, buf, len),
220
221 TP_STRUCT__entry(
222 IWM_ENTRY
223 __field(u8, action)
224 __field(u8, reason)
225 __field(u16, id)
226 __field(u16, flags)
227 ),
228
229 TP_fast_assign(
230 struct iwm_rx_ticket *ticket =
231 ((struct iwm_umac_notif_rx_ticket *)buf)->tickets;
232
233 IWM_ASSIGN;
234 __entry->id = le16_to_cpu(ticket->id);
235 __entry->action = le16_to_cpu(ticket->action);
236 __entry->flags = le16_to_cpu(ticket->flags);
237 __entry->reason = (__entry->flags & IWM_RX_TICKET_DROP_REASON_MSK) >> IWM_RX_TICKET_DROP_REASON_POS;
238 ),
239
240 TP_printk(
241 IWM_PR_FMT " Rx ticket: id 0x%x, action %s, %s 0x%x%s",
242 IWM_PR_ARG, __entry->id,
243 __print_symbolic(__entry->action, iwm_ticket_action_symbol),
244 __entry->reason ? "reason" : "flags",
245 __entry->reason ? __entry->reason : __entry->flags,
246 __entry->flags & IWM_RX_TICKET_AMSDU_MSK ? ", AMSDU frame" : ""
247 )
248);
249
250TRACE_EVENT(iwm_rx_packet,
251 TP_PROTO(struct iwm_priv *iwm, void *buf, int len),
252
253 TP_ARGS(iwm, buf, len),
254
255 TP_STRUCT__entry(
256 IWM_ENTRY
257 __field(u8, source)
258 __field(u16, id)
259 __field(u32, len)
260 ),
261
262 TP_fast_assign(
263 struct iwm_umac_wifi_in_hdr *hdr = buf;
264
265 IWM_ASSIGN;
266 __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
267 __entry->id = le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
268 __entry->len = len - sizeof(*hdr);
269 ),
270
271 TP_printk(
272 IWM_PR_FMT " Rx %s packet: id 0x%x, %d bytes",
273 IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ?
274 "LMAC" : "UMAC", __entry->id, __entry->len
275 )
276);
277#endif
278
279#undef TRACE_INCLUDE_PATH
280#define TRACE_INCLUDE_PATH .
281#undef TRACE_INCLUDE_FILE
282#define TRACE_INCLUDE_FILE trace
283#include <trace/define_trace.h>
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
index f6a02f123f31..3216621fc55a 100644
--- a/drivers/net/wireless/iwmc3200wifi/tx.c
+++ b/drivers/net/wireless/iwmc3200wifi/tx.c
@@ -302,8 +302,8 @@ void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
302 302
303#define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr) 303#define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr)
304 304
305static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb, 305static __le16 iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
306 int pool_id, u8 *buf) 306 int pool_id, u8 *buf)
307{ 307{
308 struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf; 308 struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
309 struct iwm_udma_wifi_cmd udma_cmd; 309 struct iwm_udma_wifi_cmd udma_cmd;
@@ -347,6 +347,7 @@ static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
347 /* mark EOP for the last packet */ 347 /* mark EOP for the last packet */
348 iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); 348 iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1);
349 349
350 trace_iwm_tx_packets(iwm, txq->concat_buf, txq->concat_count);
350 ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); 351 ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count);
351 352
352 txq->concat_count = 0; 353 txq->concat_count = 0;
@@ -451,7 +452,6 @@ void iwm_tx_worker(struct work_struct *work)
451int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 452int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
452{ 453{
453 struct iwm_priv *iwm = ndev_to_iwm(netdev); 454 struct iwm_priv *iwm = ndev_to_iwm(netdev);
454 struct net_device *ndev = iwm_to_ndev(iwm);
455 struct wireless_dev *wdev = iwm_to_wdev(iwm); 455 struct wireless_dev *wdev = iwm_to_wdev(iwm);
456 struct iwm_tx_info *tx_info; 456 struct iwm_tx_info *tx_info;
457 struct iwm_tx_queue *txq; 457 struct iwm_tx_queue *txq;
@@ -518,12 +518,12 @@ int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
518 518
519 queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); 519 queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
520 520
521 ndev->stats.tx_packets++; 521 netdev->stats.tx_packets++;
522 ndev->stats.tx_bytes += skb->len; 522 netdev->stats.tx_bytes += skb->len;
523 return NETDEV_TX_OK; 523 return NETDEV_TX_OK;
524 524
525 drop: 525 drop:
526 ndev->stats.tx_dropped++; 526 netdev->stats.tx_dropped++;
527 dev_kfree_skb_any(skb); 527 dev_kfree_skb_any(skb);
528 return NETDEV_TX_OK; 528 return NETDEV_TX_OK;
529} 529}
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
index 7f54a145ca65..0cbba3ecc813 100644
--- a/drivers/net/wireless/iwmc3200wifi/umac.h
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -362,7 +362,7 @@ struct iwm_udma_out_wifi_hdr {
362#define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 362#define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4
363#define IWM_RX_TICKET_AMSDU_MSK 0x8 363#define IWM_RX_TICKET_AMSDU_MSK 0x8
364#define IWM_RX_TICKET_DROP_REASON_POS 4 364#define IWM_RX_TICKET_DROP_REASON_POS 4
365#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS) 365#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << IWM_RX_TICKET_DROP_REASON_POS)
366 366
367#define IWM_RX_DROP_NO_DROP 0x0 367#define IWM_RX_DROP_NO_DROP 0x0
368#define IWM_RX_DROP_BAD_CRC 0x1 368#define IWM_RX_DROP_BAD_CRC 0x1
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 12a2ef9dacea..aa06070e5eab 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -32,6 +32,9 @@ u8 lbs_bg_rates[MAX_RATES] =
320x00, 0x00 }; 320x00, 0x00 };
33 33
34 34
35static int assoc_helper_wep_keys(struct lbs_private *priv,
36 struct assoc_request *assoc_req);
37
35/** 38/**
36 * @brief This function finds common rates between rates and card rates. 39 * @brief This function finds common rates between rates and card rates.
37 * 40 *
@@ -611,7 +614,7 @@ static int lbs_assoc_post(struct lbs_private *priv,
611 614
612 if (status_code) { 615 if (status_code) {
613 lbs_mac_event_disconnected(priv); 616 lbs_mac_event_disconnected(priv);
614 ret = -1; 617 ret = status_code;
615 goto done; 618 goto done;
616 } 619 }
617 620
@@ -814,7 +817,24 @@ static int lbs_try_associate(struct lbs_private *priv,
814 goto out; 817 goto out;
815 818
816 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); 819 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
820 /* If the association fails with current auth mode, let's
821 * try by changing the auth mode
822 */
823 if ((priv->authtype_auto) &&
824 (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) &&
825 (assoc_req->secinfo.wep_enabled) &&
826 (priv->connect_status != LBS_CONNECTED)) {
827 if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM)
828 priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
829 else
830 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
831 if (!assoc_helper_wep_keys(priv, assoc_req))
832 ret = lbs_associate(priv, assoc_req,
833 CMD_802_11_ASSOCIATE);
834 }
817 835
836 if (ret)
837 ret = -1;
818out: 838out:
819 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 839 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
820 return ret; 840 return ret;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index ce7bec402a33..9d5d3ccf08c8 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -79,6 +79,7 @@ static const u32 cipher_suites[] = {
79 79
80 80
81static int lbs_cfg_set_channel(struct wiphy *wiphy, 81static int lbs_cfg_set_channel(struct wiphy *wiphy,
82 struct net_device *netdev,
82 struct ieee80211_channel *chan, 83 struct ieee80211_channel *chan,
83 enum nl80211_channel_type channel_type) 84 enum nl80211_channel_type channel_type)
84{ 85{
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index a48ccaffb288..de2caac11dd6 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -75,7 +75,7 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
75 return -ENOMEM; 75 return -ENOMEM;
76 76
77 pos += snprintf(buf+pos, len-pos, 77 pos += snprintf(buf+pos, len-pos,
78 "# | ch | rssi | bssid | cap | Qual | SSID \n"); 78 "# | ch | rssi | bssid | cap | Qual | SSID\n");
79 79
80 mutex_lock(&priv->lock); 80 mutex_lock(&priv->lock);
81 list_for_each_entry (iter_bss, &priv->network_list, list) { 81 list_for_each_entry (iter_bss, &priv->network_list, list) {
@@ -757,15 +757,12 @@ void lbs_debugfs_init(void)
757{ 757{
758 if (!lbs_dir) 758 if (!lbs_dir)
759 lbs_dir = debugfs_create_dir("lbs_wireless", NULL); 759 lbs_dir = debugfs_create_dir("lbs_wireless", NULL);
760
761 return;
762} 760}
763 761
764void lbs_debugfs_remove(void) 762void lbs_debugfs_remove(void)
765{ 763{
766 if (lbs_dir) 764 if (lbs_dir)
767 debugfs_remove(lbs_dir); 765 debugfs_remove(lbs_dir);
768 return;
769} 766}
770 767
771void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) 768void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 6875e1498bd5..a54880e4ad2b 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -134,6 +134,7 @@ struct lbs_private {
134 u8 wpa_ie_len; 134 u8 wpa_ie_len;
135 u16 wep_tx_keyidx; 135 u16 wep_tx_keyidx;
136 struct enc_key wep_keys[4]; 136 struct enc_key wep_keys[4];
137 u8 authtype_auto;
137 138
138 /* Wake On LAN */ 139 /* Wake On LAN */
139 uint32_t wol_criteria; 140 uint32_t wol_criteria;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 7d1a3c6b6ce0..64dd345d30f5 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -35,6 +35,8 @@
35#include <linux/mmc/card.h> 35#include <linux/mmc/card.h>
36#include <linux/mmc/sdio_func.h> 36#include <linux/mmc/sdio_func.h>
37#include <linux/mmc/sdio_ids.h> 37#include <linux/mmc/sdio_ids.h>
38#include <linux/mmc/sdio.h>
39#include <linux/mmc/host.h>
38 40
39#include "host.h" 41#include "host.h"
40#include "decl.h" 42#include "decl.h"
@@ -313,12 +315,30 @@ out:
313 return ret; 315 return ret;
314} 316}
315 317
318static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
319{
320 u8 status;
321 unsigned long timeout;
322 int ret = 0;
323
324 timeout = jiffies + HZ;
325 while (1) {
326 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
327 if (ret)
328 return ret;
329 if ((status & condition) == condition)
330 break;
331 if (time_after(jiffies, timeout))
332 return -ETIMEDOUT;
333 mdelay(1);
334 }
335 return ret;
336}
337
316static int if_sdio_card_to_host(struct if_sdio_card *card) 338static int if_sdio_card_to_host(struct if_sdio_card *card)
317{ 339{
318 int ret; 340 int ret;
319 u8 status;
320 u16 size, type, chunk; 341 u16 size, type, chunk;
321 unsigned long timeout;
322 342
323 lbs_deb_enter(LBS_DEB_SDIO); 343 lbs_deb_enter(LBS_DEB_SDIO);
324 344
@@ -333,19 +353,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
333 goto out; 353 goto out;
334 } 354 }
335 355
336 timeout = jiffies + HZ; 356 ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
337 while (1) { 357 if (ret)
338 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 358 goto out;
339 if (ret)
340 goto out;
341 if (status & IF_SDIO_IO_RDY)
342 break;
343 if (time_after(jiffies, timeout)) {
344 ret = -ETIMEDOUT;
345 goto out;
346 }
347 mdelay(1);
348 }
349 359
350 /* 360 /*
351 * The transfer must be in one transaction or the firmware 361 * The transfer must be in one transaction or the firmware
@@ -412,8 +422,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
412{ 422{
413 struct if_sdio_card *card; 423 struct if_sdio_card *card;
414 struct if_sdio_packet *packet; 424 struct if_sdio_packet *packet;
415 unsigned long timeout;
416 u8 status;
417 int ret; 425 int ret;
418 unsigned long flags; 426 unsigned long flags;
419 427
@@ -433,25 +441,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
433 441
434 sdio_claim_host(card->func); 442 sdio_claim_host(card->func);
435 443
436 timeout = jiffies + HZ; 444 ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
437 while (1) { 445 if (ret == 0) {
438 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 446 ret = sdio_writesb(card->func, card->ioport,
439 if (ret) 447 packet->buffer, packet->nb);
440 goto release;
441 if (status & IF_SDIO_IO_RDY)
442 break;
443 if (time_after(jiffies, timeout)) {
444 ret = -ETIMEDOUT;
445 goto release;
446 }
447 mdelay(1);
448 } 448 }
449 449
450 ret = sdio_writesb(card->func, card->ioport,
451 packet->buffer, packet->nb);
452 if (ret) 450 if (ret)
453 goto release; 451 lbs_pr_err("error %d sending packet to firmware\n", ret);
454release: 452
455 sdio_release_host(card->func); 453 sdio_release_host(card->func);
456 454
457 kfree(packet); 455 kfree(packet);
@@ -464,10 +462,11 @@ release:
464/* Firmware */ 462/* Firmware */
465/********************************************************************/ 463/********************************************************************/
466 464
465#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
466
467static int if_sdio_prog_helper(struct if_sdio_card *card) 467static int if_sdio_prog_helper(struct if_sdio_card *card)
468{ 468{
469 int ret; 469 int ret;
470 u8 status;
471 const struct firmware *fw; 470 const struct firmware *fw;
472 unsigned long timeout; 471 unsigned long timeout;
473 u8 *chunk_buffer; 472 u8 *chunk_buffer;
@@ -499,20 +498,14 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
499 size = fw->size; 498 size = fw->size;
500 499
501 while (size) { 500 while (size) {
502 timeout = jiffies + HZ; 501 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
503 while (1) { 502 if (ret)
504 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 503 goto release;
505 if (ret) 504
506 goto release; 505 /* On some platforms (like Davinci) the chip needs more time
507 if ((status & IF_SDIO_IO_RDY) && 506 * between helper blocks.
508 (status & IF_SDIO_DL_RDY)) 507 */
509 break; 508 mdelay(2);
510 if (time_after(jiffies, timeout)) {
511 ret = -ETIMEDOUT;
512 goto release;
513 }
514 mdelay(1);
515 }
516 509
517 chunk_size = min(size, (size_t)60); 510 chunk_size = min(size, (size_t)60);
518 511
@@ -582,7 +575,6 @@ out:
582static int if_sdio_prog_real(struct if_sdio_card *card) 575static int if_sdio_prog_real(struct if_sdio_card *card)
583{ 576{
584 int ret; 577 int ret;
585 u8 status;
586 const struct firmware *fw; 578 const struct firmware *fw;
587 unsigned long timeout; 579 unsigned long timeout;
588 u8 *chunk_buffer; 580 u8 *chunk_buffer;
@@ -614,20 +606,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
614 size = fw->size; 606 size = fw->size;
615 607
616 while (size) { 608 while (size) {
617 timeout = jiffies + HZ; 609 ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
618 while (1) { 610 if (ret)
619 status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); 611 goto release;
620 if (ret)
621 goto release;
622 if ((status & IF_SDIO_IO_RDY) &&
623 (status & IF_SDIO_DL_RDY))
624 break;
625 if (time_after(jiffies, timeout)) {
626 ret = -ETIMEDOUT;
627 goto release;
628 }
629 mdelay(1);
630 }
631 612
632 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); 613 req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
633 if (ret) 614 if (ret)
@@ -943,6 +924,7 @@ static int if_sdio_probe(struct sdio_func *func,
943 int ret, i; 924 int ret, i;
944 unsigned int model; 925 unsigned int model;
945 struct if_sdio_packet *packet; 926 struct if_sdio_packet *packet;
927 struct mmc_host *host = func->card->host;
946 928
947 lbs_deb_enter(LBS_DEB_SDIO); 929 lbs_deb_enter(LBS_DEB_SDIO);
948 930
@@ -1023,6 +1005,25 @@ static int if_sdio_probe(struct sdio_func *func,
1023 if (ret) 1005 if (ret)
1024 goto disable; 1006 goto disable;
1025 1007
1008 /* For 1-bit transfers to the 8686 model, we need to enable the
1009 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1010 * bit to allow access to non-vendor registers. */
1011 if ((card->model == IF_SDIO_MODEL_8686) &&
1012 (host->caps & MMC_CAP_SDIO_IRQ) &&
1013 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1014 u8 reg;
1015
1016 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
1017 reg = sdio_f0_readb(func, SDIO_CCCR_IF, &ret);
1018 if (ret)
1019 goto release_int;
1020
1021 reg |= SDIO_BUS_ECSI;
1022 sdio_f0_writeb(func, reg, SDIO_CCCR_IF, &ret);
1023 if (ret)
1024 goto release_int;
1025 }
1026
1026 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); 1027 card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
1027 if (ret) 1028 if (ret)
1028 goto release_int; 1029 goto release_int;
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index fcea5741ba62..f41594c7ac16 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -133,8 +133,6 @@ static void if_usb_write_bulk_callback(struct urb *urb)
133 /* print the failure status number for debug */ 133 /* print the failure status number for debug */
134 lbs_pr_info("URB in failure status: %d\n", urb->status); 134 lbs_pr_info("URB in failure status: %d\n", urb->status);
135 } 135 }
136
137 return;
138} 136}
139 137
140/** 138/**
@@ -651,8 +649,6 @@ static void if_usb_receive_fwload(struct urb *urb)
651 if_usb_submit_rx_urb_fwload(cardp); 649 if_usb_submit_rx_urb_fwload(cardp);
652 650
653 kfree(syncfwheader); 651 kfree(syncfwheader);
654
655 return;
656} 652}
657 653
658#define MRVDRV_MIN_PKT_LEN 30 654#define MRVDRV_MIN_PKT_LEN 30
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 598080414b17..d9b8ee130c45 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -229,7 +229,7 @@ static void lbs_tx_timeout(struct net_device *dev)
229 229
230 lbs_pr_err("tx watch dog timeout\n"); 230 lbs_pr_err("tx watch dog timeout\n");
231 231
232 dev->trans_start = jiffies; 232 dev->trans_start = jiffies; /* prevent tx timeout */
233 233
234 if (priv->currenttxskb) 234 if (priv->currenttxskb)
235 lbs_send_tx_feedback(priv, 0); 235 lbs_send_tx_feedback(priv, 0);
@@ -319,7 +319,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
319 struct net_device *dev, int nr_addrs) 319 struct net_device *dev, int nr_addrs)
320{ 320{
321 int i = nr_addrs; 321 int i = nr_addrs;
322 struct dev_mc_list *mc_list; 322 struct netdev_hw_addr *ha;
323 int cnt; 323 int cnt;
324 324
325 if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST)) 325 if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
@@ -327,19 +327,19 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
327 327
328 netif_addr_lock_bh(dev); 328 netif_addr_lock_bh(dev);
329 cnt = netdev_mc_count(dev); 329 cnt = netdev_mc_count(dev);
330 netdev_for_each_mc_addr(mc_list, dev) { 330 netdev_for_each_mc_addr(ha, dev) {
331 if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { 331 if (mac_in_list(cmd->maclist, nr_addrs, ha->addr)) {
332 lbs_deb_net("mcast address %s:%pM skipped\n", dev->name, 332 lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
333 mc_list->dmi_addr); 333 ha->addr);
334 cnt--; 334 cnt--;
335 continue; 335 continue;
336 } 336 }
337 337
338 if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE) 338 if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
339 break; 339 break;
340 memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN); 340 memcpy(&cmd->maclist[6*i], ha->addr, ETH_ALEN);
341 lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name, 341 lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
342 mc_list->dmi_addr); 342 ha->addr);
343 i++; 343 i++;
344 cnt--; 344 cnt--;
345 } 345 }
@@ -836,6 +836,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
836 priv->is_auto_deep_sleep_enabled = 0; 836 priv->is_auto_deep_sleep_enabled = 0;
837 priv->wakeup_dev_required = 0; 837 priv->wakeup_dev_required = 0;
838 init_waitqueue_head(&priv->ds_awake_q); 838 init_waitqueue_head(&priv->ds_awake_q);
839 priv->authtype_auto = 1;
839 840
840 mutex_init(&priv->lock); 841 mutex_init(&priv->lock);
841 842
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 784dae714705..a115bfa9513a 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -39,10 +39,10 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
39 struct sk_buff *skb); 39 struct sk_buff *skb);
40 40
41/** 41/**
42 * @brief This function computes the avgSNR . 42 * @brief This function computes the avgSNR .
43 * 43 *
44 * @param priv A pointer to struct lbs_private structure 44 * @param priv A pointer to struct lbs_private structure
45 * @return avgSNR 45 * @return avgSNR
46 */ 46 */
47static u8 lbs_getavgsnr(struct lbs_private *priv) 47static u8 lbs_getavgsnr(struct lbs_private *priv)
48{ 48{
@@ -57,10 +57,10 @@ static u8 lbs_getavgsnr(struct lbs_private *priv)
57} 57}
58 58
59/** 59/**
60 * @brief This function computes the AvgNF 60 * @brief This function computes the AvgNF
61 * 61 *
62 * @param priv A pointer to struct lbs_private structure 62 * @param priv A pointer to struct lbs_private structure
63 * @return AvgNF 63 * @return AvgNF
64 */ 64 */
65static u8 lbs_getavgnf(struct lbs_private *priv) 65static u8 lbs_getavgnf(struct lbs_private *priv)
66{ 66{
@@ -75,11 +75,11 @@ static u8 lbs_getavgnf(struct lbs_private *priv)
75} 75}
76 76
77/** 77/**
78 * @brief This function save the raw SNR/NF to our internel buffer 78 * @brief This function save the raw SNR/NF to our internel buffer
79 * 79 *
80 * @param priv A pointer to struct lbs_private structure 80 * @param priv A pointer to struct lbs_private structure
81 * @param prxpd A pointer to rxpd structure of received packet 81 * @param prxpd A pointer to rxpd structure of received packet
82 * @return n/a 82 * @return n/a
83 */ 83 */
84static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) 84static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
85{ 85{
@@ -90,15 +90,14 @@ static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
90 priv->nextSNRNF++; 90 priv->nextSNRNF++;
91 if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR) 91 if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
92 priv->nextSNRNF = 0; 92 priv->nextSNRNF = 0;
93 return;
94} 93}
95 94
96/** 95/**
97 * @brief This function computes the RSSI in received packet. 96 * @brief This function computes the RSSI in received packet.
98 * 97 *
99 * @param priv A pointer to struct lbs_private structure 98 * @param priv A pointer to struct lbs_private structure
100 * @param prxpd A pointer to rxpd structure of received packet 99 * @param prxpd A pointer to rxpd structure of received packet
101 * @return n/a 100 * @return n/a
102 */ 101 */
103static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) 102static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
104{ 103{
@@ -135,9 +134,9 @@ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
135 * @brief This function processes received packet and forwards it 134 * @brief This function processes received packet and forwards it
136 * to kernel/upper layer 135 * to kernel/upper layer
137 * 136 *
138 * @param priv A pointer to struct lbs_private 137 * @param priv A pointer to struct lbs_private
139 * @param skb A pointer to skb which includes the received packet 138 * @param skb A pointer to skb which includes the received packet
140 * @return 0 or -1 139 * @return 0 or -1
141 */ 140 */
142int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) 141int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
143{ 142{
@@ -197,7 +196,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
197 * before the snap_type. 196 * before the snap_type.
198 */ 197 */
199 p_ethhdr = (struct ethhdr *) 198 p_ethhdr = (struct ethhdr *)
200 ((u8 *) & p_rx_pkt->eth803_hdr 199 ((u8 *) &p_rx_pkt->eth803_hdr
201 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) 200 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr)
202 - sizeof(p_rx_pkt->eth803_hdr.dest_addr) 201 - sizeof(p_rx_pkt->eth803_hdr.dest_addr)
203 - sizeof(p_rx_pkt->eth803_hdr.src_addr) 202 - sizeof(p_rx_pkt->eth803_hdr.src_addr)
@@ -214,7 +213,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
214 hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; 213 hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
215 } else { 214 } else {
216 lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", 215 lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
217 (u8 *) & p_rx_pkt->rfc1042_hdr, 216 (u8 *) &p_rx_pkt->rfc1042_hdr,
218 sizeof(p_rx_pkt->rfc1042_hdr)); 217 sizeof(p_rx_pkt->rfc1042_hdr));
219 218
220 /* Chop off the rxpd */ 219 /* Chop off the rxpd */
@@ -255,8 +254,8 @@ EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
255 * @brief This function converts Tx/Rx rates from the Marvell WLAN format 254 * @brief This function converts Tx/Rx rates from the Marvell WLAN format
256 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) 255 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
257 * 256 *
258 * @param rate Input rate 257 * @param rate Input rate
259 * @return Output Rate (0 if invalid) 258 * @return Output Rate (0 if invalid)
260 */ 259 */
261static u8 convert_mv_rate_to_radiotap(u8 rate) 260static u8 convert_mv_rate_to_radiotap(u8 rate)
262{ 261{
@@ -295,9 +294,9 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
295 * @brief This function processes a received 802.11 packet and forwards it 294 * @brief This function processes a received 802.11 packet and forwards it
296 * to kernel/upper layer 295 * to kernel/upper layer
297 * 296 *
298 * @param priv A pointer to struct lbs_private 297 * @param priv A pointer to struct lbs_private
299 * @param skb A pointer to skb which includes the received packet 298 * @param skb A pointer to skb which includes the received packet
300 * @return 0 or -1 299 * @return 0 or -1
301 */ 300 */
302static int process_rxed_802_11_packet(struct lbs_private *priv, 301static int process_rxed_802_11_packet(struct lbs_private *priv,
303 struct sk_buff *skb) 302 struct sk_buff *skb)
@@ -314,7 +313,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
314 p_rx_pkt = (struct rx80211packethdr *) skb->data; 313 p_rx_pkt = (struct rx80211packethdr *) skb->data;
315 prxpd = &p_rx_pkt->rx_pd; 314 prxpd = &p_rx_pkt->rx_pd;
316 315
317 // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); 316 /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */
318 317
319 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { 318 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
320 lbs_deb_rx("rx err: frame received with bad length\n"); 319 lbs_deb_rx("rx err: frame received with bad length\n");
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 52d244ea3d97..a9bf658659eb 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -147,8 +147,6 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
147 dev->stats.tx_packets++; 147 dev->stats.tx_packets++;
148 dev->stats.tx_bytes += skb->len; 148 dev->stats.tx_bytes += skb->len;
149 149
150 dev->trans_start = jiffies;
151
152 if (priv->monitormode) { 150 if (priv->monitormode) {
153 /* Keep the skb to echo it back once Tx feedback is 151 /* Keep the skb to echo it back once Tx feedback is
154 received from FW */ 152 received from FW */
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 9b555884b08a..f96a96031a50 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1441,8 +1441,10 @@ static int lbs_set_encode(struct net_device *dev,
1441 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); 1441 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
1442 1442
1443 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1443 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1444 priv->authtype_auto = 0;
1444 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1445 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1445 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1446 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1447 priv->authtype_auto = 0;
1446 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1448 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1447 } 1449 }
1448 1450
@@ -1621,8 +1623,10 @@ static int lbs_set_encodeext(struct net_device *dev,
1621 goto out; 1623 goto out;
1622 1624
1623 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1625 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1626 priv->authtype_auto = 0;
1624 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1627 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1625 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1628 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1629 priv->authtype_auto = 0;
1626 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1630 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1627 } 1631 }
1628 1632
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index b620daf59ef7..8945afd6ce3e 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -7,6 +7,8 @@
7 * the Free Software Foundation; either version 2 of the License, or (at 7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version. 8 * your option) any later version.
9 */ 9 */
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
10#include <linux/slab.h> 12#include <linux/slab.h>
11 13
12#include "libertas_tf.h" 14#include "libertas_tf.h"
@@ -82,6 +84,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
82 int ret = -1; 84 int ret = -1;
83 u32 i; 85 u32 i;
84 86
87 lbtf_deb_enter(LBTF_DEB_CMD);
88
85 memset(&cmd, 0, sizeof(cmd)); 89 memset(&cmd, 0, sizeof(cmd));
86 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 90 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
87 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); 91 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
@@ -104,6 +108,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
104 priv->fwrelease >> 8 & 0xff, 108 priv->fwrelease >> 8 & 0xff,
105 priv->fwrelease & 0xff, 109 priv->fwrelease & 0xff,
106 priv->fwcapinfo); 110 priv->fwcapinfo);
111 lbtf_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
112 cmd.hwifversion, cmd.version);
107 113
108 /* Clamp region code to 8-bit since FW spec indicates that it should 114 /* Clamp region code to 8-bit since FW spec indicates that it should
109 * only ever be 8-bit, even though the field size is 16-bit. Some 115 * only ever be 8-bit, even though the field size is 16-bit. Some
@@ -118,8 +124,10 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
118 } 124 }
119 125
120 /* if it's unidentified region code, use the default (USA) */ 126 /* if it's unidentified region code, use the default (USA) */
121 if (i >= MRVDRV_MAX_REGION_CODE) 127 if (i >= MRVDRV_MAX_REGION_CODE) {
122 priv->regioncode = 0x10; 128 priv->regioncode = 0x10;
129 pr_info("unidentified region code; using the default (USA)\n");
130 }
123 131
124 if (priv->current_addr[0] == 0xff) 132 if (priv->current_addr[0] == 0xff)
125 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); 133 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
@@ -128,6 +136,7 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
128 136
129 lbtf_geo_init(priv); 137 lbtf_geo_init(priv);
130out: 138out:
139 lbtf_deb_leave(LBTF_DEB_CMD);
131 return ret; 140 return ret;
132} 141}
133 142
@@ -141,13 +150,18 @@ out:
141 */ 150 */
142int lbtf_set_channel(struct lbtf_private *priv, u8 channel) 151int lbtf_set_channel(struct lbtf_private *priv, u8 channel)
143{ 152{
153 int ret = 0;
144 struct cmd_ds_802_11_rf_channel cmd; 154 struct cmd_ds_802_11_rf_channel cmd;
145 155
156 lbtf_deb_enter(LBTF_DEB_CMD);
157
146 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 158 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
147 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); 159 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
148 cmd.channel = cpu_to_le16(channel); 160 cmd.channel = cpu_to_le16(channel);
149 161
150 return lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); 162 ret = lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
163 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
164 return ret;
151} 165}
152 166
153int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) 167int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon)
@@ -155,20 +169,28 @@ int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon)
155 struct cmd_ds_802_11_beacon_set cmd; 169 struct cmd_ds_802_11_beacon_set cmd;
156 int size; 170 int size;
157 171
158 if (beacon->len > MRVL_MAX_BCN_SIZE) 172 lbtf_deb_enter(LBTF_DEB_CMD);
173
174 if (beacon->len > MRVL_MAX_BCN_SIZE) {
175 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", -1);
159 return -1; 176 return -1;
177 }
160 size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len; 178 size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len;
161 cmd.hdr.size = cpu_to_le16(size); 179 cmd.hdr.size = cpu_to_le16(size);
162 cmd.len = cpu_to_le16(beacon->len); 180 cmd.len = cpu_to_le16(beacon->len);
163 memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len); 181 memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len);
164 182
165 lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size); 183 lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size);
184
185 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", 0);
166 return 0; 186 return 0;
167} 187}
168 188
169int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, 189int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable,
170 int beacon_int) { 190 int beacon_int)
191{
171 struct cmd_ds_802_11_beacon_control cmd; 192 struct cmd_ds_802_11_beacon_control cmd;
193 lbtf_deb_enter(LBTF_DEB_CMD);
172 194
173 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 195 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
174 cmd.action = cpu_to_le16(CMD_ACT_SET); 196 cmd.action = cpu_to_le16(CMD_ACT_SET);
@@ -176,6 +198,8 @@ int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable,
176 cmd.beacon_period = cpu_to_le16(beacon_int); 198 cmd.beacon_period = cpu_to_le16(beacon_int);
177 199
178 lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd)); 200 lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd));
201
202 lbtf_deb_leave(LBTF_DEB_CMD);
179 return 0; 203 return 0;
180} 204}
181 205
@@ -183,17 +207,28 @@ static void lbtf_queue_cmd(struct lbtf_private *priv,
183 struct cmd_ctrl_node *cmdnode) 207 struct cmd_ctrl_node *cmdnode)
184{ 208{
185 unsigned long flags; 209 unsigned long flags;
210 lbtf_deb_enter(LBTF_DEB_HOST);
186 211
187 if (!cmdnode) 212 if (!cmdnode) {
188 return; 213 lbtf_deb_host("QUEUE_CMD: cmdnode is NULL\n");
214 goto qcmd_done;
215 }
189 216
190 if (!cmdnode->cmdbuf->size) 217 if (!cmdnode->cmdbuf->size) {
191 return; 218 lbtf_deb_host("DNLD_CMD: cmd size is zero\n");
219 goto qcmd_done;
220 }
192 221
193 cmdnode->result = 0; 222 cmdnode->result = 0;
194 spin_lock_irqsave(&priv->driver_lock, flags); 223 spin_lock_irqsave(&priv->driver_lock, flags);
195 list_add_tail(&cmdnode->list, &priv->cmdpendingq); 224 list_add_tail(&cmdnode->list, &priv->cmdpendingq);
196 spin_unlock_irqrestore(&priv->driver_lock, flags); 225 spin_unlock_irqrestore(&priv->driver_lock, flags);
226
227 lbtf_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
228 le16_to_cpu(cmdnode->cmdbuf->command));
229
230qcmd_done:
231 lbtf_deb_leave(LBTF_DEB_HOST);
197} 232}
198 233
199static void lbtf_submit_command(struct lbtf_private *priv, 234static void lbtf_submit_command(struct lbtf_private *priv,
@@ -206,22 +241,33 @@ static void lbtf_submit_command(struct lbtf_private *priv,
206 int timeo = 5 * HZ; 241 int timeo = 5 * HZ;
207 int ret; 242 int ret;
208 243
244 lbtf_deb_enter(LBTF_DEB_HOST);
245
209 cmd = cmdnode->cmdbuf; 246 cmd = cmdnode->cmdbuf;
210 247
211 spin_lock_irqsave(&priv->driver_lock, flags); 248 spin_lock_irqsave(&priv->driver_lock, flags);
212 priv->cur_cmd = cmdnode; 249 priv->cur_cmd = cmdnode;
213 cmdsize = le16_to_cpu(cmd->size); 250 cmdsize = le16_to_cpu(cmd->size);
214 command = le16_to_cpu(cmd->command); 251 command = le16_to_cpu(cmd->command);
252
253 lbtf_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
254 command, le16_to_cpu(cmd->seqnum), cmdsize);
255 lbtf_deb_hex(LBTF_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
256
215 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 257 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
216 spin_unlock_irqrestore(&priv->driver_lock, flags); 258 spin_unlock_irqrestore(&priv->driver_lock, flags);
217 259
218 if (ret) 260 if (ret) {
261 pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
219 /* Let the timer kick in and retry, and potentially reset 262 /* Let the timer kick in and retry, and potentially reset
220 the whole thing if the condition persists */ 263 the whole thing if the condition persists */
221 timeo = HZ; 264 timeo = HZ;
265 }
222 266
223 /* Setup the timer after transmit command */ 267 /* Setup the timer after transmit command */
224 mod_timer(&priv->command_timer, jiffies + timeo); 268 mod_timer(&priv->command_timer, jiffies + timeo);
269
270 lbtf_deb_leave(LBTF_DEB_HOST);
225} 271}
226 272
227/** 273/**
@@ -231,8 +277,10 @@ static void lbtf_submit_command(struct lbtf_private *priv,
231static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, 277static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
232 struct cmd_ctrl_node *cmdnode) 278 struct cmd_ctrl_node *cmdnode)
233{ 279{
280 lbtf_deb_enter(LBTF_DEB_HOST);
281
234 if (!cmdnode) 282 if (!cmdnode)
235 return; 283 goto cl_ins_out;
236 284
237 cmdnode->callback = NULL; 285 cmdnode->callback = NULL;
238 cmdnode->callback_arg = 0; 286 cmdnode->callback_arg = 0;
@@ -240,6 +288,9 @@ static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
240 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); 288 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
241 289
242 list_add_tail(&cmdnode->list, &priv->cmdfreeq); 290 list_add_tail(&cmdnode->list, &priv->cmdfreeq);
291
292cl_ins_out:
293 lbtf_deb_leave(LBTF_DEB_HOST);
243} 294}
244 295
245static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, 296static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
@@ -268,29 +319,41 @@ int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv)
268{ 319{
269 struct cmd_ds_mac_multicast_addr cmd; 320 struct cmd_ds_mac_multicast_addr cmd;
270 321
322 lbtf_deb_enter(LBTF_DEB_CMD);
323
271 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 324 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
272 cmd.action = cpu_to_le16(CMD_ACT_SET); 325 cmd.action = cpu_to_le16(CMD_ACT_SET);
273 326
274 cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr); 327 cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
328
329 lbtf_deb_cmd("MULTICAST_ADR: setting %d addresses\n", cmd.nr_of_adrs);
330
275 memcpy(cmd.maclist, priv->multicastlist, 331 memcpy(cmd.maclist, priv->multicastlist,
276 priv->nr_of_multicastmacaddr * ETH_ALEN); 332 priv->nr_of_multicastmacaddr * ETH_ALEN);
277 333
278 lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd)); 334 lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd));
335
336 lbtf_deb_leave(LBTF_DEB_CMD);
279 return 0; 337 return 0;
280} 338}
281 339
282void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) 340void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode)
283{ 341{
284 struct cmd_ds_set_mode cmd; 342 struct cmd_ds_set_mode cmd;
343 lbtf_deb_enter(LBTF_DEB_WEXT);
285 344
286 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 345 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
287 cmd.mode = cpu_to_le16(mode); 346 cmd.mode = cpu_to_le16(mode);
347 lbtf_deb_wext("Switching to mode: 0x%x\n", mode);
288 lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); 348 lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
349
350 lbtf_deb_leave(LBTF_DEB_WEXT);
289} 351}
290 352
291void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) 353void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
292{ 354{
293 struct cmd_ds_set_bssid cmd; 355 struct cmd_ds_set_bssid cmd;
356 lbtf_deb_enter(LBTF_DEB_CMD);
294 357
295 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 358 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
296 cmd.activate = activate ? 1 : 0; 359 cmd.activate = activate ? 1 : 0;
@@ -298,11 +361,13 @@ void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
298 memcpy(cmd.bssid, bssid, ETH_ALEN); 361 memcpy(cmd.bssid, bssid, ETH_ALEN);
299 362
300 lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd)); 363 lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd));
364 lbtf_deb_leave(LBTF_DEB_CMD);
301} 365}
302 366
303int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) 367int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr)
304{ 368{
305 struct cmd_ds_802_11_mac_address cmd; 369 struct cmd_ds_802_11_mac_address cmd;
370 lbtf_deb_enter(LBTF_DEB_CMD);
306 371
307 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 372 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
308 cmd.action = cpu_to_le16(CMD_ACT_SET); 373 cmd.action = cpu_to_le16(CMD_ACT_SET);
@@ -310,6 +375,7 @@ int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr)
310 memcpy(cmd.macadd, mac_addr, ETH_ALEN); 375 memcpy(cmd.macadd, mac_addr, ETH_ALEN);
311 376
312 lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd)); 377 lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd));
378 lbtf_deb_leave(LBTF_DEB_CMD);
313 return 0; 379 return 0;
314} 380}
315 381
@@ -318,6 +384,8 @@ int lbtf_set_radio_control(struct lbtf_private *priv)
318 int ret = 0; 384 int ret = 0;
319 struct cmd_ds_802_11_radio_control cmd; 385 struct cmd_ds_802_11_radio_control cmd;
320 386
387 lbtf_deb_enter(LBTF_DEB_CMD);
388
321 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 389 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
322 cmd.action = cpu_to_le16(CMD_ACT_SET); 390 cmd.action = cpu_to_le16(CMD_ACT_SET);
323 391
@@ -341,19 +409,28 @@ int lbtf_set_radio_control(struct lbtf_private *priv)
341 else 409 else
342 cmd.control &= cpu_to_le16(~TURN_ON_RF); 410 cmd.control &= cpu_to_le16(~TURN_ON_RF);
343 411
412 lbtf_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
413 priv->preamble);
414
344 ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 415 ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
416
417 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
345 return ret; 418 return ret;
346} 419}
347 420
348void lbtf_set_mac_control(struct lbtf_private *priv) 421void lbtf_set_mac_control(struct lbtf_private *priv)
349{ 422{
350 struct cmd_ds_mac_control cmd; 423 struct cmd_ds_mac_control cmd;
424 lbtf_deb_enter(LBTF_DEB_CMD);
425
351 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 426 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
352 cmd.action = cpu_to_le16(priv->mac_control); 427 cmd.action = cpu_to_le16(priv->mac_control);
353 cmd.reserved = 0; 428 cmd.reserved = 0;
354 429
355 lbtf_cmd_async(priv, CMD_MAC_CONTROL, 430 lbtf_cmd_async(priv, CMD_MAC_CONTROL,
356 &cmd.hdr, sizeof(cmd)); 431 &cmd.hdr, sizeof(cmd));
432
433 lbtf_deb_leave(LBTF_DEB_CMD);
357} 434}
358 435
359/** 436/**
@@ -365,29 +442,43 @@ void lbtf_set_mac_control(struct lbtf_private *priv)
365 */ 442 */
366int lbtf_allocate_cmd_buffer(struct lbtf_private *priv) 443int lbtf_allocate_cmd_buffer(struct lbtf_private *priv)
367{ 444{
445 int ret = 0;
368 u32 bufsize; 446 u32 bufsize;
369 u32 i; 447 u32 i;
370 struct cmd_ctrl_node *cmdarray; 448 struct cmd_ctrl_node *cmdarray;
371 449
450 lbtf_deb_enter(LBTF_DEB_HOST);
451
372 /* Allocate and initialize the command array */ 452 /* Allocate and initialize the command array */
373 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; 453 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
374 cmdarray = kzalloc(bufsize, GFP_KERNEL); 454 cmdarray = kzalloc(bufsize, GFP_KERNEL);
375 if (!cmdarray) 455 if (!cmdarray) {
376 return -1; 456 lbtf_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
457 ret = -1;
458 goto done;
459 }
377 priv->cmd_array = cmdarray; 460 priv->cmd_array = cmdarray;
378 461
379 /* Allocate and initialize each command buffer in the command array */ 462 /* Allocate and initialize each command buffer in the command array */
380 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 463 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
381 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); 464 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
382 if (!cmdarray[i].cmdbuf) 465 if (!cmdarray[i].cmdbuf) {
383 return -1; 466 lbtf_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
467 ret = -1;
468 goto done;
469 }
384 } 470 }
385 471
386 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 472 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
387 init_waitqueue_head(&cmdarray[i].cmdwait_q); 473 init_waitqueue_head(&cmdarray[i].cmdwait_q);
388 lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]); 474 lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]);
389 } 475 }
390 return 0; 476
477 ret = 0;
478
479done:
480 lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
481 return ret;
391} 482}
392 483
393/** 484/**
@@ -402,9 +493,13 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv)
402 struct cmd_ctrl_node *cmdarray; 493 struct cmd_ctrl_node *cmdarray;
403 unsigned int i; 494 unsigned int i;
404 495
496 lbtf_deb_enter(LBTF_DEB_HOST);
497
405 /* need to check if cmd array is allocated or not */ 498 /* need to check if cmd array is allocated or not */
406 if (priv->cmd_array == NULL) 499 if (priv->cmd_array == NULL) {
407 return 0; 500 lbtf_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
501 goto done;
502 }
408 503
409 cmdarray = priv->cmd_array; 504 cmdarray = priv->cmd_array;
410 505
@@ -418,6 +513,8 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv)
418 kfree(priv->cmd_array); 513 kfree(priv->cmd_array);
419 priv->cmd_array = NULL; 514 priv->cmd_array = NULL;
420 515
516done:
517 lbtf_deb_leave(LBTF_DEB_HOST);
421 return 0; 518 return 0;
422} 519}
423 520
@@ -433,6 +530,8 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv)
433 struct cmd_ctrl_node *tempnode; 530 struct cmd_ctrl_node *tempnode;
434 unsigned long flags; 531 unsigned long flags;
435 532
533 lbtf_deb_enter(LBTF_DEB_HOST);
534
436 if (!priv) 535 if (!priv)
437 return NULL; 536 return NULL;
438 537
@@ -442,11 +541,14 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv)
442 tempnode = list_first_entry(&priv->cmdfreeq, 541 tempnode = list_first_entry(&priv->cmdfreeq,
443 struct cmd_ctrl_node, list); 542 struct cmd_ctrl_node, list);
444 list_del(&tempnode->list); 543 list_del(&tempnode->list);
445 } else 544 } else {
545 lbtf_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
446 tempnode = NULL; 546 tempnode = NULL;
547 }
447 548
448 spin_unlock_irqrestore(&priv->driver_lock, flags); 549 spin_unlock_irqrestore(&priv->driver_lock, flags);
449 550
551 lbtf_deb_leave(LBTF_DEB_HOST);
450 return tempnode; 552 return tempnode;
451} 553}
452 554
@@ -462,16 +564,20 @@ int lbtf_execute_next_command(struct lbtf_private *priv)
462 struct cmd_ctrl_node *cmdnode = NULL; 564 struct cmd_ctrl_node *cmdnode = NULL;
463 struct cmd_header *cmd; 565 struct cmd_header *cmd;
464 unsigned long flags; 566 unsigned long flags;
567 int ret = 0;
465 568
466 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the 569 /* Debug group is lbtf_deb_THREAD and not lbtf_deb_HOST, because the
467 * only caller to us is lbtf_thread() and we get even when a 570 * only caller to us is lbtf_thread() and we get even when a
468 * data packet is received */ 571 * data packet is received */
572 lbtf_deb_enter(LBTF_DEB_THREAD);
469 573
470 spin_lock_irqsave(&priv->driver_lock, flags); 574 spin_lock_irqsave(&priv->driver_lock, flags);
471 575
472 if (priv->cur_cmd) { 576 if (priv->cur_cmd) {
577 pr_alert("EXEC_NEXT_CMD: already processing command!\n");
473 spin_unlock_irqrestore(&priv->driver_lock, flags); 578 spin_unlock_irqrestore(&priv->driver_lock, flags);
474 return -1; 579 ret = -1;
580 goto done;
475 } 581 }
476 582
477 if (!list_empty(&priv->cmdpendingq)) { 583 if (!list_empty(&priv->cmdpendingq)) {
@@ -483,11 +589,17 @@ int lbtf_execute_next_command(struct lbtf_private *priv)
483 cmd = cmdnode->cmdbuf; 589 cmd = cmdnode->cmdbuf;
484 590
485 list_del(&cmdnode->list); 591 list_del(&cmdnode->list);
592 lbtf_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
593 le16_to_cpu(cmd->command));
486 spin_unlock_irqrestore(&priv->driver_lock, flags); 594 spin_unlock_irqrestore(&priv->driver_lock, flags);
487 lbtf_submit_command(priv, cmdnode); 595 lbtf_submit_command(priv, cmdnode);
488 } else 596 } else
489 spin_unlock_irqrestore(&priv->driver_lock, flags); 597 spin_unlock_irqrestore(&priv->driver_lock, flags);
490 return 0; 598
599 ret = 0;
600done:
601 lbtf_deb_leave(LBTF_DEB_THREAD);
602 return ret;
491} 603}
492 604
493static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, 605static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
@@ -498,14 +610,22 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
498{ 610{
499 struct cmd_ctrl_node *cmdnode; 611 struct cmd_ctrl_node *cmdnode;
500 612
501 if (priv->surpriseremoved) 613 lbtf_deb_enter(LBTF_DEB_HOST);
502 return ERR_PTR(-ENOENT); 614
615 if (priv->surpriseremoved) {
616 lbtf_deb_host("PREP_CMD: card removed\n");
617 cmdnode = ERR_PTR(-ENOENT);
618 goto done;
619 }
503 620
504 cmdnode = lbtf_get_cmd_ctrl_node(priv); 621 cmdnode = lbtf_get_cmd_ctrl_node(priv);
505 if (cmdnode == NULL) { 622 if (cmdnode == NULL) {
623 lbtf_deb_host("PREP_CMD: cmdnode is NULL\n");
624
506 /* Wake up main thread to execute next command */ 625 /* Wake up main thread to execute next command */
507 queue_work(lbtf_wq, &priv->cmd_work); 626 queue_work(lbtf_wq, &priv->cmd_work);
508 return ERR_PTR(-ENOBUFS); 627 cmdnode = ERR_PTR(-ENOBUFS);
628 goto done;
509 } 629 }
510 630
511 cmdnode->callback = callback; 631 cmdnode->callback = callback;
@@ -520,17 +640,24 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
520 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); 640 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size);
521 cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); 641 cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum);
522 cmdnode->cmdbuf->result = 0; 642 cmdnode->cmdbuf->result = 0;
643
644 lbtf_deb_host("PREP_CMD: command 0x%04x\n", command);
645
523 cmdnode->cmdwaitqwoken = 0; 646 cmdnode->cmdwaitqwoken = 0;
524 lbtf_queue_cmd(priv, cmdnode); 647 lbtf_queue_cmd(priv, cmdnode);
525 queue_work(lbtf_wq, &priv->cmd_work); 648 queue_work(lbtf_wq, &priv->cmd_work);
526 649
650 done:
651 lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %p", cmdnode);
527 return cmdnode; 652 return cmdnode;
528} 653}
529 654
530void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command, 655void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command,
531 struct cmd_header *in_cmd, int in_cmd_size) 656 struct cmd_header *in_cmd, int in_cmd_size)
532{ 657{
658 lbtf_deb_enter(LBTF_DEB_CMD);
533 __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0); 659 __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0);
660 lbtf_deb_leave(LBTF_DEB_CMD);
534} 661}
535 662
536int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, 663int __lbtf_cmd(struct lbtf_private *priv, uint16_t command,
@@ -543,30 +670,35 @@ int __lbtf_cmd(struct lbtf_private *priv, uint16_t command,
543 unsigned long flags; 670 unsigned long flags;
544 int ret = 0; 671 int ret = 0;
545 672
673 lbtf_deb_enter(LBTF_DEB_HOST);
674
546 cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, 675 cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size,
547 callback, callback_arg); 676 callback, callback_arg);
548 if (IS_ERR(cmdnode)) 677 if (IS_ERR(cmdnode)) {
549 return PTR_ERR(cmdnode); 678 ret = PTR_ERR(cmdnode);
679 goto done;
680 }
550 681
551 might_sleep(); 682 might_sleep();
552 ret = wait_event_interruptible(cmdnode->cmdwait_q, 683 ret = wait_event_interruptible(cmdnode->cmdwait_q,
553 cmdnode->cmdwaitqwoken); 684 cmdnode->cmdwaitqwoken);
554 if (ret) { 685 if (ret) {
555 printk(KERN_DEBUG 686 pr_info("PREP_CMD: command 0x%04x interrupted by signal: %d\n",
556 "libertastf: command 0x%04x interrupted by signal", 687 command, ret);
557 command); 688 goto done;
558 return ret;
559 } 689 }
560 690
561 spin_lock_irqsave(&priv->driver_lock, flags); 691 spin_lock_irqsave(&priv->driver_lock, flags);
562 ret = cmdnode->result; 692 ret = cmdnode->result;
563 if (ret) 693 if (ret)
564 printk(KERN_DEBUG "libertastf: command 0x%04x failed: %d\n", 694 pr_info("PREP_CMD: command 0x%04x failed: %d\n",
565 command, ret); 695 command, ret);
566 696
567 __lbtf_cleanup_and_insert_cmd(priv, cmdnode); 697 __lbtf_cleanup_and_insert_cmd(priv, cmdnode);
568 spin_unlock_irqrestore(&priv->driver_lock, flags); 698 spin_unlock_irqrestore(&priv->driver_lock, flags);
569 699
700done:
701 lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
570 return ret; 702 return ret;
571} 703}
572EXPORT_SYMBOL_GPL(__lbtf_cmd); 704EXPORT_SYMBOL_GPL(__lbtf_cmd);
@@ -587,6 +719,8 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
587 unsigned long flags; 719 unsigned long flags;
588 uint16_t result; 720 uint16_t result;
589 721
722 lbtf_deb_enter(LBTF_DEB_CMD);
723
590 mutex_lock(&priv->lock); 724 mutex_lock(&priv->lock);
591 spin_lock_irqsave(&priv->driver_lock, flags); 725 spin_lock_irqsave(&priv->driver_lock, flags);
592 726
@@ -602,7 +736,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
602 result = le16_to_cpu(resp->result); 736 result = le16_to_cpu(resp->result);
603 737
604 if (net_ratelimit()) 738 if (net_ratelimit())
605 printk(KERN_DEBUG "libertastf: cmd response 0x%04x, seq %d, size %d\n", 739 pr_info("libertastf: cmd response 0x%04x, seq %d, size %d\n",
606 respcmd, le16_to_cpu(resp->seqnum), 740 respcmd, le16_to_cpu(resp->seqnum),
607 le16_to_cpu(resp->size)); 741 le16_to_cpu(resp->size));
608 742
@@ -639,7 +773,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
639 switch (respcmd) { 773 switch (respcmd) {
640 case CMD_RET(CMD_GET_HW_SPEC): 774 case CMD_RET(CMD_GET_HW_SPEC):
641 case CMD_RET(CMD_802_11_RESET): 775 case CMD_RET(CMD_802_11_RESET):
642 printk(KERN_DEBUG "libertastf: reset failed\n"); 776 pr_info("libertastf: reset failed\n");
643 break; 777 break;
644 778
645 } 779 }
@@ -666,5 +800,6 @@ int lbtf_process_rx_command(struct lbtf_private *priv)
666 800
667done: 801done:
668 mutex_unlock(&priv->lock); 802 mutex_unlock(&priv->lock);
803 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
669 return ret; 804 return ret;
670} 805}
diff --git a/drivers/net/wireless/libertas_tf/deb_defs.h b/drivers/net/wireless/libertas_tf/deb_defs.h
new file mode 100644
index 000000000000..ae753962d8b5
--- /dev/null
+++ b/drivers/net/wireless/libertas_tf/deb_defs.h
@@ -0,0 +1,104 @@
1/**
2 * This header file contains global constant/enum definitions,
3 * global variable declaration.
4 */
5#ifndef _LBS_DEB_DEFS_H_
6#define _LBS_DEB_EFS_H_
7
8#ifndef DRV_NAME
9#define DRV_NAME "libertas_tf"
10#endif
11
12#include <linux/spinlock.h>
13
14#ifdef CONFIG_LIBERTAS_THINFIRM_DEBUG
15#define DEBUG
16#define PROC_DEBUG
17#endif
18
19#define LBTF_DEB_ENTER 0x00000001
20#define LBTF_DEB_LEAVE 0x00000002
21#define LBTF_DEB_MAIN 0x00000004
22#define LBTF_DEB_NET 0x00000008
23#define LBTF_DEB_MESH 0x00000010
24#define LBTF_DEB_WEXT 0x00000020
25#define LBTF_DEB_IOCTL 0x00000040
26#define LBTF_DEB_SCAN 0x00000080
27#define LBTF_DEB_ASSOC 0x00000100
28#define LBTF_DEB_JOIN 0x00000200
29#define LBTF_DEB_11D 0x00000400
30#define LBTF_DEB_DEBUGFS 0x00000800
31#define LBTF_DEB_ETHTOOL 0x00001000
32#define LBTF_DEB_HOST 0x00002000
33#define LBTF_DEB_CMD 0x00004000
34#define LBTF_DEB_RX 0x00008000
35#define LBTF_DEB_TX 0x00010000
36#define LBTF_DEB_USB 0x00020000
37#define LBTF_DEB_CS 0x00040000
38#define LBTF_DEB_FW 0x00080000
39#define LBTF_DEB_THREAD 0x00100000
40#define LBTF_DEB_HEX 0x00200000
41#define LBTF_DEB_SDIO 0x00400000
42#define LBTF_DEB_MACOPS 0x00800000
43
44extern unsigned int lbtf_debug;
45
46
47#ifdef DEBUG
48#define LBTF_DEB_LL(grp, grpnam, fmt, args...) \
49do { if ((lbtf_debug & (grp)) == (grp)) \
50 printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \
51 in_interrupt() ? " (INT)" : "", ## args); } while (0)
52#else
53#define LBTF_DEB_LL(grp, grpnam, fmt, args...) do {} while (0)
54#endif
55
56#define lbtf_deb_enter(grp) \
57 LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s()\n", __func__);
58#define lbtf_deb_enter_args(grp, fmt, args...) \
59 LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s(" fmt ")\n", __func__, ## args);
60#define lbtf_deb_leave(grp) \
61 LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s()\n", __func__);
62#define lbtf_deb_leave_args(grp, fmt, args...) \
63 LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s(), " fmt "\n", \
64 __func__, ##args);
65#define lbtf_deb_main(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MAIN, " main", fmt, ##args)
66#define lbtf_deb_net(fmt, args...) LBTF_DEB_LL(LBTF_DEB_NET, " net", fmt, ##args)
67#define lbtf_deb_mesh(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MESH, " mesh", fmt, ##args)
68#define lbtf_deb_wext(fmt, args...) LBTF_DEB_LL(LBTF_DEB_WEXT, " wext", fmt, ##args)
69#define lbtf_deb_ioctl(fmt, args...) LBTF_DEB_LL(LBTF_DEB_IOCTL, " ioctl", fmt, ##args)
70#define lbtf_deb_scan(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SCAN, " scan", fmt, ##args)
71#define lbtf_deb_assoc(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ASSOC, " assoc", fmt, ##args)
72#define lbtf_deb_join(fmt, args...) LBTF_DEB_LL(LBTF_DEB_JOIN, " join", fmt, ##args)
73#define lbtf_deb_11d(fmt, args...) LBTF_DEB_LL(LBTF_DEB_11D, " 11d", fmt, ##args)
74#define lbtf_deb_debugfs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_DEBUGFS, " debugfs", fmt, ##args)
75#define lbtf_deb_ethtool(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ETHTOOL, " ethtool", fmt, ##args)
76#define lbtf_deb_host(fmt, args...) LBTF_DEB_LL(LBTF_DEB_HOST, " host", fmt, ##args)
77#define lbtf_deb_cmd(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CMD, " cmd", fmt, ##args)
78#define lbtf_deb_rx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_RX, " rx", fmt, ##args)
79#define lbtf_deb_tx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_TX, " tx", fmt, ##args)
80#define lbtf_deb_fw(fmt, args...) LBTF_DEB_LL(LBTF_DEB_FW, " fw", fmt, ##args)
81#define lbtf_deb_usb(fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usb", fmt, ##args)
82#define lbtf_deb_usbd(dev, fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usbd", "%s:" fmt, dev_name(dev), ##args)
83#define lbtf_deb_cs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CS, " cs", fmt, ##args)
84#define lbtf_deb_thread(fmt, args...) LBTF_DEB_LL(LBTF_DEB_THREAD, " thread", fmt, ##args)
85#define lbtf_deb_sdio(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SDIO, " thread", fmt, ##args)
86#define lbtf_deb_macops(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MACOPS, " thread", fmt, ##args)
87
88#ifdef DEBUG
89static inline void lbtf_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
90{
91 char newprompt[32];
92
93 if (len &&
94 (lbtf_debug & LBTF_DEB_HEX) &&
95 (lbtf_debug & grp)) {
96 snprintf(newprompt, sizeof(newprompt), DRV_NAME " %s: ", prompt);
97 print_hex_dump_bytes(prompt, DUMP_PREFIX_NONE, buf, len);
98 }
99}
100#else
101#define lbtf_deb_hex(grp, prompt, buf, len) do {} while (0)
102#endif
103
104#endif
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index 8cc9db60c14b..c445500ffc61 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -7,6 +7,13 @@
7 * the Free Software Foundation; either version 2 of the License, or (at 7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version. 8 * your option) any later version.
9 */ 9 */
10#define DRV_NAME "lbtf_usb"
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include "libertas_tf.h"
15#include "if_usb.h"
16
10#include <linux/delay.h> 17#include <linux/delay.h>
11#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
12#include <linux/firmware.h> 19#include <linux/firmware.h>
@@ -14,10 +21,8 @@
14#include <linux/slab.h> 21#include <linux/slab.h>
15#include <linux/usb.h> 22#include <linux/usb.h>
16 23
17#define DRV_NAME "lbtf_usb" 24#define INSANEDEBUG 0
18 25#define lbtf_deb_usb2(...) do { if (INSANEDEBUG) lbtf_deb_usbd(__VA_ARGS__); } while (0)
19#include "libertas_tf.h"
20#include "if_usb.h"
21 26
22#define MESSAGE_HEADER_LEN 4 27#define MESSAGE_HEADER_LEN 4
23 28
@@ -53,9 +58,14 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
53 */ 58 */
54static void if_usb_write_bulk_callback(struct urb *urb) 59static void if_usb_write_bulk_callback(struct urb *urb)
55{ 60{
56 if (urb->status != 0) 61 if (urb->status != 0) {
57 printk(KERN_INFO "libertastf: URB in failure status: %d\n", 62 /* print the failure status number for debug */
58 urb->status); 63 pr_info("URB in failure status: %d\n", urb->status);
64 } else {
65 lbtf_deb_usb2(&urb->dev->dev, "URB status is successful\n");
66 lbtf_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
67 urb->actual_length);
68 }
59} 69}
60 70
61/** 71/**
@@ -65,6 +75,8 @@ static void if_usb_write_bulk_callback(struct urb *urb)
65 */ 75 */
66static void if_usb_free(struct if_usb_card *cardp) 76static void if_usb_free(struct if_usb_card *cardp)
67{ 77{
78 lbtf_deb_enter(LBTF_DEB_USB);
79
68 /* Unlink tx & rx urb */ 80 /* Unlink tx & rx urb */
69 usb_kill_urb(cardp->tx_urb); 81 usb_kill_urb(cardp->tx_urb);
70 usb_kill_urb(cardp->rx_urb); 82 usb_kill_urb(cardp->rx_urb);
@@ -81,6 +93,8 @@ static void if_usb_free(struct if_usb_card *cardp)
81 93
82 kfree(cardp->ep_out_buf); 94 kfree(cardp->ep_out_buf);
83 cardp->ep_out_buf = NULL; 95 cardp->ep_out_buf = NULL;
96
97 lbtf_deb_leave(LBTF_DEB_USB);
84} 98}
85 99
86static void if_usb_setup_firmware(struct lbtf_private *priv) 100static void if_usb_setup_firmware(struct lbtf_private *priv)
@@ -88,23 +102,33 @@ static void if_usb_setup_firmware(struct lbtf_private *priv)
88 struct if_usb_card *cardp = priv->card; 102 struct if_usb_card *cardp = priv->card;
89 struct cmd_ds_set_boot2_ver b2_cmd; 103 struct cmd_ds_set_boot2_ver b2_cmd;
90 104
105 lbtf_deb_enter(LBTF_DEB_USB);
106
91 if_usb_submit_rx_urb(cardp); 107 if_usb_submit_rx_urb(cardp);
92 b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd)); 108 b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
93 b2_cmd.action = 0; 109 b2_cmd.action = 0;
94 b2_cmd.version = cardp->boot2_version; 110 b2_cmd.version = cardp->boot2_version;
95 111
96 if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd)) 112 if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
97 printk(KERN_INFO "libertastf: setting boot2 version failed\n"); 113 lbtf_deb_usb("Setting boot2 version failed\n");
114
115 lbtf_deb_leave(LBTF_DEB_USB);
98} 116}
99 117
100static void if_usb_fw_timeo(unsigned long priv) 118static void if_usb_fw_timeo(unsigned long priv)
101{ 119{
102 struct if_usb_card *cardp = (void *)priv; 120 struct if_usb_card *cardp = (void *)priv;
103 121
104 if (!cardp->fwdnldover) 122 lbtf_deb_enter(LBTF_DEB_USB);
123 if (!cardp->fwdnldover) {
105 /* Download timed out */ 124 /* Download timed out */
106 cardp->priv->surpriseremoved = 1; 125 cardp->priv->surpriseremoved = 1;
126 pr_err("Download timed out\n");
127 } else {
128 lbtf_deb_usb("Download complete, no event. Assuming success\n");
129 }
107 wake_up(&cardp->fw_wq); 130 wake_up(&cardp->fw_wq);
131 lbtf_deb_leave(LBTF_DEB_USB);
108} 132}
109 133
110/** 134/**
@@ -125,11 +149,14 @@ static int if_usb_probe(struct usb_interface *intf,
125 struct if_usb_card *cardp; 149 struct if_usb_card *cardp;
126 int i; 150 int i;
127 151
152 lbtf_deb_enter(LBTF_DEB_USB);
128 udev = interface_to_usbdev(intf); 153 udev = interface_to_usbdev(intf);
129 154
130 cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); 155 cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
131 if (!cardp) 156 if (!cardp) {
157 pr_err("Out of memory allocating private data.\n");
132 goto error; 158 goto error;
159 }
133 160
134 setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); 161 setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
135 init_waitqueue_head(&cardp->fw_wq); 162 init_waitqueue_head(&cardp->fw_wq);
@@ -137,38 +164,62 @@ static int if_usb_probe(struct usb_interface *intf,
137 cardp->udev = udev; 164 cardp->udev = udev;
138 iface_desc = intf->cur_altsetting; 165 iface_desc = intf->cur_altsetting;
139 166
167 lbtf_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
168 " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
169 le16_to_cpu(udev->descriptor.bcdUSB),
170 udev->descriptor.bDeviceClass,
171 udev->descriptor.bDeviceSubClass,
172 udev->descriptor.bDeviceProtocol);
173
140 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { 174 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
141 endpoint = &iface_desc->endpoint[i].desc; 175 endpoint = &iface_desc->endpoint[i].desc;
142 if (usb_endpoint_is_bulk_in(endpoint)) { 176 if (usb_endpoint_is_bulk_in(endpoint)) {
143 cardp->ep_in_size = 177 cardp->ep_in_size =
144 le16_to_cpu(endpoint->wMaxPacketSize); 178 le16_to_cpu(endpoint->wMaxPacketSize);
145 cardp->ep_in = usb_endpoint_num(endpoint); 179 cardp->ep_in = usb_endpoint_num(endpoint);
180
181 lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
182 lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
146 } else if (usb_endpoint_is_bulk_out(endpoint)) { 183 } else if (usb_endpoint_is_bulk_out(endpoint)) {
147 cardp->ep_out_size = 184 cardp->ep_out_size =
148 le16_to_cpu(endpoint->wMaxPacketSize); 185 le16_to_cpu(endpoint->wMaxPacketSize);
149 cardp->ep_out = usb_endpoint_num(endpoint); 186 cardp->ep_out = usb_endpoint_num(endpoint);
187
188 lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
189 lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n",
190 cardp->ep_out_size);
150 } 191 }
151 } 192 }
152 if (!cardp->ep_out_size || !cardp->ep_in_size) 193 if (!cardp->ep_out_size || !cardp->ep_in_size) {
194 lbtf_deb_usbd(&udev->dev, "Endpoints not found\n");
153 /* Endpoints not found */ 195 /* Endpoints not found */
154 goto dealloc; 196 goto dealloc;
197 }
155 198
156 cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 199 cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
157 if (!cardp->rx_urb) 200 if (!cardp->rx_urb) {
201 lbtf_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
158 goto dealloc; 202 goto dealloc;
203 }
159 204
160 cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 205 cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
161 if (!cardp->tx_urb) 206 if (!cardp->tx_urb) {
207 lbtf_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
162 goto dealloc; 208 goto dealloc;
209 }
163 210
164 cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL); 211 cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL);
165 if (!cardp->cmd_urb) 212 if (!cardp->cmd_urb) {
213 lbtf_deb_usbd(&udev->dev, "Cmd URB allocation failed\n");
166 goto dealloc; 214 goto dealloc;
215 }
167 216
168 cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, 217 cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
169 GFP_KERNEL); 218 GFP_KERNEL);
170 if (!cardp->ep_out_buf) 219 if (!cardp->ep_out_buf) {
220 lbtf_deb_usbd(&udev->dev, "Could not allocate buffer\n");
171 goto dealloc; 221 goto dealloc;
222 }
172 223
173 priv = lbtf_add_card(cardp, &udev->dev); 224 priv = lbtf_add_card(cardp, &udev->dev);
174 if (!priv) 225 if (!priv)
@@ -189,6 +240,7 @@ static int if_usb_probe(struct usb_interface *intf,
189dealloc: 240dealloc:
190 if_usb_free(cardp); 241 if_usb_free(cardp);
191error: 242error:
243lbtf_deb_leave(LBTF_DEB_MAIN);
192 return -ENOMEM; 244 return -ENOMEM;
193} 245}
194 246
@@ -202,6 +254,8 @@ static void if_usb_disconnect(struct usb_interface *intf)
202 struct if_usb_card *cardp = usb_get_intfdata(intf); 254 struct if_usb_card *cardp = usb_get_intfdata(intf);
203 struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; 255 struct lbtf_private *priv = (struct lbtf_private *) cardp->priv;
204 256
257 lbtf_deb_enter(LBTF_DEB_MAIN);
258
205 if_usb_reset_device(cardp); 259 if_usb_reset_device(cardp);
206 260
207 if (priv) 261 if (priv)
@@ -212,6 +266,8 @@ static void if_usb_disconnect(struct usb_interface *intf)
212 266
213 usb_set_intfdata(intf, NULL); 267 usb_set_intfdata(intf, NULL);
214 usb_put_dev(interface_to_usbdev(intf)); 268 usb_put_dev(interface_to_usbdev(intf));
269
270 lbtf_deb_leave(LBTF_DEB_MAIN);
215} 271}
216 272
217/** 273/**
@@ -226,6 +282,8 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
226 struct fwdata *fwdata = cardp->ep_out_buf; 282 struct fwdata *fwdata = cardp->ep_out_buf;
227 u8 *firmware = (u8 *) cardp->fw->data; 283 u8 *firmware = (u8 *) cardp->fw->data;
228 284
285 lbtf_deb_enter(LBTF_DEB_FW);
286
229 /* If we got a CRC failure on the last block, back 287 /* If we got a CRC failure on the last block, back
230 up and retry it */ 288 up and retry it */
231 if (!cardp->CRC_OK) { 289 if (!cardp->CRC_OK) {
@@ -233,6 +291,9 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
233 cardp->fwseqnum--; 291 cardp->fwseqnum--;
234 } 292 }
235 293
294 lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
295 cardp->totalbytes);
296
236 /* struct fwdata (which we sent to the card) has an 297 /* struct fwdata (which we sent to the card) has an
237 extra __le32 field in between the header and the data, 298 extra __le32 field in between the header and the data,
238 which is not in the struct fwheader in the actual 299 which is not in the struct fwheader in the actual
@@ -246,18 +307,33 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
246 memcpy(fwdata->data, &firmware[cardp->totalbytes], 307 memcpy(fwdata->data, &firmware[cardp->totalbytes],
247 le32_to_cpu(fwdata->hdr.datalength)); 308 le32_to_cpu(fwdata->hdr.datalength));
248 309
310 lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
311 le32_to_cpu(fwdata->hdr.datalength));
312
249 fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum); 313 fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
250 cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength); 314 cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
251 315
252 usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) + 316 usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
253 le32_to_cpu(fwdata->hdr.datalength), 0); 317 le32_to_cpu(fwdata->hdr.datalength), 0);
254 318
255 if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) 319 if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
320 lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
321 lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
322 cardp->fwseqnum, cardp->totalbytes);
323 } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
324 lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
325 lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
326
256 /* Host has finished FW downloading 327 /* Host has finished FW downloading
257 * Donwloading FW JUMP BLOCK 328 * Donwloading FW JUMP BLOCK
258 */ 329 */
259 cardp->fwfinalblk = 1; 330 cardp->fwfinalblk = 1;
331 }
260 332
333 lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
334 cardp->totalbytes);
335
336 lbtf_deb_leave(LBTF_DEB_FW);
261 return 0; 337 return 0;
262} 338}
263 339
@@ -266,6 +342,8 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
266 struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4; 342 struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4;
267 int ret; 343 int ret;
268 344
345 lbtf_deb_enter(LBTF_DEB_USB);
346
269 *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); 347 *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
270 348
271 cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET); 349 cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET);
@@ -280,6 +358,8 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
280 ret = usb_reset_device(cardp->udev); 358 ret = usb_reset_device(cardp->udev);
281 msleep(100); 359 msleep(100);
282 360
361 lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);
362
283 return ret; 363 return ret;
284} 364}
285EXPORT_SYMBOL_GPL(if_usb_reset_device); 365EXPORT_SYMBOL_GPL(if_usb_reset_device);
@@ -297,11 +377,15 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device);
297static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, 377static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
298 uint16_t nb, u8 data) 378 uint16_t nb, u8 data)
299{ 379{
380 int ret = -1;
300 struct urb *urb; 381 struct urb *urb;
301 382
383 lbtf_deb_enter(LBTF_DEB_USB);
302 /* check if device is removed */ 384 /* check if device is removed */
303 if (cardp->priv->surpriseremoved) 385 if (cardp->priv->surpriseremoved) {
304 return -1; 386 lbtf_deb_usbd(&cardp->udev->dev, "Device removed\n");
387 goto tx_ret;
388 }
305 389
306 if (data) 390 if (data)
307 urb = cardp->tx_urb; 391 urb = cardp->tx_urb;
@@ -315,19 +399,34 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
315 399
316 urb->transfer_flags |= URB_ZERO_PACKET; 400 urb->transfer_flags |= URB_ZERO_PACKET;
317 401
318 if (usb_submit_urb(urb, GFP_ATOMIC)) 402 if (usb_submit_urb(urb, GFP_ATOMIC)) {
319 return -1; 403 lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
320 return 0; 404 goto tx_ret;
405 }
406
407 lbtf_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
408
409 ret = 0;
410
411tx_ret:
412 lbtf_deb_leave(LBTF_DEB_USB);
413 return ret;
321} 414}
322 415
323static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, 416static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
324 void (*callbackfn)(struct urb *urb)) 417 void (*callbackfn)(struct urb *urb))
325{ 418{
326 struct sk_buff *skb; 419 struct sk_buff *skb;
420 int ret = -1;
421
422 lbtf_deb_enter(LBTF_DEB_USB);
327 423
328 skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); 424 skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
329 if (!skb) 425 if (!skb) {
426 pr_err("No free skb\n");
427 lbtf_deb_leave(LBTF_DEB_USB);
330 return -1; 428 return -1;
429 }
331 430
332 cardp->rx_skb = skb; 431 cardp->rx_skb = skb;
333 432
@@ -339,12 +438,19 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
339 438
340 cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; 439 cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
341 440
342 if (usb_submit_urb(cardp->rx_urb, GFP_ATOMIC)) { 441 lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
442 ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC);
443 if (ret) {
444 lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
343 kfree_skb(skb); 445 kfree_skb(skb);
344 cardp->rx_skb = NULL; 446 cardp->rx_skb = NULL;
447 lbtf_deb_leave(LBTF_DEB_USB);
345 return -1; 448 return -1;
346 } else 449 } else {
450 lbtf_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
451 lbtf_deb_leave(LBTF_DEB_USB);
347 return 0; 452 return 0;
453 }
348} 454}
349 455
350static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp) 456static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
@@ -364,8 +470,12 @@ static void if_usb_receive_fwload(struct urb *urb)
364 struct fwsyncheader *syncfwheader; 470 struct fwsyncheader *syncfwheader;
365 struct bootcmdresp bcmdresp; 471 struct bootcmdresp bcmdresp;
366 472
473 lbtf_deb_enter(LBTF_DEB_USB);
367 if (urb->status) { 474 if (urb->status) {
475 lbtf_deb_usbd(&cardp->udev->dev,
476 "URB status is failed during fw load\n");
368 kfree_skb(skb); 477 kfree_skb(skb);
478 lbtf_deb_leave(LBTF_DEB_USB);
369 return; 479 return;
370 } 480 }
371 481
@@ -373,12 +483,17 @@ static void if_usb_receive_fwload(struct urb *urb)
373 __le32 *tmp = (__le32 *)(skb->data); 483 __le32 *tmp = (__le32 *)(skb->data);
374 484
375 if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && 485 if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
376 tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) 486 tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
377 /* Firmware ready event received */ 487 /* Firmware ready event received */
488 pr_info("Firmware ready event received\n");
378 wake_up(&cardp->fw_wq); 489 wake_up(&cardp->fw_wq);
379 else 490 } else {
491 lbtf_deb_usb("Waiting for confirmation; got %x %x\n",
492 le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
380 if_usb_submit_rx_urb_fwload(cardp); 493 if_usb_submit_rx_urb_fwload(cardp);
494 }
381 kfree_skb(skb); 495 kfree_skb(skb);
496 lbtf_deb_leave(LBTF_DEB_USB);
382 return; 497 return;
383 } 498 }
384 if (cardp->bootcmdresp <= 0) { 499 if (cardp->bootcmdresp <= 0) {
@@ -389,34 +504,60 @@ static void if_usb_receive_fwload(struct urb *urb)
389 if_usb_submit_rx_urb_fwload(cardp); 504 if_usb_submit_rx_urb_fwload(cardp);
390 cardp->bootcmdresp = 1; 505 cardp->bootcmdresp = 1;
391 /* Received valid boot command response */ 506 /* Received valid boot command response */
507 lbtf_deb_usbd(&cardp->udev->dev,
508 "Received valid boot command response\n");
509 lbtf_deb_leave(LBTF_DEB_USB);
392 return; 510 return;
393 } 511 }
394 if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) { 512 if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
395 if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) || 513 if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
396 bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || 514 bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
397 bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) 515 bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
516 if (!cardp->bootcmdresp)
517 pr_info("Firmware already seems alive; resetting\n");
398 cardp->bootcmdresp = -1; 518 cardp->bootcmdresp = -1;
399 } else if (bcmdresp.cmd == BOOT_CMD_FW_BY_USB && 519 } else {
400 bcmdresp.result == BOOT_CMD_RESP_OK) 520 pr_info("boot cmd response wrong magic number (0x%x)\n",
521 le32_to_cpu(bcmdresp.magic));
522 }
523 } else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
524 pr_info("boot cmd response cmd_tag error (%d)\n",
525 bcmdresp.cmd);
526 } else if (bcmdresp.result != BOOT_CMD_RESP_OK) {
527 pr_info("boot cmd response result error (%d)\n",
528 bcmdresp.result);
529 } else {
401 cardp->bootcmdresp = 1; 530 cardp->bootcmdresp = 1;
531 lbtf_deb_usbd(&cardp->udev->dev,
532 "Received valid boot command response\n");
533 }
402 534
403 kfree_skb(skb); 535 kfree_skb(skb);
404 if_usb_submit_rx_urb_fwload(cardp); 536 if_usb_submit_rx_urb_fwload(cardp);
537 lbtf_deb_leave(LBTF_DEB_USB);
405 return; 538 return;
406 } 539 }
407 540
408 syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); 541 syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
409 if (!syncfwheader) { 542 if (!syncfwheader) {
543 lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
410 kfree_skb(skb); 544 kfree_skb(skb);
545 lbtf_deb_leave(LBTF_DEB_USB);
411 return; 546 return;
412 } 547 }
413 548
414 memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader)); 549 memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader));
415 550
416 if (!syncfwheader->cmd) 551 if (!syncfwheader->cmd) {
552 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
553 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
554 le32_to_cpu(syncfwheader->seqnum));
417 cardp->CRC_OK = 1; 555 cardp->CRC_OK = 1;
418 else 556 } else {
557 lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
419 cardp->CRC_OK = 0; 558 cardp->CRC_OK = 0;
559 }
560
420 kfree_skb(skb); 561 kfree_skb(skb);
421 562
422 /* reschedule timer for 200ms hence */ 563 /* reschedule timer for 200ms hence */
@@ -434,7 +575,7 @@ static void if_usb_receive_fwload(struct urb *urb)
434 575
435 kfree(syncfwheader); 576 kfree(syncfwheader);
436 577
437 return; 578 lbtf_deb_leave(LBTF_DEB_USB);
438} 579}
439 580
440#define MRVDRV_MIN_PKT_LEN 30 581#define MRVDRV_MIN_PKT_LEN 30
@@ -445,6 +586,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
445{ 586{
446 if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN 587 if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
447 || recvlength < MRVDRV_MIN_PKT_LEN) { 588 || recvlength < MRVDRV_MIN_PKT_LEN) {
589 lbtf_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
448 kfree_skb(skb); 590 kfree_skb(skb);
449 return; 591 return;
450 } 592 }
@@ -460,6 +602,8 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
460 struct lbtf_private *priv) 602 struct lbtf_private *priv)
461{ 603{
462 if (recvlength > LBS_CMD_BUFFER_SIZE) { 604 if (recvlength > LBS_CMD_BUFFER_SIZE) {
605 lbtf_deb_usbd(&cardp->udev->dev,
606 "The receive buffer is too large\n");
463 kfree_skb(skb); 607 kfree_skb(skb);
464 return; 608 return;
465 } 609 }
@@ -489,16 +633,24 @@ static void if_usb_receive(struct urb *urb)
489 uint32_t recvtype = 0; 633 uint32_t recvtype = 0;
490 __le32 *pkt = (__le32 *) skb->data; 634 __le32 *pkt = (__le32 *) skb->data;
491 635
636 lbtf_deb_enter(LBTF_DEB_USB);
637
492 if (recvlength) { 638 if (recvlength) {
493 if (urb->status) { 639 if (urb->status) {
640 lbtf_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
641 urb->status);
494 kfree_skb(skb); 642 kfree_skb(skb);
495 goto setup_for_next; 643 goto setup_for_next;
496 } 644 }
497 645
498 recvbuff = skb->data; 646 recvbuff = skb->data;
499 recvtype = le32_to_cpu(pkt[0]); 647 recvtype = le32_to_cpu(pkt[0]);
648 lbtf_deb_usbd(&cardp->udev->dev,
649 "Recv length = 0x%x, Recv type = 0x%X\n",
650 recvlength, recvtype);
500 } else if (urb->status) { 651 } else if (urb->status) {
501 kfree_skb(skb); 652 kfree_skb(skb);
653 lbtf_deb_leave(LBTF_DEB_USB);
502 return; 654 return;
503 } 655 }
504 656
@@ -515,6 +667,7 @@ static void if_usb_receive(struct urb *urb)
515 { 667 {
516 /* Event cause handling */ 668 /* Event cause handling */
517 u32 event_cause = le32_to_cpu(pkt[1]); 669 u32 event_cause = le32_to_cpu(pkt[1]);
670 lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause);
518 671
519 /* Icky undocumented magic special case */ 672 /* Icky undocumented magic special case */
520 if (event_cause & 0xffff0000) { 673 if (event_cause & 0xffff0000) {
@@ -529,21 +682,22 @@ static void if_usb_receive(struct urb *urb)
529 } else if (event_cause == LBTF_EVENT_BCN_SENT) 682 } else if (event_cause == LBTF_EVENT_BCN_SENT)
530 lbtf_bcn_sent(priv); 683 lbtf_bcn_sent(priv);
531 else 684 else
532 printk(KERN_DEBUG 685 lbtf_deb_usbd(&cardp->udev->dev,
533 "Unsupported notification %d received\n", 686 "Unsupported notification %d received\n",
534 event_cause); 687 event_cause);
535 kfree_skb(skb); 688 kfree_skb(skb);
536 break; 689 break;
537 } 690 }
538 default: 691 default:
539 printk(KERN_DEBUG "libertastf: unknown command type 0x%X\n", 692 lbtf_deb_usbd(&cardp->udev->dev,
540 recvtype); 693 "libertastf: unknown command type 0x%X\n", recvtype);
541 kfree_skb(skb); 694 kfree_skb(skb);
542 break; 695 break;
543 } 696 }
544 697
545setup_for_next: 698setup_for_next:
546 if_usb_submit_rx_urb(cardp); 699 if_usb_submit_rx_urb(cardp);
700 lbtf_deb_leave(LBTF_DEB_USB);
547} 701}
548 702
549/** 703/**
@@ -562,6 +716,9 @@ static int if_usb_host_to_card(struct lbtf_private *priv, uint8_t type,
562 struct if_usb_card *cardp = priv->card; 716 struct if_usb_card *cardp = priv->card;
563 u8 data = 0; 717 u8 data = 0;
564 718
719 lbtf_deb_usbd(&cardp->udev->dev, "*** type = %u\n", type);
720 lbtf_deb_usbd(&cardp->udev->dev, "size after = %d\n", nb);
721
565 if (type == MVMS_CMD) { 722 if (type == MVMS_CMD) {
566 *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); 723 *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
567 } else { 724 } else {
@@ -639,8 +796,10 @@ static int check_fwfile_format(const u8 *data, u32 totlen)
639 } while (!exit); 796 } while (!exit);
640 797
641 if (ret) 798 if (ret)
642 printk(KERN_INFO 799 pr_err("firmware file format check FAIL\n");
643 "libertastf: firmware file format check failed\n"); 800 else
801 lbtf_deb_fw("firmware file format check PASS\n");
802
644 return ret; 803 return ret;
645} 804}
646 805
@@ -651,10 +810,12 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
651 static int reset_count = 10; 810 static int reset_count = 10;
652 int ret = 0; 811 int ret = 0;
653 812
813 lbtf_deb_enter(LBTF_DEB_USB);
814
654 ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); 815 ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
655 if (ret < 0) { 816 if (ret < 0) {
656 printk(KERN_INFO "libertastf: firmware %s not found\n", 817 pr_err("request_firmware() failed with %#x\n", ret);
657 lbtf_fw_name); 818 pr_err("firmware %s not found\n", lbtf_fw_name);
658 goto done; 819 goto done;
659 } 820 }
660 821
@@ -663,6 +824,7 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
663 824
664restart: 825restart:
665 if (if_usb_submit_rx_urb_fwload(cardp) < 0) { 826 if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
827 lbtf_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
666 ret = -1; 828 ret = -1;
667 goto release_fw; 829 goto release_fw;
668 } 830 }
@@ -709,14 +871,13 @@ restart:
709 usb_kill_urb(cardp->rx_urb); 871 usb_kill_urb(cardp->rx_urb);
710 872
711 if (!cardp->fwdnldover) { 873 if (!cardp->fwdnldover) {
712 printk(KERN_INFO "libertastf: failed to load fw," 874 pr_info("failed to load fw, resetting device!\n");
713 " resetting device!\n");
714 if (--reset_count >= 0) { 875 if (--reset_count >= 0) {
715 if_usb_reset_device(cardp); 876 if_usb_reset_device(cardp);
716 goto restart; 877 goto restart;
717 } 878 }
718 879
719 printk(KERN_INFO "libertastf: fw download failure\n"); 880 pr_info("FW download failure, time = %d ms\n", i * 100);
720 ret = -1; 881 ret = -1;
721 goto release_fw; 882 goto release_fw;
722 } 883 }
@@ -730,6 +891,7 @@ restart:
730 if_usb_setup_firmware(cardp->priv); 891 if_usb_setup_firmware(cardp->priv);
731 892
732 done: 893 done:
894 lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);
733 return ret; 895 return ret;
734} 896}
735EXPORT_SYMBOL_GPL(if_usb_prog_firmware); 897EXPORT_SYMBOL_GPL(if_usb_prog_firmware);
@@ -751,13 +913,19 @@ static int __init if_usb_init_module(void)
751{ 913{
752 int ret = 0; 914 int ret = 0;
753 915
916 lbtf_deb_enter(LBTF_DEB_MAIN);
917
754 ret = usb_register(&if_usb_driver); 918 ret = usb_register(&if_usb_driver);
919
920 lbtf_deb_leave_args(LBTF_DEB_MAIN, "ret %d", ret);
755 return ret; 921 return ret;
756} 922}
757 923
758static void __exit if_usb_exit_module(void) 924static void __exit if_usb_exit_module(void)
759{ 925{
926 lbtf_deb_enter(LBTF_DEB_MAIN);
760 usb_deregister(&if_usb_driver); 927 usb_deregister(&if_usb_driver);
928 lbtf_deb_leave(LBTF_DEB_MAIN);
761} 929}
762 930
763module_init(if_usb_init_module); 931module_init(if_usb_init_module);
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h
index 4cc42dd5a005..fbbaaae7a1ae 100644
--- a/drivers/net/wireless/libertas_tf/libertas_tf.h
+++ b/drivers/net/wireless/libertas_tf/libertas_tf.h
@@ -13,6 +13,8 @@
13#include <linux/kthread.h> 13#include <linux/kthread.h>
14#include <net/mac80211.h> 14#include <net/mac80211.h>
15 15
16#include "deb_defs.h"
17
16#ifndef DRV_NAME 18#ifndef DRV_NAME
17#define DRV_NAME "libertas_tf" 19#define DRV_NAME "libertas_tf"
18#endif 20#endif
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 7945ff5aa334..6a04c2157f73 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -7,10 +7,12 @@
7 * the Free Software Foundation; either version 2 of the License, or (at 7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version. 8 * your option) any later version.
9 */ 9 */
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
10#include <linux/slab.h> 12#include <linux/slab.h>
11 13
14#include <linux/etherdevice.h>
12#include "libertas_tf.h" 15#include "libertas_tf.h"
13#include "linux/etherdevice.h"
14 16
15#define DRIVER_RELEASE_VERSION "004.p0" 17#define DRIVER_RELEASE_VERSION "004.p0"
16/* thinfirm version: 5.132.X.pX */ 18/* thinfirm version: 5.132.X.pX */
@@ -18,7 +20,17 @@
18#define LBTF_FW_VER_MAX 0x0584ffff 20#define LBTF_FW_VER_MAX 0x0584ffff
19#define QOS_CONTROL_LEN 2 21#define QOS_CONTROL_LEN 2
20 22
21static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION; 23/* Module parameters */
24unsigned int lbtf_debug;
25EXPORT_SYMBOL_GPL(lbtf_debug);
26module_param_named(libertas_tf_debug, lbtf_debug, int, 0644);
27
28static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION
29#ifdef DEBUG
30 "-dbg"
31#endif
32 "";
33
22struct workqueue_struct *lbtf_wq; 34struct workqueue_struct *lbtf_wq;
23 35
24static const struct ieee80211_channel lbtf_channels[] = { 36static const struct ieee80211_channel lbtf_channels[] = {
@@ -81,6 +93,9 @@ static void lbtf_cmd_work(struct work_struct *work)
81{ 93{
82 struct lbtf_private *priv = container_of(work, struct lbtf_private, 94 struct lbtf_private *priv = container_of(work, struct lbtf_private,
83 cmd_work); 95 cmd_work);
96
97 lbtf_deb_enter(LBTF_DEB_CMD);
98
84 spin_lock_irq(&priv->driver_lock); 99 spin_lock_irq(&priv->driver_lock);
85 /* command response? */ 100 /* command response? */
86 if (priv->cmd_response_rxed) { 101 if (priv->cmd_response_rxed) {
@@ -108,11 +123,16 @@ static void lbtf_cmd_work(struct work_struct *work)
108 priv->cmd_timed_out = 0; 123 priv->cmd_timed_out = 0;
109 spin_unlock_irq(&priv->driver_lock); 124 spin_unlock_irq(&priv->driver_lock);
110 125
111 if (!priv->fw_ready) 126 if (!priv->fw_ready) {
127 lbtf_deb_leave_args(LBTF_DEB_CMD, "fw not ready");
112 return; 128 return;
129 }
130
113 /* Execute the next command */ 131 /* Execute the next command */
114 if (!priv->cur_cmd) 132 if (!priv->cur_cmd)
115 lbtf_execute_next_command(priv); 133 lbtf_execute_next_command(priv);
134
135 lbtf_deb_leave(LBTF_DEB_CMD);
116} 136}
117 137
118/** 138/**
@@ -126,6 +146,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv)
126{ 146{
127 int ret = -1; 147 int ret = -1;
128 148
149 lbtf_deb_enter(LBTF_DEB_FW);
129 /* 150 /*
130 * Read priv address from HW 151 * Read priv address from HW
131 */ 152 */
@@ -141,6 +162,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv)
141 162
142 ret = 0; 163 ret = 0;
143done: 164done:
165 lbtf_deb_leave_args(LBTF_DEB_FW, "ret: %d", ret);
144 return ret; 166 return ret;
145} 167}
146 168
@@ -152,6 +174,7 @@ static void command_timer_fn(unsigned long data)
152{ 174{
153 struct lbtf_private *priv = (struct lbtf_private *)data; 175 struct lbtf_private *priv = (struct lbtf_private *)data;
154 unsigned long flags; 176 unsigned long flags;
177 lbtf_deb_enter(LBTF_DEB_CMD);
155 178
156 spin_lock_irqsave(&priv->driver_lock, flags); 179 spin_lock_irqsave(&priv->driver_lock, flags);
157 180
@@ -168,10 +191,12 @@ static void command_timer_fn(unsigned long data)
168 queue_work(lbtf_wq, &priv->cmd_work); 191 queue_work(lbtf_wq, &priv->cmd_work);
169out: 192out:
170 spin_unlock_irqrestore(&priv->driver_lock, flags); 193 spin_unlock_irqrestore(&priv->driver_lock, flags);
194 lbtf_deb_leave(LBTF_DEB_CMD);
171} 195}
172 196
173static int lbtf_init_adapter(struct lbtf_private *priv) 197static int lbtf_init_adapter(struct lbtf_private *priv)
174{ 198{
199 lbtf_deb_enter(LBTF_DEB_MAIN);
175 memset(priv->current_addr, 0xff, ETH_ALEN); 200 memset(priv->current_addr, 0xff, ETH_ALEN);
176 mutex_init(&priv->lock); 201 mutex_init(&priv->lock);
177 202
@@ -188,13 +213,16 @@ static int lbtf_init_adapter(struct lbtf_private *priv)
188 if (lbtf_allocate_cmd_buffer(priv)) 213 if (lbtf_allocate_cmd_buffer(priv))
189 return -1; 214 return -1;
190 215
216 lbtf_deb_leave(LBTF_DEB_MAIN);
191 return 0; 217 return 0;
192} 218}
193 219
194static void lbtf_free_adapter(struct lbtf_private *priv) 220static void lbtf_free_adapter(struct lbtf_private *priv)
195{ 221{
222 lbtf_deb_enter(LBTF_DEB_MAIN);
196 lbtf_free_cmd_buffer(priv); 223 lbtf_free_cmd_buffer(priv);
197 del_timer(&priv->command_timer); 224 del_timer(&priv->command_timer);
225 lbtf_deb_leave(LBTF_DEB_MAIN);
198} 226}
199 227
200static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 228static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -221,14 +249,18 @@ static void lbtf_tx_work(struct work_struct *work)
221 struct sk_buff *skb = NULL; 249 struct sk_buff *skb = NULL;
222 int err; 250 int err;
223 251
252 lbtf_deb_enter(LBTF_DEB_MACOPS | LBTF_DEB_TX);
253
224 if ((priv->vif->type == NL80211_IFTYPE_AP) && 254 if ((priv->vif->type == NL80211_IFTYPE_AP) &&
225 (!skb_queue_empty(&priv->bc_ps_buf))) 255 (!skb_queue_empty(&priv->bc_ps_buf)))
226 skb = skb_dequeue(&priv->bc_ps_buf); 256 skb = skb_dequeue(&priv->bc_ps_buf);
227 else if (priv->skb_to_tx) { 257 else if (priv->skb_to_tx) {
228 skb = priv->skb_to_tx; 258 skb = priv->skb_to_tx;
229 priv->skb_to_tx = NULL; 259 priv->skb_to_tx = NULL;
230 } else 260 } else {
261 lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
231 return; 262 return;
263 }
232 264
233 len = skb->len; 265 len = skb->len;
234 info = IEEE80211_SKB_CB(skb); 266 info = IEEE80211_SKB_CB(skb);
@@ -236,6 +268,7 @@ static void lbtf_tx_work(struct work_struct *work)
236 268
237 if (priv->surpriseremoved) { 269 if (priv->surpriseremoved) {
238 dev_kfree_skb_any(skb); 270 dev_kfree_skb_any(skb);
271 lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
239 return; 272 return;
240 } 273 }
241 274
@@ -249,6 +282,7 @@ static void lbtf_tx_work(struct work_struct *work)
249 ETH_ALEN); 282 ETH_ALEN);
250 txpd->tx_packet_length = cpu_to_le16(len); 283 txpd->tx_packet_length = cpu_to_le16(len);
251 txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); 284 txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
285 lbtf_deb_hex(LBTF_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
252 BUG_ON(priv->tx_skb); 286 BUG_ON(priv->tx_skb);
253 spin_lock_irq(&priv->driver_lock); 287 spin_lock_irq(&priv->driver_lock);
254 priv->tx_skb = skb; 288 priv->tx_skb = skb;
@@ -257,7 +291,9 @@ static void lbtf_tx_work(struct work_struct *work)
257 if (err) { 291 if (err) {
258 dev_kfree_skb_any(skb); 292 dev_kfree_skb_any(skb);
259 priv->tx_skb = NULL; 293 priv->tx_skb = NULL;
294 pr_err("TX error: %d", err);
260 } 295 }
296 lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX);
261} 297}
262 298
263static int lbtf_op_start(struct ieee80211_hw *hw) 299static int lbtf_op_start(struct ieee80211_hw *hw)
@@ -266,6 +302,8 @@ static int lbtf_op_start(struct ieee80211_hw *hw)
266 void *card = priv->card; 302 void *card = priv->card;
267 int ret = -1; 303 int ret = -1;
268 304
305 lbtf_deb_enter(LBTF_DEB_MACOPS);
306
269 if (!priv->fw_ready) 307 if (!priv->fw_ready)
270 /* Upload firmware */ 308 /* Upload firmware */
271 if (priv->hw_prog_firmware(card)) 309 if (priv->hw_prog_firmware(card))
@@ -286,10 +324,12 @@ static int lbtf_op_start(struct ieee80211_hw *hw)
286 } 324 }
287 325
288 printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n"); 326 printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n");
327 lbtf_deb_leave(LBTF_DEB_MACOPS);
289 return 0; 328 return 0;
290 329
291err_prog_firmware: 330err_prog_firmware:
292 priv->hw_reset_device(card); 331 priv->hw_reset_device(card);
332 lbtf_deb_leave_args(LBTF_DEB_MACOPS, "error programing fw; ret=%d", ret);
293 return ret; 333 return ret;
294} 334}
295 335
@@ -300,6 +340,9 @@ static void lbtf_op_stop(struct ieee80211_hw *hw)
300 struct sk_buff *skb; 340 struct sk_buff *skb;
301 341
302 struct cmd_ctrl_node *cmdnode; 342 struct cmd_ctrl_node *cmdnode;
343
344 lbtf_deb_enter(LBTF_DEB_MACOPS);
345
303 /* Flush pending command nodes */ 346 /* Flush pending command nodes */
304 spin_lock_irqsave(&priv->driver_lock, flags); 347 spin_lock_irqsave(&priv->driver_lock, flags);
305 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { 348 list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
@@ -316,13 +359,14 @@ static void lbtf_op_stop(struct ieee80211_hw *hw)
316 priv->radioon = RADIO_OFF; 359 priv->radioon = RADIO_OFF;
317 lbtf_set_radio_control(priv); 360 lbtf_set_radio_control(priv);
318 361
319 return; 362 lbtf_deb_leave(LBTF_DEB_MACOPS);
320} 363}
321 364
322static int lbtf_op_add_interface(struct ieee80211_hw *hw, 365static int lbtf_op_add_interface(struct ieee80211_hw *hw,
323 struct ieee80211_vif *vif) 366 struct ieee80211_vif *vif)
324{ 367{
325 struct lbtf_private *priv = hw->priv; 368 struct lbtf_private *priv = hw->priv;
369 lbtf_deb_enter(LBTF_DEB_MACOPS);
326 if (priv->vif != NULL) 370 if (priv->vif != NULL)
327 return -EOPNOTSUPP; 371 return -EOPNOTSUPP;
328 372
@@ -340,6 +384,7 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw,
340 return -EOPNOTSUPP; 384 return -EOPNOTSUPP;
341 } 385 }
342 lbtf_set_mac_address(priv, (u8 *) vif->addr); 386 lbtf_set_mac_address(priv, (u8 *) vif->addr);
387 lbtf_deb_leave(LBTF_DEB_MACOPS);
343 return 0; 388 return 0;
344} 389}
345 390
@@ -347,6 +392,7 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
347 struct ieee80211_vif *vif) 392 struct ieee80211_vif *vif)
348{ 393{
349 struct lbtf_private *priv = hw->priv; 394 struct lbtf_private *priv = hw->priv;
395 lbtf_deb_enter(LBTF_DEB_MACOPS);
350 396
351 if (priv->vif->type == NL80211_IFTYPE_AP || 397 if (priv->vif->type == NL80211_IFTYPE_AP ||
352 priv->vif->type == NL80211_IFTYPE_MESH_POINT) 398 priv->vif->type == NL80211_IFTYPE_MESH_POINT)
@@ -354,37 +400,38 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
354 lbtf_set_mode(priv, LBTF_PASSIVE_MODE); 400 lbtf_set_mode(priv, LBTF_PASSIVE_MODE);
355 lbtf_set_bssid(priv, 0, NULL); 401 lbtf_set_bssid(priv, 0, NULL);
356 priv->vif = NULL; 402 priv->vif = NULL;
403 lbtf_deb_leave(LBTF_DEB_MACOPS);
357} 404}
358 405
359static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) 406static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
360{ 407{
361 struct lbtf_private *priv = hw->priv; 408 struct lbtf_private *priv = hw->priv;
362 struct ieee80211_conf *conf = &hw->conf; 409 struct ieee80211_conf *conf = &hw->conf;
410 lbtf_deb_enter(LBTF_DEB_MACOPS);
363 411
364 if (conf->channel->center_freq != priv->cur_freq) { 412 if (conf->channel->center_freq != priv->cur_freq) {
365 priv->cur_freq = conf->channel->center_freq; 413 priv->cur_freq = conf->channel->center_freq;
366 lbtf_set_channel(priv, conf->channel->hw_value); 414 lbtf_set_channel(priv, conf->channel->hw_value);
367 } 415 }
416 lbtf_deb_leave(LBTF_DEB_MACOPS);
368 return 0; 417 return 0;
369} 418}
370 419
371static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw, 420static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
372 int mc_count, struct dev_addr_list *mclist) 421 struct netdev_hw_addr_list *mc_list)
373{ 422{
374 struct lbtf_private *priv = hw->priv; 423 struct lbtf_private *priv = hw->priv;
375 int i; 424 int i;
425 struct netdev_hw_addr *ha;
426 int mc_count = netdev_hw_addr_list_count(mc_list);
376 427
377 if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) 428 if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
378 return mc_count; 429 return mc_count;
379 430
380 priv->nr_of_multicastmacaddr = mc_count; 431 priv->nr_of_multicastmacaddr = mc_count;
381 for (i = 0; i < mc_count; i++) { 432 i = 0;
382 if (!mclist) 433 netdev_hw_addr_list_for_each(ha, mc_list)
383 break; 434 memcpy(&priv->multicastlist[i++], ha->addr, ETH_ALEN);
384 memcpy(&priv->multicastlist[i], mclist->da_addr,
385 ETH_ALEN);
386 mclist = mclist->next;
387 }
388 435
389 return mc_count; 436 return mc_count;
390} 437}
@@ -397,11 +444,16 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
397{ 444{
398 struct lbtf_private *priv = hw->priv; 445 struct lbtf_private *priv = hw->priv;
399 int old_mac_control = priv->mac_control; 446 int old_mac_control = priv->mac_control;
447
448 lbtf_deb_enter(LBTF_DEB_MACOPS);
449
400 changed_flags &= SUPPORTED_FIF_FLAGS; 450 changed_flags &= SUPPORTED_FIF_FLAGS;
401 *new_flags &= SUPPORTED_FIF_FLAGS; 451 *new_flags &= SUPPORTED_FIF_FLAGS;
402 452
403 if (!changed_flags) 453 if (!changed_flags) {
454 lbtf_deb_leave(LBTF_DEB_MACOPS);
404 return; 455 return;
456 }
405 457
406 if (*new_flags & (FIF_PROMISC_IN_BSS)) 458 if (*new_flags & (FIF_PROMISC_IN_BSS))
407 priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; 459 priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
@@ -427,6 +479,8 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
427 479
428 if (priv->mac_control != old_mac_control) 480 if (priv->mac_control != old_mac_control)
429 lbtf_set_mac_control(priv); 481 lbtf_set_mac_control(priv);
482
483 lbtf_deb_leave(LBTF_DEB_MACOPS);
430} 484}
431 485
432static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, 486static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -436,6 +490,7 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
436{ 490{
437 struct lbtf_private *priv = hw->priv; 491 struct lbtf_private *priv = hw->priv;
438 struct sk_buff *beacon; 492 struct sk_buff *beacon;
493 lbtf_deb_enter(LBTF_DEB_MACOPS);
439 494
440 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) { 495 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
441 switch (priv->vif->type) { 496 switch (priv->vif->type) {
@@ -466,6 +521,8 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
466 priv->preamble = CMD_TYPE_LONG_PREAMBLE; 521 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
467 lbtf_set_radio_control(priv); 522 lbtf_set_radio_control(priv);
468 } 523 }
524
525 lbtf_deb_leave(LBTF_DEB_MACOPS);
469} 526}
470 527
471static const struct ieee80211_ops lbtf_ops = { 528static const struct ieee80211_ops lbtf_ops = {
@@ -488,6 +545,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
488 unsigned int flags; 545 unsigned int flags;
489 struct ieee80211_hdr *hdr; 546 struct ieee80211_hdr *hdr;
490 547
548 lbtf_deb_enter(LBTF_DEB_RX);
549
491 prxpd = (struct rxpd *) skb->data; 550 prxpd = (struct rxpd *) skb->data;
492 551
493 stats.flag = 0; 552 stats.flag = 0;
@@ -496,7 +555,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
496 stats.freq = priv->cur_freq; 555 stats.freq = priv->cur_freq;
497 stats.band = IEEE80211_BAND_2GHZ; 556 stats.band = IEEE80211_BAND_2GHZ;
498 stats.signal = prxpd->snr; 557 stats.signal = prxpd->snr;
499 stats.noise = prxpd->nf;
500 /* Marvell rate index has a hole at value 4 */ 558 /* Marvell rate index has a hole at value 4 */
501 if (prxpd->rx_rate > 4) 559 if (prxpd->rx_rate > 4)
502 --prxpd->rx_rate; 560 --prxpd->rx_rate;
@@ -518,7 +576,15 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
518 } 576 }
519 577
520 memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); 578 memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
579
580 lbtf_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
581 skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
582 lbtf_deb_hex(LBTF_DEB_RX, "RX Data", skb->data,
583 min_t(unsigned int, skb->len, 100));
584
521 ieee80211_rx_irqsafe(priv->hw, skb); 585 ieee80211_rx_irqsafe(priv->hw, skb);
586
587 lbtf_deb_leave(LBTF_DEB_RX);
522 return 0; 588 return 0;
523} 589}
524EXPORT_SYMBOL_GPL(lbtf_rx); 590EXPORT_SYMBOL_GPL(lbtf_rx);
@@ -535,6 +601,8 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev)
535 struct ieee80211_hw *hw; 601 struct ieee80211_hw *hw;
536 struct lbtf_private *priv = NULL; 602 struct lbtf_private *priv = NULL;
537 603
604 lbtf_deb_enter(LBTF_DEB_MAIN);
605
538 hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops); 606 hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops);
539 if (!hw) 607 if (!hw)
540 goto done; 608 goto done;
@@ -577,6 +645,7 @@ err_init_adapter:
577 priv = NULL; 645 priv = NULL;
578 646
579done: 647done:
648 lbtf_deb_leave_args(LBTF_DEB_MAIN, "priv %p", priv);
580 return priv; 649 return priv;
581} 650}
582EXPORT_SYMBOL_GPL(lbtf_add_card); 651EXPORT_SYMBOL_GPL(lbtf_add_card);
@@ -586,6 +655,8 @@ int lbtf_remove_card(struct lbtf_private *priv)
586{ 655{
587 struct ieee80211_hw *hw = priv->hw; 656 struct ieee80211_hw *hw = priv->hw;
588 657
658 lbtf_deb_enter(LBTF_DEB_MAIN);
659
589 priv->surpriseremoved = 1; 660 priv->surpriseremoved = 1;
590 del_timer(&priv->command_timer); 661 del_timer(&priv->command_timer);
591 lbtf_free_adapter(priv); 662 lbtf_free_adapter(priv);
@@ -593,6 +664,7 @@ int lbtf_remove_card(struct lbtf_private *priv)
593 ieee80211_unregister_hw(hw); 664 ieee80211_unregister_hw(hw);
594 ieee80211_free_hw(hw); 665 ieee80211_free_hw(hw);
595 666
667 lbtf_deb_leave(LBTF_DEB_MAIN);
596 return 0; 668 return 0;
597} 669}
598EXPORT_SYMBOL_GPL(lbtf_remove_card); 670EXPORT_SYMBOL_GPL(lbtf_remove_card);
@@ -651,17 +723,21 @@ EXPORT_SYMBOL_GPL(lbtf_bcn_sent);
651 723
652static int __init lbtf_init_module(void) 724static int __init lbtf_init_module(void)
653{ 725{
726 lbtf_deb_enter(LBTF_DEB_MAIN);
654 lbtf_wq = create_workqueue("libertastf"); 727 lbtf_wq = create_workqueue("libertastf");
655 if (lbtf_wq == NULL) { 728 if (lbtf_wq == NULL) {
656 printk(KERN_ERR "libertastf: couldn't create workqueue\n"); 729 printk(KERN_ERR "libertastf: couldn't create workqueue\n");
657 return -ENOMEM; 730 return -ENOMEM;
658 } 731 }
732 lbtf_deb_leave(LBTF_DEB_MAIN);
659 return 0; 733 return 0;
660} 734}
661 735
662static void __exit lbtf_exit_module(void) 736static void __exit lbtf_exit_module(void)
663{ 737{
738 lbtf_deb_enter(LBTF_DEB_MAIN);
664 destroy_workqueue(lbtf_wq); 739 destroy_workqueue(lbtf_wq);
740 lbtf_deb_leave(LBTF_DEB_MAIN);
665} 741}
666 742
667module_init(lbtf_init_module); 743module_init(lbtf_init_module);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7cd5f56662fc..6f8cb3ee6fed 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -291,7 +291,8 @@ struct mac80211_hwsim_data {
291 struct ieee80211_channel *channel; 291 struct ieee80211_channel *channel;
292 unsigned long beacon_int; /* in jiffies unit */ 292 unsigned long beacon_int; /* in jiffies unit */
293 unsigned int rx_filter; 293 unsigned int rx_filter;
294 bool started, idle; 294 bool started, idle, scanning;
295 struct mutex mutex;
295 struct timer_list beacon_timer; 296 struct timer_list beacon_timer;
296 enum ps_mode { 297 enum ps_mode {
297 PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL 298 PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
@@ -651,17 +652,17 @@ static void mac80211_hwsim_beacon(unsigned long arg)
651 add_timer(&data->beacon_timer); 652 add_timer(&data->beacon_timer);
652} 653}
653 654
655static const char *hwsim_chantypes[] = {
656 [NL80211_CHAN_NO_HT] = "noht",
657 [NL80211_CHAN_HT20] = "ht20",
658 [NL80211_CHAN_HT40MINUS] = "ht40-",
659 [NL80211_CHAN_HT40PLUS] = "ht40+",
660};
654 661
655static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) 662static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
656{ 663{
657 struct mac80211_hwsim_data *data = hw->priv; 664 struct mac80211_hwsim_data *data = hw->priv;
658 struct ieee80211_conf *conf = &hw->conf; 665 struct ieee80211_conf *conf = &hw->conf;
659 static const char *chantypes[4] = {
660 [NL80211_CHAN_NO_HT] = "noht",
661 [NL80211_CHAN_HT20] = "ht20",
662 [NL80211_CHAN_HT40MINUS] = "ht40-",
663 [NL80211_CHAN_HT40PLUS] = "ht40+",
664 };
665 static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = { 666 static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
666 [IEEE80211_SMPS_AUTOMATIC] = "auto", 667 [IEEE80211_SMPS_AUTOMATIC] = "auto",
667 [IEEE80211_SMPS_OFF] = "off", 668 [IEEE80211_SMPS_OFF] = "off",
@@ -672,7 +673,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
672 printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", 673 printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
673 wiphy_name(hw->wiphy), __func__, 674 wiphy_name(hw->wiphy), __func__,
674 conf->channel->center_freq, 675 conf->channel->center_freq,
675 chantypes[conf->channel_type], 676 hwsim_chantypes[conf->channel_type],
676 !!(conf->flags & IEEE80211_CONF_IDLE), 677 !!(conf->flags & IEEE80211_CONF_IDLE),
677 !!(conf->flags & IEEE80211_CONF_PS), 678 !!(conf->flags & IEEE80211_CONF_PS),
678 smps_modes[conf->smps_mode]); 679 smps_modes[conf->smps_mode]);
@@ -760,9 +761,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
760 } 761 }
761 762
762 if (changed & BSS_CHANGED_HT) { 763 if (changed & BSS_CHANGED_HT) {
763 printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n", 764 printk(KERN_DEBUG " %s: HT: op_mode=0x%x, chantype=%s\n",
764 wiphy_name(hw->wiphy), 765 wiphy_name(hw->wiphy),
765 info->ht_operation_mode); 766 info->ht_operation_mode,
767 hwsim_chantypes[info->channel_type]);
766 } 768 }
767 769
768 if (changed & BSS_CHANGED_BASIC_RATES) { 770 if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -829,6 +831,33 @@ static int mac80211_hwsim_conf_tx(
829 return 0; 831 return 0;
830} 832}
831 833
834static int mac80211_hwsim_get_survey(
835 struct ieee80211_hw *hw, int idx,
836 struct survey_info *survey)
837{
838 struct ieee80211_conf *conf = &hw->conf;
839
840 printk(KERN_DEBUG "%s:%s (idx=%d)\n",
841 wiphy_name(hw->wiphy), __func__, idx);
842
843 if (idx != 0)
844 return -ENOENT;
845
846 /* Current channel */
847 survey->channel = conf->channel;
848
849 /*
850 * Magically conjured noise level --- this is only ok for simulated hardware.
851 *
852 * A real driver which cannot determine the real channel noise MUST NOT
853 * report any noise, especially not a magically conjured one :-)
854 */
855 survey->filled = SURVEY_INFO_NOISE_DBM;
856 survey->noise = -92;
857
858 return 0;
859}
860
832#ifdef CONFIG_NL80211_TESTMODE 861#ifdef CONFIG_NL80211_TESTMODE
833/* 862/*
834 * This section contains example code for using netlink 863 * This section contains example code for using netlink
@@ -946,6 +975,7 @@ static void hw_scan_done(struct work_struct *work)
946} 975}
947 976
948static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, 977static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
978 struct ieee80211_vif *vif,
949 struct cfg80211_scan_request *req) 979 struct cfg80211_scan_request *req)
950{ 980{
951 struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); 981 struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL);
@@ -957,9 +987,9 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
957 hsd->hw = hw; 987 hsd->hw = hw;
958 INIT_DELAYED_WORK(&hsd->w, hw_scan_done); 988 INIT_DELAYED_WORK(&hsd->w, hw_scan_done);
959 989
960 printk(KERN_DEBUG "hwsim scan request\n"); 990 printk(KERN_DEBUG "hwsim hw_scan request\n");
961 for (i = 0; i < req->n_channels; i++) 991 for (i = 0; i < req->n_channels; i++)
962 printk(KERN_DEBUG "hwsim scan freq %d\n", 992 printk(KERN_DEBUG "hwsim hw_scan freq %d\n",
963 req->channels[i]->center_freq); 993 req->channels[i]->center_freq);
964 994
965 ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); 995 ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ);
@@ -967,6 +997,36 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
967 return 0; 997 return 0;
968} 998}
969 999
1000static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw)
1001{
1002 struct mac80211_hwsim_data *hwsim = hw->priv;
1003
1004 mutex_lock(&hwsim->mutex);
1005
1006 if (hwsim->scanning) {
1007 printk(KERN_DEBUG "two hwsim sw_scans detected!\n");
1008 goto out;
1009 }
1010
1011 printk(KERN_DEBUG "hwsim sw_scan request, prepping stuff\n");
1012 hwsim->scanning = true;
1013
1014out:
1015 mutex_unlock(&hwsim->mutex);
1016}
1017
1018static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw)
1019{
1020 struct mac80211_hwsim_data *hwsim = hw->priv;
1021
1022 mutex_lock(&hwsim->mutex);
1023
1024 printk(KERN_DEBUG "hwsim sw_scan_complete\n");
1025 hwsim->scanning = false;
1026
1027 mutex_unlock(&hwsim->mutex);
1028}
1029
970static struct ieee80211_ops mac80211_hwsim_ops = 1030static struct ieee80211_ops mac80211_hwsim_ops =
971{ 1031{
972 .tx = mac80211_hwsim_tx, 1032 .tx = mac80211_hwsim_tx,
@@ -982,8 +1042,11 @@ static struct ieee80211_ops mac80211_hwsim_ops =
982 .sta_notify = mac80211_hwsim_sta_notify, 1042 .sta_notify = mac80211_hwsim_sta_notify,
983 .set_tim = mac80211_hwsim_set_tim, 1043 .set_tim = mac80211_hwsim_set_tim,
984 .conf_tx = mac80211_hwsim_conf_tx, 1044 .conf_tx = mac80211_hwsim_conf_tx,
1045 .get_survey = mac80211_hwsim_get_survey,
985 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd) 1046 CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
986 .ampdu_action = mac80211_hwsim_ampdu_action, 1047 .ampdu_action = mac80211_hwsim_ampdu_action,
1048 .sw_scan_start = mac80211_hwsim_sw_scan,
1049 .sw_scan_complete = mac80211_hwsim_sw_scan_complete,
987 .flush = mac80211_hwsim_flush, 1050 .flush = mac80211_hwsim_flush,
988}; 1051};
989 1052
@@ -1179,8 +1242,11 @@ static int __init init_mac80211_hwsim(void)
1179 if (radios < 1 || radios > 100) 1242 if (radios < 1 || radios > 100)
1180 return -EINVAL; 1243 return -EINVAL;
1181 1244
1182 if (fake_hw_scan) 1245 if (fake_hw_scan) {
1183 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 1246 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
1247 mac80211_hwsim_ops.sw_scan_start = NULL;
1248 mac80211_hwsim_ops.sw_scan_complete = NULL;
1249 }
1184 1250
1185 spin_lock_init(&hwsim_radio_lock); 1251 spin_lock_init(&hwsim_radio_lock);
1186 INIT_LIST_HEAD(&hwsim_radios); 1252 INIT_LIST_HEAD(&hwsim_radios);
@@ -1235,7 +1301,8 @@ static int __init init_mac80211_hwsim(void)
1235 hw->flags = IEEE80211_HW_MFP_CAPABLE | 1301 hw->flags = IEEE80211_HW_MFP_CAPABLE |
1236 IEEE80211_HW_SIGNAL_DBM | 1302 IEEE80211_HW_SIGNAL_DBM |
1237 IEEE80211_HW_SUPPORTS_STATIC_SMPS | 1303 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
1238 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; 1304 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
1305 IEEE80211_HW_AMPDU_AGGREGATION;
1239 1306
1240 /* ask mac80211 to reserve space for magic */ 1307 /* ask mac80211 to reserve space for magic */
1241 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 1308 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
@@ -1285,6 +1352,7 @@ static int __init init_mac80211_hwsim(void)
1285 } 1352 }
1286 /* By default all radios are belonging to the first group */ 1353 /* By default all radios are belonging to the first group */
1287 data->group = 1; 1354 data->group = 1;
1355 mutex_init(&data->mutex);
1288 1356
1289 /* Work to be done prior to ieee80211_register_hw() */ 1357 /* Work to be done prior to ieee80211_register_hw() */
1290 switch (regtest) { 1358 switch (regtest) {
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 12fdcb25fd38..808adb909095 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -750,7 +750,6 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
750 memset(status, 0, sizeof(*status)); 750 memset(status, 0, sizeof(*status));
751 751
752 status->signal = -rxd->rssi; 752 status->signal = -rxd->rssi;
753 status->noise = -rxd->noise_floor;
754 753
755 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { 754 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
756 status->flag |= RX_FLAG_HT; 755 status->flag |= RX_FLAG_HT;
@@ -852,7 +851,6 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
852 memset(status, 0, sizeof(*status)); 851 memset(status, 0, sizeof(*status));
853 852
854 status->signal = -rxd->rssi; 853 status->signal = -rxd->rssi;
855 status->noise = -rxd->noise_level;
856 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); 854 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
857 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); 855 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
858 856
@@ -1939,11 +1937,15 @@ struct mwl8k_cmd_mac_multicast_adr {
1939 1937
1940static struct mwl8k_cmd_pkt * 1938static struct mwl8k_cmd_pkt *
1941__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, 1939__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1942 int mc_count, struct dev_addr_list *mclist) 1940 struct netdev_hw_addr_list *mc_list)
1943{ 1941{
1944 struct mwl8k_priv *priv = hw->priv; 1942 struct mwl8k_priv *priv = hw->priv;
1945 struct mwl8k_cmd_mac_multicast_adr *cmd; 1943 struct mwl8k_cmd_mac_multicast_adr *cmd;
1946 int size; 1944 int size;
1945 int mc_count = 0;
1946
1947 if (mc_list)
1948 mc_count = netdev_hw_addr_list_count(mc_list);
1947 1949
1948 if (allmulti || mc_count > priv->num_mcaddrs) { 1950 if (allmulti || mc_count > priv->num_mcaddrs) {
1949 allmulti = 1; 1951 allmulti = 1;
@@ -1964,17 +1966,13 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1964 if (allmulti) { 1966 if (allmulti) {
1965 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST); 1967 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
1966 } else if (mc_count) { 1968 } else if (mc_count) {
1967 int i; 1969 struct netdev_hw_addr *ha;
1970 int i = 0;
1968 1971
1969 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); 1972 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
1970 cmd->numaddr = cpu_to_le16(mc_count); 1973 cmd->numaddr = cpu_to_le16(mc_count);
1971 for (i = 0; i < mc_count && mclist; i++) { 1974 netdev_hw_addr_list_for_each(ha, mc_list) {
1972 if (mclist->da_addrlen != ETH_ALEN) { 1975 memcpy(cmd->addr[i], ha->addr, ETH_ALEN);
1973 kfree(cmd);
1974 return NULL;
1975 }
1976 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1977 mclist = mclist->next;
1978 } 1976 }
1979 } 1977 }
1980 1978
@@ -3553,7 +3551,7 @@ mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3553} 3551}
3554 3552
3555static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 3553static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3556 int mc_count, struct dev_addr_list *mclist) 3554 struct netdev_hw_addr_list *mc_list)
3557{ 3555{
3558 struct mwl8k_cmd_pkt *cmd; 3556 struct mwl8k_cmd_pkt *cmd;
3559 3557
@@ -3564,7 +3562,7 @@ static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3564 * we'll end up throwing this packet away and creating a new 3562 * we'll end up throwing this packet away and creating a new
3565 * one in mwl8k_configure_filter(). 3563 * one in mwl8k_configure_filter().
3566 */ 3564 */
3567 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist); 3565 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_list);
3568 3566
3569 return (unsigned long)cmd; 3567 return (unsigned long)cmd;
3570} 3568}
@@ -3687,7 +3685,7 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3687 */ 3685 */
3688 if (*total_flags & FIF_ALLMULTI) { 3686 if (*total_flags & FIF_ALLMULTI) {
3689 kfree(cmd); 3687 kfree(cmd);
3690 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL); 3688 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, NULL);
3691 } 3689 }
3692 3690
3693 if (cmd != NULL) { 3691 if (cmd != NULL) {
@@ -3984,8 +3982,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3984 3982
3985 hw->queues = MWL8K_TX_QUEUES; 3983 hw->queues = MWL8K_TX_QUEUES;
3986 3984
3987 /* Set rssi and noise values to dBm */ 3985 /* Set rssi values to dBm */
3988 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; 3986 hw->flags |= IEEE80211_HW_SIGNAL_DBM;
3989 hw->vif_data_size = sizeof(struct mwl8k_vif); 3987 hw->vif_data_size = sizeof(struct mwl8k_vif);
3990 hw->sta_data_size = sizeof(struct mwl8k_sta); 3988 hw->sta_data_size = sizeof(struct mwl8k_sta);
3991 3989
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index e2a2c18920aa..60819bcf4377 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -27,6 +27,17 @@ config HERMES
27 configure your card and that /etc/pcmcia/wireless.opts works : 27 configure your card and that /etc/pcmcia/wireless.opts works :
28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> 28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
29 29
30config HERMES_PRISM
31 bool "Support Prism 2/2.5 chipset"
32 depends on HERMES
33 ---help---
34
35 Say Y to enable support for Prism 2 and 2.5 chipsets. These
36 chipsets are better handled by the hostap driver. This driver
37 would not support WPA or firmware download for Prism chipset.
38
39 If you are not sure, say N.
40
30config HERMES_CACHE_FW_ON_INIT 41config HERMES_CACHE_FW_ON_INIT
31 bool "Cache Hermes firmware on driver initialisation" 42 bool "Cache Hermes firmware on driver initialisation"
32 depends on HERMES 43 depends on HERMES
@@ -86,7 +97,7 @@ config NORTEL_HERMES
86 97
87config PCI_HERMES 98config PCI_HERMES
88 tristate "Prism 2.5 PCI 802.11b adaptor support" 99 tristate "Prism 2.5 PCI 802.11b adaptor support"
89 depends on PCI && HERMES 100 depends on PCI && HERMES && HERMES_PRISM
90 help 101 help
91 Enable support for PCI and mini-PCI 802.11b wireless NICs based on 102 Enable support for PCI and mini-PCI 802.11b wireless NICs based on
92 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b 103 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
@@ -121,3 +132,10 @@ config PCMCIA_SPECTRUM
121 This driver requires firmware download on startup. Utilities 132 This driver requires firmware download on startup. Utilities
122 for downloading Symbol firmware are available at 133 for downloading Symbol firmware are available at
123 <http://sourceforge.net/projects/orinoco/> 134 <http://sourceforge.net/projects/orinoco/>
135
136config ORINOCO_USB
137 tristate "Agere Orinoco USB support"
138 depends on USB && HERMES
139 select FW_LOADER
140 ---help---
141 This driver is for USB versions of the Agere Orinoco card.
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 9abd6329bcbd..bfdefb85abcd 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -11,3 +11,7 @@ obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
11obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o 11obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
12obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o 12obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o
13obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o 13obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o
14obj-$(CONFIG_ORINOCO_USB) += orinoco_usb.o
15
16# Orinoco should be endian clean.
17ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index c60df2c1aca3..9bcee10c9308 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -77,9 +77,9 @@ airport_resume(struct macio_dev *mdev)
77 77
78 enable_irq(card->irq); 78 enable_irq(card->irq);
79 79
80 spin_lock_irqsave(&priv->lock, flags); 80 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
81 err = orinoco_up(priv); 81 err = orinoco_up(priv);
82 spin_unlock_irqrestore(&priv->lock, flags); 82 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
83 83
84 return err; 84 return err;
85} 85}
@@ -195,7 +195,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
195 ssleep(1); 195 ssleep(1);
196 196
197 /* Reset it before we get the interrupt */ 197 /* Reset it before we get the interrupt */
198 hermes_init(hw); 198 hw->ops->init(hw);
199 199
200 if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { 200 if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
201 printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); 201 printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq);
@@ -210,7 +210,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
210 } 210 }
211 211
212 /* Register an interface with the stack */ 212 /* Register an interface with the stack */
213 if (orinoco_if_add(priv, phys_addr, card->irq) != 0) { 213 if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) {
214 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 214 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
215 goto failed; 215 goto failed;
216 } 216 }
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 27f2d3342645..8c4169c227ae 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -88,7 +88,9 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
88 88
89 wiphy->rts_threshold = priv->rts_thresh; 89 wiphy->rts_threshold = priv->rts_thresh;
90 if (!priv->has_mwo) 90 if (!priv->has_mwo)
91 wiphy->frag_threshold = priv->frag_thresh; 91 wiphy->frag_threshold = priv->frag_thresh + 1;
92 wiphy->retry_short = priv->short_retry_limit;
93 wiphy->retry_long = priv->long_retry_limit;
92 94
93 return wiphy_register(wiphy); 95 return wiphy_register(wiphy);
94} 96}
@@ -157,6 +159,7 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
157} 159}
158 160
159static int orinoco_set_channel(struct wiphy *wiphy, 161static int orinoco_set_channel(struct wiphy *wiphy,
162 struct net_device *netdev,
160 struct ieee80211_channel *chan, 163 struct ieee80211_channel *chan,
161 enum nl80211_channel_type channel_type) 164 enum nl80211_channel_type channel_type)
162{ 165{
@@ -187,7 +190,7 @@ static int orinoco_set_channel(struct wiphy *wiphy,
187 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 190 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
188 /* Fast channel change - no commit if successful */ 191 /* Fast channel change - no commit if successful */
189 hermes_t *hw = &priv->hw; 192 hermes_t *hw = &priv->hw;
190 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 193 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
191 HERMES_TEST_SET_CHANNEL, 194 HERMES_TEST_SET_CHANNEL,
192 channel, NULL); 195 channel, NULL);
193 } 196 }
@@ -196,8 +199,92 @@ static int orinoco_set_channel(struct wiphy *wiphy,
196 return err; 199 return err;
197} 200}
198 201
202static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
203{
204 struct orinoco_private *priv = wiphy_priv(wiphy);
205 int frag_value = -1;
206 int rts_value = -1;
207 int err = 0;
208
209 if (changed & WIPHY_PARAM_RETRY_SHORT) {
210 /* Setting short retry not supported */
211 err = -EINVAL;
212 }
213
214 if (changed & WIPHY_PARAM_RETRY_LONG) {
215 /* Setting long retry not supported */
216 err = -EINVAL;
217 }
218
219 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
220 /* Set fragmentation */
221 if (priv->has_mwo) {
222 if (wiphy->frag_threshold < 0)
223 frag_value = 0;
224 else {
225 printk(KERN_WARNING "%s: Fixed fragmentation "
226 "is not supported on this firmware. "
227 "Using MWO robust instead.\n",
228 priv->ndev->name);
229 frag_value = 1;
230 }
231 } else {
232 if (wiphy->frag_threshold < 0)
233 frag_value = 2346;
234 else if ((wiphy->frag_threshold < 257) ||
235 (wiphy->frag_threshold > 2347))
236 err = -EINVAL;
237 else
238 /* cfg80211 value is 257-2347 (odd only)
239 * orinoco rid has range 256-2346 (even only) */
240 frag_value = wiphy->frag_threshold & ~0x1;
241 }
242 }
243
244 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
245 /* Set RTS.
246 *
247 * Prism documentation suggests default of 2432,
248 * and a range of 0-3000.
249 *
250 * Current implementation uses 2347 as the default and
251 * the upper limit.
252 */
253
254 if (wiphy->rts_threshold < 0)
255 rts_value = 2347;
256 else if (wiphy->rts_threshold > 2347)
257 err = -EINVAL;
258 else
259 rts_value = wiphy->rts_threshold;
260 }
261
262 if (!err) {
263 unsigned long flags;
264
265 if (orinoco_lock(priv, &flags) != 0)
266 return -EBUSY;
267
268 if (frag_value >= 0) {
269 if (priv->has_mwo)
270 priv->mwo_robust = frag_value;
271 else
272 priv->frag_thresh = frag_value;
273 }
274 if (rts_value >= 0)
275 priv->rts_thresh = rts_value;
276
277 err = orinoco_commit(priv);
278
279 orinoco_unlock(priv, &flags);
280 }
281
282 return err;
283}
284
199const struct cfg80211_ops orinoco_cfg_ops = { 285const struct cfg80211_ops orinoco_cfg_ops = {
200 .change_virtual_intf = orinoco_change_vif, 286 .change_virtual_intf = orinoco_change_vif,
201 .set_channel = orinoco_set_channel, 287 .set_channel = orinoco_set_channel,
202 .scan = orinoco_scan, 288 .scan = orinoco_scan,
289 .set_wiphy_params = orinoco_set_wiphy_params,
203}; 290};
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 5ea0f7cf85b1..3e1947d097ca 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
122 dev_dbg(dev, "Attempting to download firmware %s\n", firmware); 122 dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
123 123
124 /* Read current plug data */ 124 /* Read current plug data */
125 err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0); 125 err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
126 dev_dbg(dev, "Read PDA returned %d\n", err); 126 dev_dbg(dev, "Read PDA returned %d\n", err);
127 if (err) 127 if (err)
128 goto free; 128 goto free;
@@ -149,7 +149,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
149 } 149 }
150 150
151 /* Enable aux port to allow programming */ 151 /* Enable aux port to allow programming */
152 err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point)); 152 err = hw->ops->program_init(hw, le32_to_cpu(hdr->entry_point));
153 dev_dbg(dev, "Program init returned %d\n", err); 153 dev_dbg(dev, "Program init returned %d\n", err);
154 if (err != 0) 154 if (err != 0)
155 goto abort; 155 goto abort;
@@ -177,7 +177,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
177 goto abort; 177 goto abort;
178 178
179 /* Tell card we've finished */ 179 /* Tell card we've finished */
180 err = hermesi_program_end(hw); 180 err = hw->ops->program_end(hw);
181 dev_dbg(dev, "Program end returned %d\n", err); 181 dev_dbg(dev, "Program end returned %d\n", err);
182 if (err != 0) 182 if (err != 0)
183 goto abort; 183 goto abort;
@@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
224 if (!pda) 224 if (!pda)
225 return -ENOMEM; 225 return -ENOMEM;
226 226
227 ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1); 227 ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
228 if (ret) 228 if (ret)
229 goto free; 229 goto free;
230 } 230 }
@@ -260,7 +260,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
260 } 260 }
261 261
262 /* Reset hermes chip and make sure it responds */ 262 /* Reset hermes chip and make sure it responds */
263 ret = hermes_init(hw); 263 ret = hw->ops->init(hw);
264 264
265 /* hermes_reset() should return 0 with the secondary firmware */ 265 /* hermes_reset() should return 0 with the secondary firmware */
266 if (secondary && ret != 0) 266 if (secondary && ret != 0)
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index 1a2fca76fd3c..6c6a23e08df6 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -52,6 +52,26 @@
52#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ 52#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
53 53
54/* 54/*
55 * AUX port access. To unlock the AUX port write the access keys to the
56 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
57 * register. Then read it and make sure it's HERMES_AUX_ENABLED.
58 */
59#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
60#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
61#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
62#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */
63
64#define HERMES_AUX_PW0 0xFE01
65#define HERMES_AUX_PW1 0xDC23
66#define HERMES_AUX_PW2 0xBA45
67
68/* HERMES_CMD_DOWNLD */
69#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD)
70#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD)
71#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
72#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD)
73
74/*
55 * Debugging helpers 75 * Debugging helpers
56 */ 76 */
57 77
@@ -70,6 +90,7 @@
70 90
71#endif /* ! HERMES_DEBUG */ 91#endif /* ! HERMES_DEBUG */
72 92
93static const struct hermes_ops hermes_ops_local;
73 94
74/* 95/*
75 * Internal functions 96 * Internal functions
@@ -111,9 +132,9 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
111 */ 132 */
112 133
113/* For doing cmds that wipe the magic constant in SWSUPPORT0 */ 134/* For doing cmds that wipe the magic constant in SWSUPPORT0 */
114int hermes_doicmd_wait(hermes_t *hw, u16 cmd, 135static int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
115 u16 parm0, u16 parm1, u16 parm2, 136 u16 parm0, u16 parm1, u16 parm2,
116 struct hermes_response *resp) 137 struct hermes_response *resp)
117{ 138{
118 int err = 0; 139 int err = 0;
119 int k; 140 int k;
@@ -163,17 +184,18 @@ int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
163out: 184out:
164 return err; 185 return err;
165} 186}
166EXPORT_SYMBOL(hermes_doicmd_wait);
167 187
168void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) 188void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
169{ 189{
170 hw->iobase = address; 190 hw->iobase = address;
171 hw->reg_spacing = reg_spacing; 191 hw->reg_spacing = reg_spacing;
172 hw->inten = 0x0; 192 hw->inten = 0x0;
193 hw->eeprom_pda = false;
194 hw->ops = &hermes_ops_local;
173} 195}
174EXPORT_SYMBOL(hermes_struct_init); 196EXPORT_SYMBOL(hermes_struct_init);
175 197
176int hermes_init(hermes_t *hw) 198static int hermes_init(hermes_t *hw)
177{ 199{
178 u16 reg; 200 u16 reg;
179 int err = 0; 201 int err = 0;
@@ -217,7 +239,6 @@ int hermes_init(hermes_t *hw)
217 239
218 return err; 240 return err;
219} 241}
220EXPORT_SYMBOL(hermes_init);
221 242
222/* Issue a command to the chip, and (busy!) wait for it to 243/* Issue a command to the chip, and (busy!) wait for it to
223 * complete. 244 * complete.
@@ -228,8 +249,8 @@ EXPORT_SYMBOL(hermes_init);
228 * > 0 on error returned by the firmware 249 * > 0 on error returned by the firmware
229 * 250 *
230 * Callable from any context, but locking is your problem. */ 251 * Callable from any context, but locking is your problem. */
231int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, 252static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
232 struct hermes_response *resp) 253 struct hermes_response *resp)
233{ 254{
234 int err; 255 int err;
235 int k; 256 int k;
@@ -291,9 +312,8 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
291 out: 312 out:
292 return err; 313 return err;
293} 314}
294EXPORT_SYMBOL(hermes_docmd_wait);
295 315
296int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) 316static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
297{ 317{
298 int err = 0; 318 int err = 0;
299 int k; 319 int k;
@@ -333,7 +353,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
333 353
334 return 0; 354 return 0;
335} 355}
336EXPORT_SYMBOL(hermes_allocate);
337 356
338/* Set up a BAP to read a particular chunk of data from card's internal buffer. 357/* Set up a BAP to read a particular chunk of data from card's internal buffer.
339 * 358 *
@@ -403,8 +422,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
403 * 0 on success 422 * 0 on success
404 * > 0 on error from firmware 423 * > 0 on error from firmware
405 */ 424 */
406int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, 425static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
407 u16 id, u16 offset) 426 u16 id, u16 offset)
408{ 427{
409 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 428 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
410 int err = 0; 429 int err = 0;
@@ -422,7 +441,6 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
422 out: 441 out:
423 return err; 442 return err;
424} 443}
425EXPORT_SYMBOL(hermes_bap_pread);
426 444
427/* Write a block of data to the chip's buffer, via the 445/* Write a block of data to the chip's buffer, via the
428 * BAP. Synchronization/serialization is the caller's problem. 446 * BAP. Synchronization/serialization is the caller's problem.
@@ -432,8 +450,8 @@ EXPORT_SYMBOL(hermes_bap_pread);
432 * 0 on success 450 * 0 on success
433 * > 0 on error from firmware 451 * > 0 on error from firmware
434 */ 452 */
435int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, 453static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
436 u16 id, u16 offset) 454 u16 id, u16 offset)
437{ 455{
438 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 456 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
439 int err = 0; 457 int err = 0;
@@ -451,7 +469,6 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
451 out: 469 out:
452 return err; 470 return err;
453} 471}
454EXPORT_SYMBOL(hermes_bap_pwrite);
455 472
456/* Read a Length-Type-Value record from the card. 473/* Read a Length-Type-Value record from the card.
457 * 474 *
@@ -461,8 +478,8 @@ EXPORT_SYMBOL(hermes_bap_pwrite);
461 * practice. 478 * practice.
462 * 479 *
463 * Callable from user or bh context. */ 480 * Callable from user or bh context. */
464int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, 481static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
465 u16 *length, void *buf) 482 u16 *length, void *buf)
466{ 483{
467 int err = 0; 484 int err = 0;
468 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 485 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -505,10 +522,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
505 522
506 return 0; 523 return 0;
507} 524}
508EXPORT_SYMBOL(hermes_read_ltv);
509 525
510int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 526static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
511 u16 length, const void *value) 527 u16 length, const void *value)
512{ 528{
513 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 529 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
514 int err = 0; 530 int err = 0;
@@ -533,4 +549,228 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
533 549
534 return err; 550 return err;
535} 551}
536EXPORT_SYMBOL(hermes_write_ltv); 552
553/*** Hermes AUX control ***/
554
555static inline void
556hermes_aux_setaddr(hermes_t *hw, u32 addr)
557{
558 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
559 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
560}
561
562static inline int
563hermes_aux_control(hermes_t *hw, int enabled)
564{
565 int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
566 int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
567 int i;
568
569 /* Already open? */
570 if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
571 return 0;
572
573 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
574 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
575 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
576 hermes_write_reg(hw, HERMES_CONTROL, action);
577
578 for (i = 0; i < 20; i++) {
579 udelay(10);
580 if (hermes_read_reg(hw, HERMES_CONTROL) ==
581 desired_state)
582 return 0;
583 }
584
585 return -EBUSY;
586}
587
588/*** Hermes programming ***/
589
590/* About to start programming data (Hermes I)
591 * offset is the entry point
592 *
593 * Spectrum_cs' Symbol fw does not require this
594 * wl_lkm Agere fw does
595 * Don't know about intersil
596 */
597static int hermesi_program_init(hermes_t *hw, u32 offset)
598{
599 int err;
600
601 /* Disable interrupts?*/
602 /*hw->inten = 0x0;*/
603 /*hermes_write_regn(hw, INTEN, 0);*/
604 /*hermes_set_irqmask(hw, 0);*/
605
606 /* Acknowledge any outstanding command */
607 hermes_write_regn(hw, EVACK, 0xFFFF);
608
609 /* Using init_cmd_wait rather than cmd_wait */
610 err = hw->ops->init_cmd_wait(hw,
611 0x0100 | HERMES_CMD_INIT,
612 0, 0, 0, NULL);
613 if (err)
614 return err;
615
616 err = hw->ops->init_cmd_wait(hw,
617 0x0000 | HERMES_CMD_INIT,
618 0, 0, 0, NULL);
619 if (err)
620 return err;
621
622 err = hermes_aux_control(hw, 1);
623 pr_debug("AUX enable returned %d\n", err);
624
625 if (err)
626 return err;
627
628 pr_debug("Enabling volatile, EP 0x%08x\n", offset);
629 err = hw->ops->init_cmd_wait(hw,
630 HERMES_PROGRAM_ENABLE_VOLATILE,
631 offset & 0xFFFFu,
632 offset >> 16,
633 0,
634 NULL);
635 pr_debug("PROGRAM_ENABLE returned %d\n", err);
636
637 return err;
638}
639
640/* Done programming data (Hermes I)
641 *
642 * Spectrum_cs' Symbol fw does not require this
643 * wl_lkm Agere fw does
644 * Don't know about intersil
645 */
646static int hermesi_program_end(hermes_t *hw)
647{
648 struct hermes_response resp;
649 int rc = 0;
650 int err;
651
652 rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
653
654 pr_debug("PROGRAM_DISABLE returned %d, "
655 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
656 rc, resp.resp0, resp.resp1, resp.resp2);
657
658 if ((rc == 0) &&
659 ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
660 rc = -EIO;
661
662 err = hermes_aux_control(hw, 0);
663 pr_debug("AUX disable returned %d\n", err);
664
665 /* Acknowledge any outstanding command */
666 hermes_write_regn(hw, EVACK, 0xFFFF);
667
668 /* Reinitialise, ignoring return */
669 (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
670 0, 0, 0, NULL);
671
672 return rc ? rc : err;
673}
674
675static int hermes_program_bytes(struct hermes *hw, const char *data,
676 u32 addr, u32 len)
677{
678 /* wl lkm splits the programming into chunks of 2000 bytes.
679 * This restriction appears to come from USB. The PCMCIA
680 * adapters can program the whole lot in one go */
681 hermes_aux_setaddr(hw, addr);
682 hermes_write_bytes(hw, HERMES_AUXDATA, data, len);
683 return 0;
684}
685
686/* Read PDA from the adapter */
687static int hermes_read_pda(hermes_t *hw, __le16 *pda, u32 pda_addr, u16 pda_len)
688{
689 int ret;
690 u16 pda_size;
691 u16 data_len = pda_len;
692 __le16 *data = pda;
693
694 if (hw->eeprom_pda) {
695 /* PDA of spectrum symbol is in eeprom */
696
697 /* Issue command to read EEPROM */
698 ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
699 if (ret)
700 return ret;
701 } else {
702 /* wl_lkm does not include PDA size in the PDA area.
703 * We will pad the information into pda, so other routines
704 * don't have to be modified */
705 pda[0] = cpu_to_le16(pda_len - 2);
706 /* Includes CFG_PROD_DATA but not itself */
707 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
708 data_len = pda_len - 4;
709 data = pda + 2;
710 }
711
712 /* Open auxiliary port */
713 ret = hermes_aux_control(hw, 1);
714 pr_debug("AUX enable returned %d\n", ret);
715 if (ret)
716 return ret;
717
718 /* Read PDA */
719 hermes_aux_setaddr(hw, pda_addr);
720 hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
721
722 /* Close aux port */
723 ret = hermes_aux_control(hw, 0);
724 pr_debug("AUX disable returned %d\n", ret);
725
726 /* Check PDA length */
727 pda_size = le16_to_cpu(pda[0]);
728 pr_debug("Actual PDA length %d, Max allowed %d\n",
729 pda_size, pda_len);
730 if (pda_size > pda_len)
731 return -EINVAL;
732
733 return 0;
734}
735
736static void hermes_lock_irqsave(spinlock_t *lock,
737 unsigned long *flags) __acquires(lock)
738{
739 spin_lock_irqsave(lock, *flags);
740}
741
742static void hermes_unlock_irqrestore(spinlock_t *lock,
743 unsigned long *flags) __releases(lock)
744{
745 spin_unlock_irqrestore(lock, *flags);
746}
747
748static void hermes_lock_irq(spinlock_t *lock) __acquires(lock)
749{
750 spin_lock_irq(lock);
751}
752
753static void hermes_unlock_irq(spinlock_t *lock) __releases(lock)
754{
755 spin_unlock_irq(lock);
756}
757
758/* Hermes operations for local buses */
759static const struct hermes_ops hermes_ops_local = {
760 .init = hermes_init,
761 .cmd_wait = hermes_docmd_wait,
762 .init_cmd_wait = hermes_doicmd_wait,
763 .allocate = hermes_allocate,
764 .read_ltv = hermes_read_ltv,
765 .write_ltv = hermes_write_ltv,
766 .bap_pread = hermes_bap_pread,
767 .bap_pwrite = hermes_bap_pwrite,
768 .read_pda = hermes_read_pda,
769 .program_init = hermesi_program_init,
770 .program_end = hermesi_program_end,
771 .program = hermes_program_bytes,
772 .lock_irqsave = hermes_lock_irqsave,
773 .unlock_irqrestore = hermes_unlock_irqrestore,
774 .lock_irq = hermes_lock_irq,
775 .unlock_irq = hermes_unlock_irq,
776};
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index 2dddbb597c4d..9ca34e722b45 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -374,6 +374,37 @@ struct hermes_multicast {
374/* Timeouts */ 374/* Timeouts */
375#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ 375#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
376 376
377struct hermes;
378
379/* Functions to access hardware */
380struct hermes_ops {
381 int (*init)(struct hermes *hw);
382 int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0,
383 struct hermes_response *resp);
384 int (*init_cmd_wait)(struct hermes *hw, u16 cmd,
385 u16 parm0, u16 parm1, u16 parm2,
386 struct hermes_response *resp);
387 int (*allocate)(struct hermes *hw, u16 size, u16 *fid);
388 int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen,
389 u16 *length, void *buf);
390 int (*write_ltv)(struct hermes *hw, int bap, u16 rid,
391 u16 length, const void *value);
392 int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len,
393 u16 id, u16 offset);
394 int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
395 int len, u16 id, u16 offset);
396 int (*read_pda)(struct hermes *hw, __le16 *pda,
397 u32 pda_addr, u16 pda_len);
398 int (*program_init)(struct hermes *hw, u32 entry_point);
399 int (*program_end)(struct hermes *hw);
400 int (*program)(struct hermes *hw, const char *buf,
401 u32 addr, u32 len);
402 void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags);
403 void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags);
404 void (*lock_irq)(spinlock_t *lock);
405 void (*unlock_irq)(spinlock_t *lock);
406};
407
377/* Basic control structure */ 408/* Basic control structure */
378typedef struct hermes { 409typedef struct hermes {
379 void __iomem *iobase; 410 void __iomem *iobase;
@@ -381,6 +412,9 @@ typedef struct hermes {
381#define HERMES_16BIT_REGSPACING 0 412#define HERMES_16BIT_REGSPACING 0
382#define HERMES_32BIT_REGSPACING 1 413#define HERMES_32BIT_REGSPACING 1
383 u16 inten; /* Which interrupts should be enabled? */ 414 u16 inten; /* Which interrupts should be enabled? */
415 bool eeprom_pda;
416 const struct hermes_ops *ops;
417 void *priv;
384} hermes_t; 418} hermes_t;
385 419
386/* Register access convenience macros */ 420/* Register access convenience macros */
@@ -394,22 +428,6 @@ typedef struct hermes {
394 428
395/* Function prototypes */ 429/* Function prototypes */
396void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing); 430void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
397int hermes_init(hermes_t *hw);
398int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
399 struct hermes_response *resp);
400int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
401 u16 parm0, u16 parm1, u16 parm2,
402 struct hermes_response *resp);
403int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
404
405int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
406 u16 id, u16 offset);
407int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
408 u16 id, u16 offset);
409int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
410 u16 *length, void *buf);
411int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
412 u16 length, const void *value);
413 431
414/* Inline functions */ 432/* Inline functions */
415 433
@@ -426,13 +444,13 @@ static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
426 444
427static inline int hermes_enable_port(hermes_t *hw, int port) 445static inline int hermes_enable_port(hermes_t *hw, int port)
428{ 446{
429 return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), 447 return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
430 0, NULL); 448 0, NULL);
431} 449}
432 450
433static inline int hermes_disable_port(hermes_t *hw, int port) 451static inline int hermes_disable_port(hermes_t *hw, int port)
434{ 452{
435 return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 453 return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
436 0, NULL); 454 0, NULL);
437} 455}
438 456
@@ -440,7 +458,7 @@ static inline int hermes_disable_port(hermes_t *hw, int port)
440 * information frame in __orinoco_ev_info() */ 458 * information frame in __orinoco_ev_info() */
441static inline int hermes_inquire(hermes_t *hw, u16 rid) 459static inline int hermes_inquire(hermes_t *hw, u16 rid)
442{ 460{
443 return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); 461 return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
444} 462}
445 463
446#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1) 464#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
@@ -475,10 +493,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off,
475} 493}
476 494
477#define HERMES_READ_RECORD(hw, bap, rid, buf) \ 495#define HERMES_READ_RECORD(hw, bap, rid, buf) \
478 (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) 496 (hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
479#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ 497#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
480 (hermes_write_ltv((hw), (bap), (rid), \ 498 (hw->ops->write_ltv((hw), (bap), (rid), \
481 HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) 499 HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
482 500
483static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word) 501static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
484{ 502{
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index fb157eb889ca..6da85e75fce0 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -46,37 +46,11 @@
46 46
47#define PFX "hermes_dld: " 47#define PFX "hermes_dld: "
48 48
49/*
50 * AUX port access. To unlock the AUX port write the access keys to the
51 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
52 * register. Then read it and make sure it's HERMES_AUX_ENABLED.
53 */
54#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
55#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
56#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
57#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */
58
59#define HERMES_AUX_PW0 0xFE01
60#define HERMES_AUX_PW1 0xDC23
61#define HERMES_AUX_PW2 0xBA45
62
63/* HERMES_CMD_DOWNLD */
64#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD)
65#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD)
66#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
67#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD)
68
69/* End markers used in dblocks */ 49/* End markers used in dblocks */
70#define PDI_END 0x00000000 /* End of PDA */ 50#define PDI_END 0x00000000 /* End of PDA */
71#define BLOCK_END 0xFFFFFFFF /* Last image block */ 51#define BLOCK_END 0xFFFFFFFF /* Last image block */
72#define TEXT_END 0x1A /* End of text header */ 52#define TEXT_END 0x1A /* End of text header */
73 53
74/* Limit the amout we try to download in a single shot.
75 * Size is in bytes.
76 */
77#define MAX_DL_SIZE 1024
78#define LIMIT_PROGRAM_SIZE 0
79
80/* 54/*
81 * The following structures have little-endian fields denoted by 55 * The following structures have little-endian fields denoted by
82 * the leading underscore. Don't access them directly - use inline 56 * the leading underscore. Don't access them directly - use inline
@@ -165,41 +139,6 @@ pdi_len(const struct pdi *pdi)
165 return 2 * (le16_to_cpu(pdi->len) - 1); 139 return 2 * (le16_to_cpu(pdi->len) - 1);
166} 140}
167 141
168/*** Hermes AUX control ***/
169
170static inline void
171hermes_aux_setaddr(hermes_t *hw, u32 addr)
172{
173 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
174 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
175}
176
177static inline int
178hermes_aux_control(hermes_t *hw, int enabled)
179{
180 int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
181 int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
182 int i;
183
184 /* Already open? */
185 if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
186 return 0;
187
188 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
189 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
190 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
191 hermes_write_reg(hw, HERMES_CONTROL, action);
192
193 for (i = 0; i < 20; i++) {
194 udelay(10);
195 if (hermes_read_reg(hw, HERMES_CONTROL) ==
196 desired_state)
197 return 0;
198 }
199
200 return -EBUSY;
201}
202
203/*** Plug Data Functions ***/ 142/*** Plug Data Functions ***/
204 143
205/* 144/*
@@ -271,62 +210,7 @@ hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
271 return -EINVAL; 210 return -EINVAL;
272 211
273 /* do the actual plugging */ 212 /* do the actual plugging */
274 hermes_aux_setaddr(hw, pdr_addr(pdr)); 213 hw->ops->program(hw, pdi->data, pdr_addr(pdr), pdi_len(pdi));
275 hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
276
277 return 0;
278}
279
280/* Read PDA from the adapter */
281int hermes_read_pda(hermes_t *hw,
282 __le16 *pda,
283 u32 pda_addr,
284 u16 pda_len,
285 int use_eeprom) /* can we get this into hw? */
286{
287 int ret;
288 u16 pda_size;
289 u16 data_len = pda_len;
290 __le16 *data = pda;
291
292 if (use_eeprom) {
293 /* PDA of spectrum symbol is in eeprom */
294
295 /* Issue command to read EEPROM */
296 ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
297 if (ret)
298 return ret;
299 } else {
300 /* wl_lkm does not include PDA size in the PDA area.
301 * We will pad the information into pda, so other routines
302 * don't have to be modified */
303 pda[0] = cpu_to_le16(pda_len - 2);
304 /* Includes CFG_PROD_DATA but not itself */
305 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
306 data_len = pda_len - 4;
307 data = pda + 2;
308 }
309
310 /* Open auxiliary port */
311 ret = hermes_aux_control(hw, 1);
312 pr_debug(PFX "AUX enable returned %d\n", ret);
313 if (ret)
314 return ret;
315
316 /* read PDA from EEPROM */
317 hermes_aux_setaddr(hw, pda_addr);
318 hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
319
320 /* Close aux port */
321 ret = hermes_aux_control(hw, 0);
322 pr_debug(PFX "AUX disable returned %d\n", ret);
323
324 /* Check PDA length */
325 pda_size = le16_to_cpu(pda[0]);
326 pr_debug(PFX "Actual PDA length %d, Max allowed %d\n",
327 pda_size, pda_len);
328 if (pda_size > pda_len)
329 return -EINVAL;
330 214
331 return 0; 215 return 0;
332} 216}
@@ -389,101 +273,13 @@ hermes_blocks_length(const char *first_block, const void *end)
389 273
390/*** Hermes programming ***/ 274/*** Hermes programming ***/
391 275
392/* About to start programming data (Hermes I)
393 * offset is the entry point
394 *
395 * Spectrum_cs' Symbol fw does not require this
396 * wl_lkm Agere fw does
397 * Don't know about intersil
398 */
399int hermesi_program_init(hermes_t *hw, u32 offset)
400{
401 int err;
402
403 /* Disable interrupts?*/
404 /*hw->inten = 0x0;*/
405 /*hermes_write_regn(hw, INTEN, 0);*/
406 /*hermes_set_irqmask(hw, 0);*/
407
408 /* Acknowledge any outstanding command */
409 hermes_write_regn(hw, EVACK, 0xFFFF);
410
411 /* Using doicmd_wait rather than docmd_wait */
412 err = hermes_doicmd_wait(hw,
413 0x0100 | HERMES_CMD_INIT,
414 0, 0, 0, NULL);
415 if (err)
416 return err;
417
418 err = hermes_doicmd_wait(hw,
419 0x0000 | HERMES_CMD_INIT,
420 0, 0, 0, NULL);
421 if (err)
422 return err;
423
424 err = hermes_aux_control(hw, 1);
425 pr_debug(PFX "AUX enable returned %d\n", err);
426
427 if (err)
428 return err;
429
430 pr_debug(PFX "Enabling volatile, EP 0x%08x\n", offset);
431 err = hermes_doicmd_wait(hw,
432 HERMES_PROGRAM_ENABLE_VOLATILE,
433 offset & 0xFFFFu,
434 offset >> 16,
435 0,
436 NULL);
437 pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err);
438
439 return err;
440}
441
442/* Done programming data (Hermes I)
443 *
444 * Spectrum_cs' Symbol fw does not require this
445 * wl_lkm Agere fw does
446 * Don't know about intersil
447 */
448int hermesi_program_end(hermes_t *hw)
449{
450 struct hermes_response resp;
451 int rc = 0;
452 int err;
453
454 rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
455
456 pr_debug(PFX "PROGRAM_DISABLE returned %d, "
457 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
458 rc, resp.resp0, resp.resp1, resp.resp2);
459
460 if ((rc == 0) &&
461 ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
462 rc = -EIO;
463
464 err = hermes_aux_control(hw, 0);
465 pr_debug(PFX "AUX disable returned %d\n", err);
466
467 /* Acknowledge any outstanding command */
468 hermes_write_regn(hw, EVACK, 0xFFFF);
469
470 /* Reinitialise, ignoring return */
471 (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
472 0, 0, 0, NULL);
473
474 return rc ? rc : err;
475}
476
477/* Program the data blocks */ 276/* Program the data blocks */
478int hermes_program(hermes_t *hw, const char *first_block, const void *end) 277int hermes_program(hermes_t *hw, const char *first_block, const void *end)
479{ 278{
480 const struct dblock *blk; 279 const struct dblock *blk;
481 u32 blkaddr; 280 u32 blkaddr;
482 u32 blklen; 281 u32 blklen;
483#if LIMIT_PROGRAM_SIZE 282 int err = 0;
484 u32 addr;
485 u32 len;
486#endif
487 283
488 blk = (const struct dblock *) first_block; 284 blk = (const struct dblock *) first_block;
489 285
@@ -498,30 +294,10 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
498 pr_debug(PFX "Programming block of length %d " 294 pr_debug(PFX "Programming block of length %d "
499 "to address 0x%08x\n", blklen, blkaddr); 295 "to address 0x%08x\n", blklen, blkaddr);
500 296
501#if !LIMIT_PROGRAM_SIZE 297 err = hw->ops->program(hw, blk->data, blkaddr, blklen);
502 /* wl_lkm driver splits this into writes of 2000 bytes */ 298 if (err)
503 hermes_aux_setaddr(hw, blkaddr); 299 break;
504 hermes_write_bytes(hw, HERMES_AUXDATA, blk->data, 300
505 blklen);
506#else
507 len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE;
508 addr = blkaddr;
509
510 while (addr < (blkaddr + blklen)) {
511 pr_debug(PFX "Programming subblock of length %d "
512 "to address 0x%08x. Data @ %p\n",
513 len, addr, &blk->data[addr - blkaddr]);
514
515 hermes_aux_setaddr(hw, addr);
516 hermes_write_bytes(hw, HERMES_AUXDATA,
517 &blk->data[addr - blkaddr],
518 len);
519
520 addr += len;
521 len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ?
522 (blkaddr + blklen - addr) : MAX_DL_SIZE;
523 }
524#endif
525 blk = (const struct dblock *) &blk->data[blklen]; 301 blk = (const struct dblock *) &blk->data[blklen];
526 302
527 if ((void *) blk > (end - sizeof(*blk))) 303 if ((void *) blk > (end - sizeof(*blk)))
@@ -530,7 +306,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
530 blkaddr = dblock_addr(blk); 306 blkaddr = dblock_addr(blk);
531 blklen = dblock_len(blk); 307 blklen = dblock_len(blk);
532 } 308 }
533 return 0; 309 return err;
534} 310}
535 311
536/*** Default plugging data for Hermes I ***/ 312/*** Default plugging data for Hermes I ***/
@@ -690,9 +466,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
690 if ((pdi_len(pdi) == pdr_len(pdr)) && 466 if ((pdi_len(pdi) == pdr_len(pdr)) &&
691 ((void *) pdi->data + pdi_len(pdi) < pda_end)) { 467 ((void *) pdi->data + pdi_len(pdi) < pda_end)) {
692 /* do the actual plugging */ 468 /* do the actual plugging */
693 hermes_aux_setaddr(hw, pdr_addr(pdr)); 469 hw->ops->program(hw, pdi->data, pdr_addr(pdr),
694 hermes_write_bytes(hw, HERMES_AUXDATA, 470 pdi_len(pdi));
695 pdi->data, pdi_len(pdi));
696 } 471 }
697 } 472 }
698 473
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index e6369242e49c..6fbd78850123 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -177,9 +177,9 @@ int determine_fw_capabilities(struct orinoco_private *priv,
177 /* 3Com MAC : 00:50:DA:* */ 177 /* 3Com MAC : 00:50:DA:* */
178 memset(tmp, 0, sizeof(tmp)); 178 memset(tmp, 0, sizeof(tmp));
179 /* Get the Symbol firmware version */ 179 /* Get the Symbol firmware version */
180 err = hermes_read_ltv(hw, USER_BAP, 180 err = hw->ops->read_ltv(hw, USER_BAP,
181 HERMES_RID_SECONDARYVERSION_SYMBOL, 181 HERMES_RID_SECONDARYVERSION_SYMBOL,
182 SYMBOL_MAX_VER_LEN, NULL, &tmp); 182 SYMBOL_MAX_VER_LEN, NULL, &tmp);
183 if (err) { 183 if (err) {
184 dev_warn(dev, "Error %d reading Symbol firmware info. " 184 dev_warn(dev, "Error %d reading Symbol firmware info. "
185 "Wildly guessing capabilities...\n", err); 185 "Wildly guessing capabilities...\n", err);
@@ -262,6 +262,13 @@ int determine_fw_capabilities(struct orinoco_private *priv,
262 if (fw_name) 262 if (fw_name)
263 dev_info(dev, "Firmware determined as %s\n", fw_name); 263 dev_info(dev, "Firmware determined as %s\n", fw_name);
264 264
265#ifndef CONFIG_HERMES_PRISM
266 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
267 dev_err(dev, "Support for Prism chipset is not enabled\n");
268 return -ENODEV;
269 }
270#endif
271
265 return 0; 272 return 0;
266} 273}
267 274
@@ -279,8 +286,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
279 u16 reclen; 286 u16 reclen;
280 287
281 /* Get the MAC address */ 288 /* Get the MAC address */
282 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 289 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
283 ETH_ALEN, NULL, dev_addr); 290 ETH_ALEN, NULL, dev_addr);
284 if (err) { 291 if (err) {
285 dev_warn(dev, "Failed to read MAC address!\n"); 292 dev_warn(dev, "Failed to read MAC address!\n");
286 goto out; 293 goto out;
@@ -289,8 +296,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
289 dev_dbg(dev, "MAC address %pM\n", dev_addr); 296 dev_dbg(dev, "MAC address %pM\n", dev_addr);
290 297
291 /* Get the station name */ 298 /* Get the station name */
292 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 299 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
293 sizeof(nickbuf), &reclen, &nickbuf); 300 sizeof(nickbuf), &reclen, &nickbuf);
294 if (err) { 301 if (err) {
295 dev_err(dev, "failed to read station name\n"); 302 dev_err(dev, "failed to read station name\n");
296 goto out; 303 goto out;
@@ -367,6 +374,32 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
367 err = hermes_read_wordrec(hw, USER_BAP, 374 err = hermes_read_wordrec(hw, USER_BAP,
368 HERMES_RID_CNFPREAMBLE_SYMBOL, 375 HERMES_RID_CNFPREAMBLE_SYMBOL,
369 &priv->preamble); 376 &priv->preamble);
377 if (err) {
378 dev_err(dev, "Failed to read preamble setup\n");
379 goto out;
380 }
381 }
382
383 /* Retry settings */
384 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
385 &priv->short_retry_limit);
386 if (err) {
387 dev_err(dev, "Failed to read short retry limit\n");
388 goto out;
389 }
390
391 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
392 &priv->long_retry_limit);
393 if (err) {
394 dev_err(dev, "Failed to read long retry limit\n");
395 goto out;
396 }
397
398 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
399 &priv->retry_lifetime);
400 if (err) {
401 dev_err(dev, "Failed to read max retry lifetime\n");
402 goto out;
370 } 403 }
371 404
372out: 405out:
@@ -380,11 +413,11 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv)
380 struct hermes *hw = &priv->hw; 413 struct hermes *hw = &priv->hw;
381 int err; 414 int err;
382 415
383 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 416 err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid);
384 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { 417 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
385 /* Try workaround for old Symbol firmware bug */ 418 /* Try workaround for old Symbol firmware bug */
386 priv->nicbuf_size = TX_NICBUF_SIZE_BUG; 419 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
387 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 420 err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid);
388 421
389 dev_warn(dev, "Firmware ALLOC bug detected " 422 dev_warn(dev, "Firmware ALLOC bug detected "
390 "(old Symbol firmware?). Work around %s\n", 423 "(old Symbol firmware?). Work around %s\n",
@@ -430,8 +463,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
430 struct hermes_idstring idbuf; 463 struct hermes_idstring idbuf;
431 464
432 /* Set the MAC address */ 465 /* Set the MAC address */
433 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 466 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
434 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); 467 HERMES_BYTES_TO_RECLEN(ETH_ALEN),
468 dev->dev_addr);
435 if (err) { 469 if (err) {
436 printk(KERN_ERR "%s: Error %d setting MAC address\n", 470 printk(KERN_ERR "%s: Error %d setting MAC address\n",
437 dev->name, err); 471 dev->name, err);
@@ -494,7 +528,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
494 idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); 528 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
495 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); 529 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
496 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ 530 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
497 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, 531 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
498 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 532 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
499 &idbuf); 533 &idbuf);
500 if (err) { 534 if (err) {
@@ -502,7 +536,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
502 dev->name, err); 536 dev->name, err);
503 return err; 537 return err;
504 } 538 }
505 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, 539 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
506 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 540 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
507 &idbuf); 541 &idbuf);
508 if (err) { 542 if (err) {
@@ -514,9 +548,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
514 /* Set the station name */ 548 /* Set the station name */
515 idbuf.len = cpu_to_le16(strlen(priv->nick)); 549 idbuf.len = cpu_to_le16(strlen(priv->nick));
516 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); 550 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
517 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 551 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
518 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), 552 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
519 &idbuf); 553 &idbuf);
520 if (err) { 554 if (err) {
521 printk(KERN_ERR "%s: Error %d setting nickname\n", 555 printk(KERN_ERR "%s: Error %d setting nickname\n",
522 dev->name, err); 556 dev->name, err);
@@ -631,12 +665,12 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
631 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 665 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
632 /* Enable monitor mode */ 666 /* Enable monitor mode */
633 dev->type = ARPHRD_IEEE80211; 667 dev->type = ARPHRD_IEEE80211;
634 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 668 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
635 HERMES_TEST_MONITOR, 0, NULL); 669 HERMES_TEST_MONITOR, 0, NULL);
636 } else { 670 } else {
637 /* Disable monitor mode */ 671 /* Disable monitor mode */
638 dev->type = ARPHRD_ETHER; 672 dev->type = ARPHRD_ETHER;
639 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 673 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
640 HERMES_TEST_STOP, 0, NULL); 674 HERMES_TEST_STOP, 0, NULL);
641 } 675 }
642 if (err) 676 if (err)
@@ -662,8 +696,8 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
662 if ((key < 0) || (key >= 4)) 696 if ((key < 0) || (key >= 4))
663 return -EINVAL; 697 return -EINVAL;
664 698
665 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, 699 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
666 sizeof(tsc_arr), NULL, &tsc_arr); 700 sizeof(tsc_arr), NULL, &tsc_arr);
667 if (!err) 701 if (!err)
668 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); 702 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
669 703
@@ -842,7 +876,7 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
842 memcpy(key, priv->keys[i].key, 876 memcpy(key, priv->keys[i].key,
843 priv->keys[i].key_len); 877 priv->keys[i].key_len);
844 878
845 err = hermes_write_ltv(hw, USER_BAP, 879 err = hw->ops->write_ltv(hw, USER_BAP,
846 HERMES_RID_CNFDEFAULTKEY0 + i, 880 HERMES_RID_CNFDEFAULTKEY0 + i,
847 HERMES_BYTES_TO_RECLEN(keylen), 881 HERMES_BYTES_TO_RECLEN(keylen),
848 key); 882 key);
@@ -1049,17 +1083,17 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
1049 * group address if either we want to multicast, or if we were 1083 * group address if either we want to multicast, or if we were
1050 * multicasting and want to stop */ 1084 * multicasting and want to stop */
1051 if (!promisc && (mc_count || priv->mc_count)) { 1085 if (!promisc && (mc_count || priv->mc_count)) {
1052 struct dev_mc_list *p; 1086 struct netdev_hw_addr *ha;
1053 struct hermes_multicast mclist; 1087 struct hermes_multicast mclist;
1054 int i = 0; 1088 int i = 0;
1055 1089
1056 netdev_for_each_mc_addr(p, dev) { 1090 netdev_for_each_mc_addr(ha, dev) {
1057 if (i == mc_count) 1091 if (i == mc_count)
1058 break; 1092 break;
1059 memcpy(mclist.addr[i++], p->dmi_addr, ETH_ALEN); 1093 memcpy(mclist.addr[i++], ha->addr, ETH_ALEN);
1060 } 1094 }
1061 1095
1062 err = hermes_write_ltv(hw, USER_BAP, 1096 err = hw->ops->write_ltv(hw, USER_BAP,
1063 HERMES_RID_CNFGROUPADDRESSES, 1097 HERMES_RID_CNFGROUPADDRESSES,
1064 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), 1098 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
1065 &mclist); 1099 &mclist);
@@ -1101,15 +1135,15 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
1101 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : 1135 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
1102 HERMES_RID_CNFDESIREDSSID; 1136 HERMES_RID_CNFDESIREDSSID;
1103 1137
1104 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), 1138 err = hw->ops->read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
1105 NULL, &essidbuf); 1139 NULL, &essidbuf);
1106 if (err) 1140 if (err)
1107 goto fail_unlock; 1141 goto fail_unlock;
1108 } else { 1142 } else {
1109 *active = 0; 1143 *active = 0;
1110 1144
1111 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, 1145 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
1112 sizeof(essidbuf), NULL, &essidbuf); 1146 sizeof(essidbuf), NULL, &essidbuf);
1113 if (err) 1147 if (err)
1114 goto fail_unlock; 1148 goto fail_unlock;
1115 } 1149 }
@@ -1180,8 +1214,8 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
1180 if (orinoco_lock(priv, &flags) != 0) 1214 if (orinoco_lock(priv, &flags) != 0)
1181 return -EBUSY; 1215 return -EBUSY;
1182 1216
1183 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, 1217 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
1184 sizeof(list), NULL, &list); 1218 sizeof(list), NULL, &list);
1185 orinoco_unlock(priv, &flags); 1219 orinoco_unlock(priv, &flags);
1186 1220
1187 if (err) 1221 if (err)
@@ -1248,7 +1282,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv,
1248 idbuf.len = cpu_to_le16(len); 1282 idbuf.len = cpu_to_le16(len);
1249 memcpy(idbuf.val, ssid->ssid, len); 1283 memcpy(idbuf.val, ssid->ssid, len);
1250 1284
1251 err = hermes_write_ltv(hw, USER_BAP, 1285 err = hw->ops->write_ltv(hw, USER_BAP,
1252 HERMES_RID_CNFSCANSSID_AGERE, 1286 HERMES_RID_CNFSCANSSID_AGERE,
1253 HERMES_BYTES_TO_RECLEN(len + 2), 1287 HERMES_BYTES_TO_RECLEN(len + 2),
1254 &idbuf); 1288 &idbuf);
@@ -1312,8 +1346,8 @@ int orinoco_hw_get_current_bssid(struct orinoco_private *priv,
1312 hermes_t *hw = &priv->hw; 1346 hermes_t *hw = &priv->hw;
1313 int err; 1347 int err;
1314 1348
1315 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, 1349 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1316 ETH_ALEN, NULL, addr); 1350 ETH_ALEN, NULL, addr);
1317 1351
1318 return err; 1352 return err;
1319} 1353}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 9799a1d14a63..97af71e79950 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -22,7 +22,6 @@
22 22
23/* Forward declarations */ 23/* Forward declarations */
24struct orinoco_private; 24struct orinoco_private;
25struct dev_addr_list;
26 25
27int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name, 26int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name,
28 size_t fw_name_len, u32 *hw_ver); 27 size_t fw_name_len, u32 *hw_ver);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 413e9ab6cab3..ca71f08709bc 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -254,7 +254,7 @@ void set_port_type(struct orinoco_private *priv)
254/* Device methods */ 254/* Device methods */
255/********************************************************************/ 255/********************************************************************/
256 256
257static int orinoco_open(struct net_device *dev) 257int orinoco_open(struct net_device *dev)
258{ 258{
259 struct orinoco_private *priv = ndev_priv(dev); 259 struct orinoco_private *priv = ndev_priv(dev);
260 unsigned long flags; 260 unsigned long flags;
@@ -272,8 +272,9 @@ static int orinoco_open(struct net_device *dev)
272 272
273 return err; 273 return err;
274} 274}
275EXPORT_SYMBOL(orinoco_open);
275 276
276static int orinoco_stop(struct net_device *dev) 277int orinoco_stop(struct net_device *dev)
277{ 278{
278 struct orinoco_private *priv = ndev_priv(dev); 279 struct orinoco_private *priv = ndev_priv(dev);
279 int err = 0; 280 int err = 0;
@@ -281,25 +282,27 @@ static int orinoco_stop(struct net_device *dev)
281 /* We mustn't use orinoco_lock() here, because we need to be 282 /* We mustn't use orinoco_lock() here, because we need to be
282 able to close the interface even if hw_unavailable is set 283 able to close the interface even if hw_unavailable is set
283 (e.g. as we're released after a PC Card removal) */ 284 (e.g. as we're released after a PC Card removal) */
284 spin_lock_irq(&priv->lock); 285 orinoco_lock_irq(priv);
285 286
286 priv->open = 0; 287 priv->open = 0;
287 288
288 err = __orinoco_down(priv); 289 err = __orinoco_down(priv);
289 290
290 spin_unlock_irq(&priv->lock); 291 orinoco_unlock_irq(priv);
291 292
292 return err; 293 return err;
293} 294}
295EXPORT_SYMBOL(orinoco_stop);
294 296
295static struct net_device_stats *orinoco_get_stats(struct net_device *dev) 297struct net_device_stats *orinoco_get_stats(struct net_device *dev)
296{ 298{
297 struct orinoco_private *priv = ndev_priv(dev); 299 struct orinoco_private *priv = ndev_priv(dev);
298 300
299 return &priv->stats; 301 return &priv->stats;
300} 302}
303EXPORT_SYMBOL(orinoco_get_stats);
301 304
302static void orinoco_set_multicast_list(struct net_device *dev) 305void orinoco_set_multicast_list(struct net_device *dev)
303{ 306{
304 struct orinoco_private *priv = ndev_priv(dev); 307 struct orinoco_private *priv = ndev_priv(dev);
305 unsigned long flags; 308 unsigned long flags;
@@ -313,8 +316,9 @@ static void orinoco_set_multicast_list(struct net_device *dev)
313 __orinoco_set_multicast_list(dev); 316 __orinoco_set_multicast_list(dev);
314 orinoco_unlock(priv, &flags); 317 orinoco_unlock(priv, &flags);
315} 318}
319EXPORT_SYMBOL(orinoco_set_multicast_list);
316 320
317static int orinoco_change_mtu(struct net_device *dev, int new_mtu) 321int orinoco_change_mtu(struct net_device *dev, int new_mtu)
318{ 322{
319 struct orinoco_private *priv = ndev_priv(dev); 323 struct orinoco_private *priv = ndev_priv(dev);
320 324
@@ -330,23 +334,115 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
330 334
331 return 0; 335 return 0;
332} 336}
337EXPORT_SYMBOL(orinoco_change_mtu);
333 338
334/********************************************************************/ 339/********************************************************************/
335/* Tx path */ 340/* Tx path */
336/********************************************************************/ 341/********************************************************************/
337 342
343/* Add encapsulation and MIC to the existing SKB.
344 * The main xmit routine will then send the whole lot to the card.
345 * Need 8 bytes headroom
346 * Need 8 bytes tailroom
347 *
348 * With encapsulated ethernet II frame
349 * --------
350 * 803.3 header (14 bytes)
351 * dst[6]
352 * -------- src[6]
353 * 803.3 header (14 bytes) len[2]
354 * dst[6] 803.2 header (8 bytes)
355 * src[6] encaps[6]
356 * len[2] <- leave alone -> len[2]
357 * -------- -------- <-- 0
358 * Payload Payload
359 * ... ...
360 *
361 * -------- --------
362 * MIC (8 bytes)
363 * --------
364 *
365 * returns 0 on success, -ENOMEM on error.
366 */
367int orinoco_process_xmit_skb(struct sk_buff *skb,
368 struct net_device *dev,
369 struct orinoco_private *priv,
370 int *tx_control,
371 u8 *mic_buf)
372{
373 struct orinoco_tkip_key *key;
374 struct ethhdr *eh;
375 int do_mic;
376
377 key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
378
379 do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
380 (key != NULL));
381
382 if (do_mic)
383 *tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
384 HERMES_TXCTRL_MIC;
385
386 eh = (struct ethhdr *)skb->data;
387
388 /* Encapsulate Ethernet-II frames */
389 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
390 struct header_struct {
391 struct ethhdr eth; /* 802.3 header */
392 u8 encap[6]; /* 802.2 header */
393 } __attribute__ ((packed)) hdr;
394 int len = skb->len + sizeof(encaps_hdr) - (2 * ETH_ALEN);
395
396 if (skb_headroom(skb) < ENCAPS_OVERHEAD) {
397 if (net_ratelimit())
398 printk(KERN_ERR
399 "%s: Not enough headroom for 802.2 headers %d\n",
400 dev->name, skb_headroom(skb));
401 return -ENOMEM;
402 }
403
404 /* Fill in new header */
405 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
406 hdr.eth.h_proto = htons(len);
407 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
408
409 /* Make room for the new header, and copy it in */
410 eh = (struct ethhdr *) skb_push(skb, ENCAPS_OVERHEAD);
411 memcpy(eh, &hdr, sizeof(hdr));
412 }
413
414 /* Calculate Michael MIC */
415 if (do_mic) {
416 size_t len = skb->len - ETH_HLEN;
417 u8 *mic = &mic_buf[0];
418
419 /* Have to write to an even address, so copy the spare
420 * byte across */
421 if (skb->len % 2) {
422 *mic = skb->data[skb->len - 1];
423 mic++;
424 }
425
426 orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
427 eh->h_dest, eh->h_source, 0 /* priority */,
428 skb->data + ETH_HLEN,
429 len, mic);
430 }
431
432 return 0;
433}
434EXPORT_SYMBOL(orinoco_process_xmit_skb);
435
338static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) 436static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
339{ 437{
340 struct orinoco_private *priv = ndev_priv(dev); 438 struct orinoco_private *priv = ndev_priv(dev);
341 struct net_device_stats *stats = &priv->stats; 439 struct net_device_stats *stats = &priv->stats;
342 struct orinoco_tkip_key *key;
343 hermes_t *hw = &priv->hw; 440 hermes_t *hw = &priv->hw;
344 int err = 0; 441 int err = 0;
345 u16 txfid = priv->txfid; 442 u16 txfid = priv->txfid;
346 struct ethhdr *eh;
347 int tx_control; 443 int tx_control;
348 unsigned long flags; 444 unsigned long flags;
349 int do_mic; 445 u8 mic_buf[MICHAEL_MIC_LEN+1];
350 446
351 if (!netif_running(dev)) { 447 if (!netif_running(dev)) {
352 printk(KERN_ERR "%s: Tx on stopped device!\n", 448 printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -378,16 +474,12 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
378 if (skb->len < ETH_HLEN) 474 if (skb->len < ETH_HLEN)
379 goto drop; 475 goto drop;
380 476
381 key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
382
383 do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
384 (key != NULL));
385
386 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; 477 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
387 478
388 if (do_mic) 479 err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
389 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | 480 &mic_buf[0]);
390 HERMES_TXCTRL_MIC; 481 if (err)
482 goto drop;
391 483
392 if (priv->has_alt_txcntl) { 484 if (priv->has_alt_txcntl) {
393 /* WPA enabled firmwares have tx_cntl at the end of 485 /* WPA enabled firmwares have tx_cntl at the end of
@@ -400,8 +492,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
400 memset(&desc, 0, sizeof(desc)); 492 memset(&desc, 0, sizeof(desc));
401 493
402 *txcntl = cpu_to_le16(tx_control); 494 *txcntl = cpu_to_le16(tx_control);
403 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), 495 err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
404 txfid, 0); 496 txfid, 0);
405 if (err) { 497 if (err) {
406 if (net_ratelimit()) 498 if (net_ratelimit())
407 printk(KERN_ERR "%s: Error %d writing Tx " 499 printk(KERN_ERR "%s: Error %d writing Tx "
@@ -414,8 +506,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
414 memset(&desc, 0, sizeof(desc)); 506 memset(&desc, 0, sizeof(desc));
415 507
416 desc.tx_control = cpu_to_le16(tx_control); 508 desc.tx_control = cpu_to_le16(tx_control);
417 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), 509 err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
418 txfid, 0); 510 txfid, 0);
419 if (err) { 511 if (err) {
420 if (net_ratelimit()) 512 if (net_ratelimit())
421 printk(KERN_ERR "%s: Error %d writing Tx " 513 printk(KERN_ERR "%s: Error %d writing Tx "
@@ -430,68 +522,24 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
430 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); 522 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
431 } 523 }
432 524
433 eh = (struct ethhdr *)skb->data; 525 err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len,
434 526 txfid, HERMES_802_3_OFFSET);
435 /* Encapsulate Ethernet-II frames */
436 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
437 struct header_struct {
438 struct ethhdr eth; /* 802.3 header */
439 u8 encap[6]; /* 802.2 header */
440 } __attribute__ ((packed)) hdr;
441
442 /* Strip destination and source from the data */
443 skb_pull(skb, 2 * ETH_ALEN);
444
445 /* And move them to a separate header */
446 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
447 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
448 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
449
450 /* Insert the SNAP header */
451 if (skb_headroom(skb) < sizeof(hdr)) {
452 printk(KERN_ERR
453 "%s: Not enough headroom for 802.2 headers %d\n",
454 dev->name, skb_headroom(skb));
455 goto drop;
456 }
457 eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
458 memcpy(eh, &hdr, sizeof(hdr));
459 }
460
461 err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
462 txfid, HERMES_802_3_OFFSET);
463 if (err) { 527 if (err) {
464 printk(KERN_ERR "%s: Error %d writing packet to BAP\n", 528 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
465 dev->name, err); 529 dev->name, err);
466 goto busy; 530 goto busy;
467 } 531 }
468 532
469 /* Calculate Michael MIC */ 533 if (tx_control & HERMES_TXCTRL_MIC) {
470 if (do_mic) { 534 size_t offset = HERMES_802_3_OFFSET + skb->len;
471 u8 mic_buf[MICHAEL_MIC_LEN + 1]; 535 size_t len = MICHAEL_MIC_LEN;
472 u8 *mic;
473 size_t offset;
474 size_t len;
475 536
476 if (skb->len % 2) { 537 if (offset % 2) {
477 /* MIC start is on an odd boundary */ 538 offset--;
478 mic_buf[0] = skb->data[skb->len - 1]; 539 len++;
479 mic = &mic_buf[1];
480 offset = skb->len - 1;
481 len = MICHAEL_MIC_LEN + 1;
482 } else {
483 mic = &mic_buf[0];
484 offset = skb->len;
485 len = MICHAEL_MIC_LEN;
486 } 540 }
487 541 err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
488 orinoco_mic(priv->tx_tfm_mic, key->tx_mic, 542 txfid, offset);
489 eh->h_dest, eh->h_source, 0 /* priority */,
490 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
491
492 /* Write the MIC */
493 err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
494 txfid, HERMES_802_3_OFFSET + offset);
495 if (err) { 543 if (err) {
496 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", 544 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
497 dev->name, err); 545 dev->name, err);
@@ -502,7 +550,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
502 /* Finally, we actually initiate the send */ 550 /* Finally, we actually initiate the send */
503 netif_stop_queue(dev); 551 netif_stop_queue(dev);
504 552
505 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, 553 err = hw->ops->cmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
506 txfid, NULL); 554 txfid, NULL);
507 if (err) { 555 if (err) {
508 netif_start_queue(dev); 556 netif_start_queue(dev);
@@ -512,7 +560,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
512 goto busy; 560 goto busy;
513 } 561 }
514 562
515 dev->trans_start = jiffies;
516 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len; 563 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
517 goto ok; 564 goto ok;
518 565
@@ -572,9 +619,9 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
572 return; /* Nothing's really happened */ 619 return; /* Nothing's really happened */
573 620
574 /* Read part of the frame header - we need status and addr1 */ 621 /* Read part of the frame header - we need status and addr1 */
575 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, 622 err = hw->ops->bap_pread(hw, IRQ_BAP, &hdr,
576 sizeof(struct hermes_txexc_data), 623 sizeof(struct hermes_txexc_data),
577 fid, 0); 624 fid, 0);
578 625
579 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 626 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
580 stats->tx_errors++; 627 stats->tx_errors++;
@@ -615,7 +662,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
615 netif_wake_queue(dev); 662 netif_wake_queue(dev);
616} 663}
617 664
618static void orinoco_tx_timeout(struct net_device *dev) 665void orinoco_tx_timeout(struct net_device *dev)
619{ 666{
620 struct orinoco_private *priv = ndev_priv(dev); 667 struct orinoco_private *priv = ndev_priv(dev);
621 struct net_device_stats *stats = &priv->stats; 668 struct net_device_stats *stats = &priv->stats;
@@ -630,6 +677,7 @@ static void orinoco_tx_timeout(struct net_device *dev)
630 677
631 schedule_work(&priv->reset_work); 678 schedule_work(&priv->reset_work);
632} 679}
680EXPORT_SYMBOL(orinoco_tx_timeout);
633 681
634/********************************************************************/ 682/********************************************************************/
635/* Rx path (data frames) */ 683/* Rx path (data frames) */
@@ -764,9 +812,9 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
764 812
765 /* If any, copy the data from the card to the skb */ 813 /* If any, copy the data from the card to the skb */
766 if (datalen > 0) { 814 if (datalen > 0) {
767 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), 815 err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
768 ALIGN(datalen, 2), rxfid, 816 ALIGN(datalen, 2), rxfid,
769 HERMES_802_2_OFFSET); 817 HERMES_802_2_OFFSET);
770 if (err) { 818 if (err) {
771 printk(KERN_ERR "%s: error %d reading monitor frame\n", 819 printk(KERN_ERR "%s: error %d reading monitor frame\n",
772 dev->name, err); 820 dev->name, err);
@@ -792,7 +840,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
792 stats->rx_dropped++; 840 stats->rx_dropped++;
793} 841}
794 842
795static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 843void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
796{ 844{
797 struct orinoco_private *priv = ndev_priv(dev); 845 struct orinoco_private *priv = ndev_priv(dev);
798 struct net_device_stats *stats = &priv->stats; 846 struct net_device_stats *stats = &priv->stats;
@@ -814,8 +862,8 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
814 862
815 rxfid = hermes_read_regn(hw, RXFID); 863 rxfid = hermes_read_regn(hw, RXFID);
816 864
817 err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), 865 err = hw->ops->bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
818 rxfid, 0); 866 rxfid, 0);
819 if (err) { 867 if (err) {
820 printk(KERN_ERR "%s: error %d reading Rx descriptor. " 868 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
821 "Frame dropped.\n", dev->name, err); 869 "Frame dropped.\n", dev->name, err);
@@ -882,9 +930,9 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
882 nothing is removed. 2 is for aligning the IP header. */ 930 nothing is removed. 2 is for aligning the IP header. */
883 skb_reserve(skb, ETH_HLEN + 2); 931 skb_reserve(skb, ETH_HLEN + 2);
884 932
885 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), 933 err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, length),
886 ALIGN(length, 2), rxfid, 934 ALIGN(length, 2), rxfid,
887 HERMES_802_2_OFFSET); 935 HERMES_802_2_OFFSET);
888 if (err) { 936 if (err) {
889 printk(KERN_ERR "%s: error %d reading frame. " 937 printk(KERN_ERR "%s: error %d reading frame. "
890 "Frame dropped.\n", dev->name, err); 938 "Frame dropped.\n", dev->name, err);
@@ -913,6 +961,7 @@ update_stats:
913out: 961out:
914 kfree(desc); 962 kfree(desc);
915} 963}
964EXPORT_SYMBOL(__orinoco_ev_rx);
916 965
917static void orinoco_rx(struct net_device *dev, 966static void orinoco_rx(struct net_device *dev,
918 struct hermes_rx_descriptor *desc, 967 struct hermes_rx_descriptor *desc,
@@ -1145,9 +1194,9 @@ static void orinoco_join_ap(struct work_struct *work)
1145 goto out; 1194 goto out;
1146 1195
1147 /* Read scan results from the firmware */ 1196 /* Read scan results from the firmware */
1148 err = hermes_read_ltv(hw, USER_BAP, 1197 err = hw->ops->read_ltv(hw, USER_BAP,
1149 HERMES_RID_SCANRESULTSTABLE, 1198 HERMES_RID_SCANRESULTSTABLE,
1150 MAX_SCAN_LEN, &len, buf); 1199 MAX_SCAN_LEN, &len, buf);
1151 if (err) { 1200 if (err) {
1152 printk(KERN_ERR "%s: Cannot read scan results\n", 1201 printk(KERN_ERR "%s: Cannot read scan results\n",
1153 dev->name); 1202 dev->name);
@@ -1194,8 +1243,8 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
1194 union iwreq_data wrqu; 1243 union iwreq_data wrqu;
1195 int err; 1244 int err;
1196 1245
1197 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, 1246 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1198 ETH_ALEN, NULL, wrqu.ap_addr.sa_data); 1247 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1199 if (err != 0) 1248 if (err != 0)
1200 return; 1249 return;
1201 1250
@@ -1217,8 +1266,8 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
1217 if (!priv->has_wpa) 1266 if (!priv->has_wpa)
1218 return; 1267 return;
1219 1268
1220 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, 1269 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
1221 sizeof(buf), NULL, &buf); 1270 sizeof(buf), NULL, &buf);
1222 if (err != 0) 1271 if (err != 0)
1223 return; 1272 return;
1224 1273
@@ -1247,8 +1296,9 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
1247 if (!priv->has_wpa) 1296 if (!priv->has_wpa)
1248 return; 1297 return;
1249 1298
1250 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO, 1299 err = hw->ops->read_ltv(hw, USER_BAP,
1251 sizeof(buf), NULL, &buf); 1300 HERMES_RID_CURRENT_ASSOC_RESP_INFO,
1301 sizeof(buf), NULL, &buf);
1252 if (err != 0) 1302 if (err != 0)
1253 return; 1303 return;
1254 1304
@@ -1353,7 +1403,7 @@ static void orinoco_process_scan_results(struct work_struct *work)
1353 spin_unlock_irqrestore(&priv->scan_lock, flags); 1403 spin_unlock_irqrestore(&priv->scan_lock, flags);
1354} 1404}
1355 1405
1356static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) 1406void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1357{ 1407{
1358 struct orinoco_private *priv = ndev_priv(dev); 1408 struct orinoco_private *priv = ndev_priv(dev);
1359 u16 infofid; 1409 u16 infofid;
@@ -1371,8 +1421,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1371 infofid = hermes_read_regn(hw, INFOFID); 1421 infofid = hermes_read_regn(hw, INFOFID);
1372 1422
1373 /* Read the info frame header - don't try too hard */ 1423 /* Read the info frame header - don't try too hard */
1374 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), 1424 err = hw->ops->bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1375 infofid, 0); 1425 infofid, 0);
1376 if (err) { 1426 if (err) {
1377 printk(KERN_ERR "%s: error %d reading info frame. " 1427 printk(KERN_ERR "%s: error %d reading info frame. "
1378 "Frame dropped.\n", dev->name, err); 1428 "Frame dropped.\n", dev->name, err);
@@ -1393,8 +1443,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1393 len = sizeof(tallies); 1443 len = sizeof(tallies);
1394 } 1444 }
1395 1445
1396 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, 1446 err = hw->ops->bap_pread(hw, IRQ_BAP, &tallies, len,
1397 infofid, sizeof(info)); 1447 infofid, sizeof(info));
1398 if (err) 1448 if (err)
1399 break; 1449 break;
1400 1450
@@ -1429,8 +1479,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1429 break; 1479 break;
1430 } 1480 }
1431 1481
1432 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, 1482 err = hw->ops->bap_pread(hw, IRQ_BAP, &linkstatus, len,
1433 infofid, sizeof(info)); 1483 infofid, sizeof(info));
1434 if (err) 1484 if (err)
1435 break; 1485 break;
1436 newstatus = le16_to_cpu(linkstatus.linkstatus); 1486 newstatus = le16_to_cpu(linkstatus.linkstatus);
@@ -1494,8 +1544,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1494 } 1544 }
1495 1545
1496 /* Read scan data */ 1546 /* Read scan data */
1497 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, 1547 err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) buf, len,
1498 infofid, sizeof(info)); 1548 infofid, sizeof(info));
1499 if (err) { 1549 if (err) {
1500 kfree(buf); 1550 kfree(buf);
1501 qabort_scan(priv); 1551 qabort_scan(priv);
@@ -1547,8 +1597,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1547 break; 1597 break;
1548 1598
1549 /* Read scan data */ 1599 /* Read scan data */
1550 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len, 1600 err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) bss, len,
1551 infofid, sizeof(info)); 1601 infofid, sizeof(info));
1552 if (err) 1602 if (err)
1553 kfree(bss); 1603 kfree(bss);
1554 else 1604 else
@@ -1568,9 +1618,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1568 /* We don't actually do anything about it */ 1618 /* We don't actually do anything about it */
1569 break; 1619 break;
1570 } 1620 }
1571
1572 return;
1573} 1621}
1622EXPORT_SYMBOL(__orinoco_ev_info);
1574 1623
1575static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) 1624static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1576{ 1625{
@@ -1647,7 +1696,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv)
1647 struct hermes *hw = &priv->hw; 1696 struct hermes *hw = &priv->hw;
1648 int err; 1697 int err;
1649 1698
1650 err = hermes_init(hw); 1699 err = hw->ops->init(hw);
1651 if (priv->do_fw_download && !err) { 1700 if (priv->do_fw_download && !err) {
1652 err = orinoco_download(priv); 1701 err = orinoco_download(priv);
1653 if (err) 1702 if (err)
@@ -1735,7 +1784,7 @@ void orinoco_reset(struct work_struct *work)
1735 } 1784 }
1736 1785
1737 /* This has to be called from user context */ 1786 /* This has to be called from user context */
1738 spin_lock_irq(&priv->lock); 1787 orinoco_lock_irq(priv);
1739 1788
1740 priv->hw_unavailable--; 1789 priv->hw_unavailable--;
1741 1790
@@ -1750,7 +1799,7 @@ void orinoco_reset(struct work_struct *work)
1750 dev->trans_start = jiffies; 1799 dev->trans_start = jiffies;
1751 } 1800 }
1752 1801
1753 spin_unlock_irq(&priv->lock); 1802 orinoco_unlock_irq(priv);
1754 1803
1755 return; 1804 return;
1756 disable: 1805 disable:
@@ -1984,7 +2033,7 @@ int orinoco_init(struct orinoco_private *priv)
1984 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; 2033 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
1985 2034
1986 /* Initialize the firmware */ 2035 /* Initialize the firmware */
1987 err = hermes_init(hw); 2036 err = hw->ops->init(hw);
1988 if (err != 0) { 2037 if (err != 0) {
1989 dev_err(dev, "Failed to initialize firmware (err = %d)\n", 2038 dev_err(dev, "Failed to initialize firmware (err = %d)\n",
1990 err); 2039 err);
@@ -2067,9 +2116,9 @@ int orinoco_init(struct orinoco_private *priv)
2067 2116
2068 /* Make the hardware available, as long as it hasn't been 2117 /* Make the hardware available, as long as it hasn't been
2069 * removed elsewhere (e.g. by PCMCIA hot unplug) */ 2118 * removed elsewhere (e.g. by PCMCIA hot unplug) */
2070 spin_lock_irq(&priv->lock); 2119 orinoco_lock_irq(priv);
2071 priv->hw_unavailable--; 2120 priv->hw_unavailable--;
2072 spin_unlock_irq(&priv->lock); 2121 orinoco_unlock_irq(priv);
2073 2122
2074 dev_dbg(dev, "Ready\n"); 2123 dev_dbg(dev, "Ready\n");
2075 2124
@@ -2192,7 +2241,8 @@ EXPORT_SYMBOL(alloc_orinocodev);
2192 */ 2241 */
2193int orinoco_if_add(struct orinoco_private *priv, 2242int orinoco_if_add(struct orinoco_private *priv,
2194 unsigned long base_addr, 2243 unsigned long base_addr,
2195 unsigned int irq) 2244 unsigned int irq,
2245 const struct net_device_ops *ops)
2196{ 2246{
2197 struct wiphy *wiphy = priv_to_wiphy(priv); 2247 struct wiphy *wiphy = priv_to_wiphy(priv);
2198 struct wireless_dev *wdev; 2248 struct wireless_dev *wdev;
@@ -2211,16 +2261,21 @@ int orinoco_if_add(struct orinoco_private *priv,
2211 2261
2212 /* Setup / override net_device fields */ 2262 /* Setup / override net_device fields */
2213 dev->ieee80211_ptr = wdev; 2263 dev->ieee80211_ptr = wdev;
2214 dev->netdev_ops = &orinoco_netdev_ops;
2215 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2264 dev->watchdog_timeo = HZ; /* 1 second timeout */
2216 dev->wireless_handlers = &orinoco_handler_def; 2265 dev->wireless_handlers = &orinoco_handler_def;
2217#ifdef WIRELESS_SPY 2266#ifdef WIRELESS_SPY
2218 dev->wireless_data = &priv->wireless_data; 2267 dev->wireless_data = &priv->wireless_data;
2219#endif 2268#endif
2269 /* Default to standard ops if not set */
2270 if (ops)
2271 dev->netdev_ops = ops;
2272 else
2273 dev->netdev_ops = &orinoco_netdev_ops;
2274
2220 /* we use the default eth_mac_addr for setting the MAC addr */ 2275 /* we use the default eth_mac_addr for setting the MAC addr */
2221 2276
2222 /* Reserve space in skb for the SNAP header */ 2277 /* Reserve space in skb for the SNAP header */
2223 dev->hard_header_len += ENCAPS_OVERHEAD; 2278 dev->needed_headroom = ENCAPS_OVERHEAD;
2224 2279
2225 netif_carrier_off(dev); 2280 netif_carrier_off(dev);
2226 2281
@@ -2305,7 +2360,7 @@ int orinoco_up(struct orinoco_private *priv)
2305 unsigned long flags; 2360 unsigned long flags;
2306 int err; 2361 int err;
2307 2362
2308 spin_lock_irqsave(&priv->lock, flags); 2363 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
2309 2364
2310 err = orinoco_reinit_firmware(priv); 2365 err = orinoco_reinit_firmware(priv);
2311 if (err) { 2366 if (err) {
@@ -2325,7 +2380,7 @@ int orinoco_up(struct orinoco_private *priv)
2325 } 2380 }
2326 2381
2327exit: 2382exit:
2328 spin_unlock_irqrestore(&priv->lock, flags); 2383 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
2329 2384
2330 return 0; 2385 return 0;
2331} 2386}
@@ -2337,7 +2392,7 @@ void orinoco_down(struct orinoco_private *priv)
2337 unsigned long flags; 2392 unsigned long flags;
2338 int err; 2393 int err;
2339 2394
2340 spin_lock_irqsave(&priv->lock, flags); 2395 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
2341 err = __orinoco_down(priv); 2396 err = __orinoco_down(priv);
2342 if (err) 2397 if (err)
2343 printk(KERN_WARNING "%s: Error %d downing interface\n", 2398 printk(KERN_WARNING "%s: Error %d downing interface\n",
@@ -2345,7 +2400,7 @@ void orinoco_down(struct orinoco_private *priv)
2345 2400
2346 netif_device_detach(dev); 2401 netif_device_detach(dev);
2347 priv->hw_unavailable++; 2402 priv->hw_unavailable++;
2348 spin_unlock_irqrestore(&priv->lock, flags); 2403 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
2349} 2404}
2350EXPORT_SYMBOL(orinoco_down); 2405EXPORT_SYMBOL(orinoco_down);
2351 2406
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
index 21ab36cd76c7..4dadf9880a97 100644
--- a/drivers/net/wireless/orinoco/main.h
+++ b/drivers/net/wireless/orinoco/main.h
@@ -33,18 +33,6 @@ int orinoco_commit(struct orinoco_private *priv);
33void orinoco_reset(struct work_struct *work); 33void orinoco_reset(struct work_struct *work);
34 34
35/* Information element helpers - find a home for these... */ 35/* Information element helpers - find a home for these... */
36static inline u8 *orinoco_get_ie(u8 *data, size_t len,
37 enum ieee80211_eid eid)
38{
39 u8 *p = data;
40 while ((p + 2) < (data + len)) {
41 if (p[0] == eid)
42 return p;
43 p += p[1] + 2;
44 }
45 return NULL;
46}
47
48#define WPA_OUI_TYPE "\x00\x50\xF2\x01" 36#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
49#define WPA_SELECTOR_LEN 4 37#define WPA_SELECTOR_LEN 4
50static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len) 38static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 665ef56f8382..a6da86e0a70f 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -131,6 +131,8 @@ struct orinoco_private {
131 u16 ap_density, rts_thresh; 131 u16 ap_density, rts_thresh;
132 u16 pm_on, pm_mcast, pm_period, pm_timeout; 132 u16 pm_on, pm_mcast, pm_period, pm_timeout;
133 u16 preamble; 133 u16 preamble;
134 u16 short_retry_limit, long_retry_limit;
135 u16 retry_lifetime;
134#ifdef WIRELESS_SPY 136#ifdef WIRELESS_SPY
135 struct iw_spy_data spy_data; /* iwspy support */ 137 struct iw_spy_data spy_data; /* iwspy support */
136 struct iw_public_data wireless_data; 138 struct iw_public_data wireless_data;
@@ -188,12 +190,30 @@ extern void free_orinocodev(struct orinoco_private *priv);
188extern int orinoco_init(struct orinoco_private *priv); 190extern int orinoco_init(struct orinoco_private *priv);
189extern int orinoco_if_add(struct orinoco_private *priv, 191extern int orinoco_if_add(struct orinoco_private *priv,
190 unsigned long base_addr, 192 unsigned long base_addr,
191 unsigned int irq); 193 unsigned int irq,
194 const struct net_device_ops *ops);
192extern void orinoco_if_del(struct orinoco_private *priv); 195extern void orinoco_if_del(struct orinoco_private *priv);
193extern int orinoco_up(struct orinoco_private *priv); 196extern int orinoco_up(struct orinoco_private *priv);
194extern void orinoco_down(struct orinoco_private *priv); 197extern void orinoco_down(struct orinoco_private *priv);
195extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); 198extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
196 199
200extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
201extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
202
203int orinoco_process_xmit_skb(struct sk_buff *skb,
204 struct net_device *dev,
205 struct orinoco_private *priv,
206 int *tx_control,
207 u8 *mic);
208
209/* Common ndo functions exported for reuse by orinoco_usb */
210int orinoco_open(struct net_device *dev);
211int orinoco_stop(struct net_device *dev);
212struct net_device_stats *orinoco_get_stats(struct net_device *dev);
213void orinoco_set_multicast_list(struct net_device *dev);
214int orinoco_change_mtu(struct net_device *dev, int new_mtu);
215void orinoco_tx_timeout(struct net_device *dev);
216
197/********************************************************************/ 217/********************************************************************/
198/* Locking and synchronization functions */ 218/* Locking and synchronization functions */
199/********************************************************************/ 219/********************************************************************/
@@ -201,11 +221,11 @@ extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
201static inline int orinoco_lock(struct orinoco_private *priv, 221static inline int orinoco_lock(struct orinoco_private *priv,
202 unsigned long *flags) 222 unsigned long *flags)
203{ 223{
204 spin_lock_irqsave(&priv->lock, *flags); 224 priv->hw.ops->lock_irqsave(&priv->lock, flags);
205 if (priv->hw_unavailable) { 225 if (priv->hw_unavailable) {
206 DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", 226 DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
207 priv->ndev); 227 priv->ndev);
208 spin_unlock_irqrestore(&priv->lock, *flags); 228 priv->hw.ops->unlock_irqrestore(&priv->lock, flags);
209 return -EBUSY; 229 return -EBUSY;
210 } 230 }
211 return 0; 231 return 0;
@@ -214,7 +234,17 @@ static inline int orinoco_lock(struct orinoco_private *priv,
214static inline void orinoco_unlock(struct orinoco_private *priv, 234static inline void orinoco_unlock(struct orinoco_private *priv,
215 unsigned long *flags) 235 unsigned long *flags)
216{ 236{
217 spin_unlock_irqrestore(&priv->lock, *flags); 237 priv->hw.ops->unlock_irqrestore(&priv->lock, flags);
238}
239
240static inline void orinoco_lock_irq(struct orinoco_private *priv)
241{
242 priv->hw.ops->lock_irq(&priv->lock);
243}
244
245static inline void orinoco_unlock_irq(struct orinoco_private *priv)
246{
247 priv->hw.ops->unlock_irq(&priv->lock);
218} 248}
219 249
220/*** Navigate from net_device to orinoco_private ***/ 250/*** Navigate from net_device to orinoco_private ***/
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 03056ab73032..b16d5db52a4d 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -281,7 +281,7 @@ orinoco_cs_config(struct pcmcia_device *link)
281 281
282 /* Register an interface with the stack */ 282 /* Register an interface with the stack */
283 if (orinoco_if_add(priv, link->io.BasePort1, 283 if (orinoco_if_add(priv, link->io.BasePort1,
284 link->irq) != 0) { 284 link->irq, NULL) != 0) {
285 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 285 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
286 goto failed; 286 goto failed;
287 } 287 }
@@ -306,9 +306,9 @@ orinoco_cs_release(struct pcmcia_device *link)
306 306
307 /* We're committed to taking the device away now, so mark the 307 /* We're committed to taking the device away now, so mark the
308 * hardware as unavailable */ 308 * hardware as unavailable */
309 spin_lock_irqsave(&priv->lock, flags); 309 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
310 priv->hw_unavailable++; 310 priv->hw_unavailable++;
311 spin_unlock_irqrestore(&priv->lock, flags); 311 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
312 312
313 pcmcia_disable_device(link); 313 pcmcia_disable_device(link);
314 if (priv->hw.iobase) 314 if (priv->hw.iobase)
@@ -353,87 +353,90 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
353 "Pavel Roskin <proski@gnu.org>, et al)"; 353 "Pavel Roskin <proski@gnu.org>, et al)";
354 354
355static struct pcmcia_device_id orinoco_cs_ids[] = { 355static struct pcmcia_device_id orinoco_cs_ids[] = {
356 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
357 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
358 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
359 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ 356 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
360 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
361 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
362 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ 357 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
363 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ 358 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
364 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ 359 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
365 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
366 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
367 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ 360 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
368 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ 361 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
369 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ 362 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */
370 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ 363 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
371 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
372 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
373 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
374 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
375 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ 364 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
376 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ 365 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
377 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ 366 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */
378 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ 367 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
368 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
369 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
370 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
371 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
372 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
373 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
374 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
375 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
376 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
377 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
378 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
379 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
380 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
381 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
382 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
383 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
384 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
385 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
386 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
387 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
388 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
389 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
390#ifdef CONFIG_HERMES_PRISM
391 /* Only entries that certainly identify Prism chipset */
392 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
393 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
394 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
395 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
396 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
397 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
398 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
399 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
400 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
401 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
402 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
379 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ 403 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
380 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ 404 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
381 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ 405 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
382 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ 406 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
383 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ 407 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
384 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ 408 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
385 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), 409 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
386 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
387 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), 410 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
388 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), 411 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
389 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
390 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
391 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
392 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
393 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
394 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
395 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), 412 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
396 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), 413 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
397 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), 414 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
398 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), 415 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
399 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), 416 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
400 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), 417 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
418 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
401 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), 419 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
402 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), 420 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
403 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), 421 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
404 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
405 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
406 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
407 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
408 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
409 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), 422 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
410 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), 423 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
411 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), 424 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
412 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
413 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), 425 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
414 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
415 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
416 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
417 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01), 426 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
418 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
419 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
420 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1), 427 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
421 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), 428 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
422 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), 429 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
423 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
424 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), 430 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
425 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), 431 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
426 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
427 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
428 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
429 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), 432 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
430 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), 433 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
431 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
432 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), 434 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
433 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092), 435 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
434 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2), 436 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
435 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b), 437 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
436 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), 438 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
439#endif
437 PCMCIA_DEVICE_NULL, 440 PCMCIA_DEVICE_NULL,
438}; 441};
439MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); 442MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 075f446b3139..bc3ea0b67a4f 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -220,7 +220,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
220 goto fail; 220 goto fail;
221 } 221 }
222 222
223 err = orinoco_if_add(priv, 0, 0); 223 err = orinoco_if_add(priv, 0, 0, NULL);
224 if (err) { 224 if (err) {
225 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 225 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
226 goto fail; 226 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index bda5317cc596..468197f86673 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -170,7 +170,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
170 goto fail; 170 goto fail;
171 } 171 }
172 172
173 err = orinoco_if_add(priv, 0, 0); 173 err = orinoco_if_add(priv, 0, 0, NULL);
174 if (err) { 174 if (err) {
175 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 175 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
176 goto fail; 176 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index e0d5874ab42f..9358f4d2307b 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -259,7 +259,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
259 goto fail; 259 goto fail;
260 } 260 }
261 261
262 err = orinoco_if_add(priv, 0, 0); 262 err = orinoco_if_add(priv, 0, 0, NULL);
263 if (err) { 263 if (err) {
264 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 264 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
265 goto fail; 265 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 88cbc7902aa0..784605f0af15 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -156,7 +156,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
156 goto fail; 156 goto fail;
157 } 157 }
158 158
159 err = orinoco_if_add(priv, 0, 0); 159 err = orinoco_if_add(priv, 0, 0, NULL);
160 if (err) { 160 if (err) {
161 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 161 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
162 goto fail; 162 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
new file mode 100644
index 000000000000..78f089baa8c9
--- /dev/null
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -0,0 +1,1795 @@
1/*
2 * USB Orinoco driver
3 *
4 * Copyright (c) 2003 Manuel Estrada Sainz
5 *
6 * The contents of this file are subject to the Mozilla Public License
7 * Version 1.1 (the "License"); you may not use this file except in
8 * compliance with the License. You may obtain a copy of the License
9 * at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS"
12 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
13 * the License for the specific language governing rights and
14 * limitations under the License.
15 *
16 * Alternatively, the contents of this file may be used under the
17 * terms of the GNU General Public License version 2 (the "GPL"), in
18 * which case the provisions of the GPL are applicable instead of the
19 * above. If you wish to allow the use of your version of this file
20 * only under the terms of the GPL and not to allow others to use your
21 * version of this file under the MPL, indicate your decision by
22 * deleting the provisions above and replace them with the notice and
23 * other provisions required by the GPL. If you do not delete the
24 * provisions above, a recipient may use your version of this file
25 * under either the MPL or the GPL.
26 *
27 * Queueing code based on linux-wlan-ng 0.2.1-pre5
28 *
29 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
30 *
31 * The license is the same as above.
32 *
33 * Initialy based on USB Skeleton driver - 0.7
34 *
35 * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
36 *
37 * This program is free software; you can redistribute it and/or
38 * modify it under the terms of the GNU General Public License as
39 * published by the Free Software Foundation; either version 2 of
40 * the License, or (at your option) any later version.
41 *
42 * NOTE: The original USB Skeleton driver is GPL, but all that code is
43 * gone so MPL/GPL applies.
44 */
45
46#define DRIVER_NAME "orinoco_usb"
47#define PFX DRIVER_NAME ": "
48
49#include <linux/module.h>
50#include <linux/kernel.h>
51#include <linux/sched.h>
52#include <linux/signal.h>
53#include <linux/errno.h>
54#include <linux/poll.h>
55#include <linux/init.h>
56#include <linux/slab.h>
57#include <linux/fcntl.h>
58#include <linux/spinlock.h>
59#include <linux/list.h>
60#include <linux/smp_lock.h>
61#include <linux/usb.h>
62#include <linux/timer.h>
63
64#include <linux/netdevice.h>
65#include <linux/if_arp.h>
66#include <linux/etherdevice.h>
67#include <linux/wireless.h>
68#include <linux/firmware.h>
69
70#include "mic.h"
71#include "orinoco.h"
72
73#ifndef URB_ASYNC_UNLINK
74#define URB_ASYNC_UNLINK 0
75#endif
76
77/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
78static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
79#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
80
81struct header_struct {
82 /* 802.3 */
83 u8 dest[ETH_ALEN];
84 u8 src[ETH_ALEN];
85 __be16 len;
86 /* 802.2 */
87 u8 dsap;
88 u8 ssap;
89 u8 ctrl;
90 /* SNAP */
91 u8 oui[3];
92 __be16 ethertype;
93} __attribute__ ((packed));
94
95struct ez_usb_fw {
96 u16 size;
97 const u8 *code;
98};
99
100static struct ez_usb_fw firmware = {
101 .size = 0,
102 .code = NULL,
103};
104
105#ifdef CONFIG_USB_DEBUG
106static int debug = 1;
107#else
108static int debug;
109#endif
110
111/* Debugging macros */
112#undef dbg
113#define dbg(format, arg...) \
114 do { if (debug) printk(KERN_DEBUG PFX "%s: " format "\n", \
115 __func__ , ## arg); } while (0)
116#undef err
117#define err(format, arg...) \
118 do { printk(KERN_ERR PFX format "\n", ## arg); } while (0)
119
120/* Module paramaters */
121module_param(debug, int, 0644);
122MODULE_PARM_DESC(debug, "Debug enabled or not");
123
124MODULE_FIRMWARE("orinoco_ezusb_fw");
125
126/*
127 * Under some conditions, the card gets stuck and stops paying attention
128 * to the world (i.e. data communication stalls) until we do something to
129 * it. Sending an INQ_TALLIES command seems to be enough and should be
130 * harmless otherwise. This behaviour has been observed when using the
131 * driver on a systemimager client during installation. In the past a
132 * timer was used to send INQ_TALLIES commands when there was no other
133 * activity, but it was troublesome and was removed.
134 */
135
136#define USB_COMPAQ_VENDOR_ID 0x049f /* Compaq Computer Corp. */
137#define USB_COMPAQ_WL215_ID 0x001f /* Compaq WL215 USB Adapter */
138#define USB_COMPAQ_W200_ID 0x0076 /* Compaq W200 USB Adapter */
139#define USB_HP_WL215_ID 0x0082 /* Compaq WL215 USB Adapter */
140
141#define USB_MELCO_VENDOR_ID 0x0411
142#define USB_BUFFALO_L11_ID 0x0006 /* BUFFALO WLI-USB-L11 */
143#define USB_BUFFALO_L11G_WR_ID 0x000B /* BUFFALO WLI-USB-L11G-WR */
144#define USB_BUFFALO_L11G_ID 0x000D /* BUFFALO WLI-USB-L11G */
145
146#define USB_LUCENT_VENDOR_ID 0x047E /* Lucent Technologies */
147#define USB_LUCENT_ORINOCO_ID 0x0300 /* Lucent/Agere Orinoco USB Client */
148
149#define USB_AVAYA8_VENDOR_ID 0x0D98
150#define USB_AVAYAE_VENDOR_ID 0x0D9E
151#define USB_AVAYA_WIRELESS_ID 0x0300 /* Avaya Wireless USB Card */
152
153#define USB_AGERE_VENDOR_ID 0x0D4E /* Agere Systems */
154#define USB_AGERE_MODEL0801_ID 0x1000 /* Wireless USB Card Model 0801 */
155#define USB_AGERE_MODEL0802_ID 0x1001 /* Wireless USB Card Model 0802 */
156#define USB_AGERE_REBRANDED_ID 0x047A /* WLAN USB Card */
157
158#define USB_ELSA_VENDOR_ID 0x05CC
159#define USB_ELSA_AIRLANCER_ID 0x3100 /* ELSA AirLancer USB-11 */
160
161#define USB_LEGEND_VENDOR_ID 0x0E7C
162#define USB_LEGEND_JOYNET_ID 0x0300 /* Joynet WLAN USB Card */
163
164#define USB_SAMSUNG_VENDOR_ID 0x04E8
165#define USB_SAMSUNG_SEW2001U1_ID 0x5002 /* Samsung SEW-2001u Card */
166#define USB_SAMSUNG_SEW2001U2_ID 0x5B11 /* Samsung SEW-2001u Card */
167#define USB_SAMSUNG_SEW2003U_ID 0x7011 /* Samsung SEW-2003U Card */
168
169#define USB_IGATE_VENDOR_ID 0x0681
170#define USB_IGATE_IGATE_11M_ID 0x0012 /* I-GATE 11M USB Card */
171
172#define USB_FUJITSU_VENDOR_ID 0x0BF8
173#define USB_FUJITSU_E1100_ID 0x1002 /* connect2AIR WLAN E-1100 USB */
174
175#define USB_2WIRE_VENDOR_ID 0x1630
176#define USB_2WIRE_WIRELESS_ID 0xff81 /* 2Wire Wireless USB adapter */
177
178
179#define EZUSB_REQUEST_FW_TRANS 0xA0
180#define EZUSB_REQUEST_TRIGER 0xAA
181#define EZUSB_REQUEST_TRIG_AC 0xAC
182#define EZUSB_CPUCS_REG 0x7F92
183
184#define EZUSB_RID_TX 0x0700
185#define EZUSB_RID_RX 0x0701
186#define EZUSB_RID_INIT1 0x0702
187#define EZUSB_RID_ACK 0x0710
188#define EZUSB_RID_READ_PDA 0x0800
189#define EZUSB_RID_PROG_INIT 0x0852
190#define EZUSB_RID_PROG_SET_ADDR 0x0853
191#define EZUSB_RID_PROG_BYTES 0x0854
192#define EZUSB_RID_PROG_END 0x0855
193#define EZUSB_RID_DOCMD 0x0860
194
195/* Recognize info frames */
196#define EZUSB_IS_INFO(id) ((id >= 0xF000) && (id <= 0xF2FF))
197
198#define EZUSB_MAGIC 0x0210
199
200#define EZUSB_FRAME_DATA 1
201#define EZUSB_FRAME_CONTROL 2
202
203#define DEF_TIMEOUT (3*HZ)
204
205#define BULK_BUF_SIZE 2048
206
207#define MAX_DL_SIZE (BULK_BUF_SIZE - sizeof(struct ezusb_packet))
208
209#define FW_BUF_SIZE 64
210#define FW_VAR_OFFSET_PTR 0x359
211#define FW_VAR_VALUE 0
212#define FW_HOLE_START 0x100
213#define FW_HOLE_END 0x300
214
215struct ezusb_packet {
216 __le16 magic; /* 0x0210 */
217 u8 req_reply_count;
218 u8 ans_reply_count;
219 __le16 frame_type; /* 0x01 for data frames, 0x02 otherwise */
220 __le16 size; /* transport size */
221 __le16 crc; /* CRC up to here */
222 __le16 hermes_len;
223 __le16 hermes_rid;
224 u8 data[0];
225} __attribute__ ((packed));
226
227/* Table of devices that work or may work with this driver */
228static struct usb_device_id ezusb_table[] = {
229 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_WL215_ID)},
230 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_HP_WL215_ID)},
231 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_W200_ID)},
232 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11_ID)},
233 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_WR_ID)},
234 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_ID)},
235 {USB_DEVICE(USB_LUCENT_VENDOR_ID, USB_LUCENT_ORINOCO_ID)},
236 {USB_DEVICE(USB_AVAYA8_VENDOR_ID, USB_AVAYA_WIRELESS_ID)},
237 {USB_DEVICE(USB_AVAYAE_VENDOR_ID, USB_AVAYA_WIRELESS_ID)},
238 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0801_ID)},
239 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0802_ID)},
240 {USB_DEVICE(USB_ELSA_VENDOR_ID, USB_ELSA_AIRLANCER_ID)},
241 {USB_DEVICE(USB_LEGEND_VENDOR_ID, USB_LEGEND_JOYNET_ID)},
242 {USB_DEVICE_VER(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U1_ID,
243 0, 0)},
244 {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U2_ID)},
245 {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2003U_ID)},
246 {USB_DEVICE(USB_IGATE_VENDOR_ID, USB_IGATE_IGATE_11M_ID)},
247 {USB_DEVICE(USB_FUJITSU_VENDOR_ID, USB_FUJITSU_E1100_ID)},
248 {USB_DEVICE(USB_2WIRE_VENDOR_ID, USB_2WIRE_WIRELESS_ID)},
249 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_REBRANDED_ID)},
250 {} /* Terminating entry */
251};
252
253MODULE_DEVICE_TABLE(usb, ezusb_table);
254
255/* Structure to hold all of our device specific stuff */
256struct ezusb_priv {
257 struct usb_device *udev;
258 struct net_device *dev;
259 struct mutex mtx;
260 spinlock_t req_lock;
261 struct list_head req_pending;
262 struct list_head req_active;
263 spinlock_t reply_count_lock;
264 u16 hermes_reg_fake[0x40];
265 u8 *bap_buf;
266 struct urb *read_urb;
267 int read_pipe;
268 int write_pipe;
269 u8 reply_count;
270};
271
272enum ezusb_state {
273 EZUSB_CTX_START,
274 EZUSB_CTX_QUEUED,
275 EZUSB_CTX_REQ_SUBMITTED,
276 EZUSB_CTX_REQ_COMPLETE,
277 EZUSB_CTX_RESP_RECEIVED,
278 EZUSB_CTX_REQ_TIMEOUT,
279 EZUSB_CTX_REQ_FAILED,
280 EZUSB_CTX_RESP_TIMEOUT,
281 EZUSB_CTX_REQSUBMIT_FAIL,
282 EZUSB_CTX_COMPLETE,
283};
284
285struct request_context {
286 struct list_head list;
287 atomic_t refcount;
288 struct completion done; /* Signals that CTX is dead */
289 int killed;
290 struct urb *outurb; /* OUT for req pkt */
291 struct ezusb_priv *upriv;
292 struct ezusb_packet *buf;
293 int buf_length;
294 struct timer_list timer; /* Timeout handling */
295 enum ezusb_state state; /* Current state */
296 /* the RID that we will wait for */
297 u16 out_rid;
298 u16 in_rid;
299};
300
301
302/* Forward declarations */
303static void ezusb_ctx_complete(struct request_context *ctx);
304static void ezusb_req_queue_run(struct ezusb_priv *upriv);
305static void ezusb_bulk_in_callback(struct urb *urb);
306
307static inline u8 ezusb_reply_inc(u8 count)
308{
309 if (count < 0x7F)
310 return count + 1;
311 else
312 return 1;
313}
314
315static void ezusb_request_context_put(struct request_context *ctx)
316{
317 if (!atomic_dec_and_test(&ctx->refcount))
318 return;
319
320 WARN_ON(!ctx->done.done);
321 BUG_ON(ctx->outurb->status == -EINPROGRESS);
322 BUG_ON(timer_pending(&ctx->timer));
323 usb_free_urb(ctx->outurb);
324 kfree(ctx->buf);
325 kfree(ctx);
326}
327
328static inline void ezusb_mod_timer(struct ezusb_priv *upriv,
329 struct timer_list *timer,
330 unsigned long expire)
331{
332 if (!upriv->udev)
333 return;
334 mod_timer(timer, expire);
335}
336
337static void ezusb_request_timerfn(u_long _ctx)
338{
339 struct request_context *ctx = (void *) _ctx;
340
341 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
342 if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) {
343 ctx->state = EZUSB_CTX_REQ_TIMEOUT;
344 } else {
345 ctx->state = EZUSB_CTX_RESP_TIMEOUT;
346 dbg("couldn't unlink");
347 atomic_inc(&ctx->refcount);
348 ctx->killed = 1;
349 ezusb_ctx_complete(ctx);
350 ezusb_request_context_put(ctx);
351 }
352};
353
354static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv,
355 u16 out_rid, u16 in_rid)
356{
357 struct request_context *ctx;
358
359 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
360 if (!ctx)
361 return NULL;
362
363 memset(ctx, 0, sizeof(*ctx));
364
365 ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC);
366 if (!ctx->buf) {
367 kfree(ctx);
368 return NULL;
369 }
370 ctx->outurb = usb_alloc_urb(0, GFP_ATOMIC);
371 if (!ctx->outurb) {
372 kfree(ctx->buf);
373 kfree(ctx);
374 return NULL;
375 }
376
377 ctx->upriv = upriv;
378 ctx->state = EZUSB_CTX_START;
379 ctx->out_rid = out_rid;
380 ctx->in_rid = in_rid;
381
382 atomic_set(&ctx->refcount, 1);
383 init_completion(&ctx->done);
384
385 init_timer(&ctx->timer);
386 ctx->timer.function = ezusb_request_timerfn;
387 ctx->timer.data = (u_long) ctx;
388 return ctx;
389}
390
391
392/* Hopefully the real complete_all will soon be exported, in the mean
393 * while this should work. */
394static inline void ezusb_complete_all(struct completion *comp)
395{
396 complete(comp);
397 complete(comp);
398 complete(comp);
399 complete(comp);
400}
401
402static void ezusb_ctx_complete(struct request_context *ctx)
403{
404 struct ezusb_priv *upriv = ctx->upriv;
405 unsigned long flags;
406
407 spin_lock_irqsave(&upriv->req_lock, flags);
408
409 list_del_init(&ctx->list);
410 if (upriv->udev) {
411 spin_unlock_irqrestore(&upriv->req_lock, flags);
412 ezusb_req_queue_run(upriv);
413 spin_lock_irqsave(&upriv->req_lock, flags);
414 }
415
416 switch (ctx->state) {
417 case EZUSB_CTX_COMPLETE:
418 case EZUSB_CTX_REQSUBMIT_FAIL:
419 case EZUSB_CTX_REQ_FAILED:
420 case EZUSB_CTX_REQ_TIMEOUT:
421 case EZUSB_CTX_RESP_TIMEOUT:
422 spin_unlock_irqrestore(&upriv->req_lock, flags);
423
424 if ((ctx->out_rid == EZUSB_RID_TX) && upriv->dev) {
425 struct net_device *dev = upriv->dev;
426 struct orinoco_private *priv = ndev_priv(dev);
427 struct net_device_stats *stats = &priv->stats;
428
429 if (ctx->state != EZUSB_CTX_COMPLETE)
430 stats->tx_errors++;
431 else
432 stats->tx_packets++;
433
434 netif_wake_queue(dev);
435 }
436 ezusb_complete_all(&ctx->done);
437 ezusb_request_context_put(ctx);
438 break;
439
440 default:
441 spin_unlock_irqrestore(&upriv->req_lock, flags);
442 if (!upriv->udev) {
443 /* This is normal, as all request contexts get flushed
444 * when the device is disconnected */
445 err("Called, CTX not terminating, but device gone");
446 ezusb_complete_all(&ctx->done);
447 ezusb_request_context_put(ctx);
448 break;
449 }
450
451 err("Called, CTX not in terminating state.");
452 /* Things are really bad if this happens. Just leak
453 * the CTX because it may still be linked to the
454 * queue or the OUT urb may still be active.
455 * Just leaking at least prevents an Oops or Panic.
456 */
457 break;
458 }
459}
460
461/**
462 * ezusb_req_queue_run:
463 * Description:
464 * Note: Only one active CTX at any one time, because there's no
465 * other (reliable) way to match the response URB to the correct
466 * CTX.
467 **/
468static void ezusb_req_queue_run(struct ezusb_priv *upriv)
469{
470 unsigned long flags;
471 struct request_context *ctx;
472 int result;
473
474 spin_lock_irqsave(&upriv->req_lock, flags);
475
476 if (!list_empty(&upriv->req_active))
477 goto unlock;
478
479 if (list_empty(&upriv->req_pending))
480 goto unlock;
481
482 ctx =
483 list_entry(upriv->req_pending.next, struct request_context,
484 list);
485
486 if (!ctx->upriv->udev)
487 goto unlock;
488
489 /* We need to split this off to avoid a race condition */
490 list_move_tail(&ctx->list, &upriv->req_active);
491
492 if (ctx->state == EZUSB_CTX_QUEUED) {
493 atomic_inc(&ctx->refcount);
494 result = usb_submit_urb(ctx->outurb, GFP_ATOMIC);
495 if (result) {
496 ctx->state = EZUSB_CTX_REQSUBMIT_FAIL;
497
498 spin_unlock_irqrestore(&upriv->req_lock, flags);
499
500 err("Fatal, failed to submit command urb."
501 " error=%d\n", result);
502
503 ezusb_ctx_complete(ctx);
504 ezusb_request_context_put(ctx);
505 goto done;
506 }
507
508 ctx->state = EZUSB_CTX_REQ_SUBMITTED;
509 ezusb_mod_timer(ctx->upriv, &ctx->timer,
510 jiffies + DEF_TIMEOUT);
511 }
512
513 unlock:
514 spin_unlock_irqrestore(&upriv->req_lock, flags);
515
516 done:
517 return;
518}
519
520static void ezusb_req_enqueue_run(struct ezusb_priv *upriv,
521 struct request_context *ctx)
522{
523 unsigned long flags;
524
525 spin_lock_irqsave(&upriv->req_lock, flags);
526
527 if (!ctx->upriv->udev) {
528 spin_unlock_irqrestore(&upriv->req_lock, flags);
529 goto done;
530 }
531 atomic_inc(&ctx->refcount);
532 list_add_tail(&ctx->list, &upriv->req_pending);
533 spin_unlock_irqrestore(&upriv->req_lock, flags);
534
535 ctx->state = EZUSB_CTX_QUEUED;
536 ezusb_req_queue_run(upriv);
537
538 done:
539 return;
540}
541
542static void ezusb_request_out_callback(struct urb *urb)
543{
544 unsigned long flags;
545 enum ezusb_state state;
546 struct request_context *ctx = urb->context;
547 struct ezusb_priv *upriv = ctx->upriv;
548
549 spin_lock_irqsave(&upriv->req_lock, flags);
550
551 del_timer(&ctx->timer);
552
553 if (ctx->killed) {
554 spin_unlock_irqrestore(&upriv->req_lock, flags);
555 pr_warning("interrupt called with dead ctx");
556 goto out;
557 }
558
559 state = ctx->state;
560
561 if (urb->status == 0) {
562 switch (state) {
563 case EZUSB_CTX_REQ_SUBMITTED:
564 if (ctx->in_rid) {
565 ctx->state = EZUSB_CTX_REQ_COMPLETE;
566 /* reply URB still pending */
567 ezusb_mod_timer(upriv, &ctx->timer,
568 jiffies + DEF_TIMEOUT);
569 spin_unlock_irqrestore(&upriv->req_lock,
570 flags);
571 break;
572 }
573 /* fall through */
574 case EZUSB_CTX_RESP_RECEIVED:
575 /* IN already received before this OUT-ACK */
576 ctx->state = EZUSB_CTX_COMPLETE;
577 spin_unlock_irqrestore(&upriv->req_lock, flags);
578 ezusb_ctx_complete(ctx);
579 break;
580
581 default:
582 spin_unlock_irqrestore(&upriv->req_lock, flags);
583 err("Unexpected state(0x%x, %d) in OUT URB",
584 state, urb->status);
585 break;
586 }
587 } else {
588 /* If someone cancels the OUT URB then its status
589 * should be either -ECONNRESET or -ENOENT.
590 */
591 switch (state) {
592 case EZUSB_CTX_REQ_SUBMITTED:
593 case EZUSB_CTX_RESP_RECEIVED:
594 ctx->state = EZUSB_CTX_REQ_FAILED;
595 /* fall through */
596
597 case EZUSB_CTX_REQ_FAILED:
598 case EZUSB_CTX_REQ_TIMEOUT:
599 spin_unlock_irqrestore(&upriv->req_lock, flags);
600
601 ezusb_ctx_complete(ctx);
602 break;
603
604 default:
605 spin_unlock_irqrestore(&upriv->req_lock, flags);
606
607 err("Unexpected state(0x%x, %d) in OUT URB",
608 state, urb->status);
609 break;
610 }
611 }
612 out:
613 ezusb_request_context_put(ctx);
614}
615
616static void ezusb_request_in_callback(struct ezusb_priv *upriv,
617 struct urb *urb)
618{
619 struct ezusb_packet *ans = urb->transfer_buffer;
620 struct request_context *ctx = NULL;
621 enum ezusb_state state;
622 unsigned long flags;
623
624 /* Find the CTX on the active queue that requested this URB */
625 spin_lock_irqsave(&upriv->req_lock, flags);
626 if (upriv->udev) {
627 struct list_head *item;
628
629 list_for_each(item, &upriv->req_active) {
630 struct request_context *c;
631 int reply_count;
632
633 c = list_entry(item, struct request_context, list);
634 reply_count =
635 ezusb_reply_inc(c->buf->req_reply_count);
636 if ((ans->ans_reply_count == reply_count)
637 && (le16_to_cpu(ans->hermes_rid) == c->in_rid)) {
638 ctx = c;
639 break;
640 }
641 dbg("Skipped (0x%x/0x%x) (%d/%d)",
642 le16_to_cpu(ans->hermes_rid),
643 c->in_rid, ans->ans_reply_count, reply_count);
644 }
645 }
646
647 if (ctx == NULL) {
648 spin_unlock_irqrestore(&upriv->req_lock, flags);
649 err("%s: got unexpected RID: 0x%04X", __func__,
650 le16_to_cpu(ans->hermes_rid));
651 ezusb_req_queue_run(upriv);
652 return;
653 }
654
655 /* The data we want is in the in buffer, exchange */
656 urb->transfer_buffer = ctx->buf;
657 ctx->buf = (void *) ans;
658 ctx->buf_length = urb->actual_length;
659
660 state = ctx->state;
661 switch (state) {
662 case EZUSB_CTX_REQ_SUBMITTED:
663 /* We have received our response URB before
664 * our request has been acknowledged. Do NOT
665 * destroy our CTX yet, because our OUT URB
666 * is still alive ...
667 */
668 ctx->state = EZUSB_CTX_RESP_RECEIVED;
669 spin_unlock_irqrestore(&upriv->req_lock, flags);
670
671 /* Let the machine continue running. */
672 break;
673
674 case EZUSB_CTX_REQ_COMPLETE:
675 /* This is the usual path: our request
676 * has already been acknowledged, and
677 * we have now received the reply.
678 */
679 ctx->state = EZUSB_CTX_COMPLETE;
680
681 /* Stop the intimer */
682 del_timer(&ctx->timer);
683 spin_unlock_irqrestore(&upriv->req_lock, flags);
684
685 /* Call the completion handler */
686 ezusb_ctx_complete(ctx);
687 break;
688
689 default:
690 spin_unlock_irqrestore(&upriv->req_lock, flags);
691
692 pr_warning("Matched IN URB, unexpected context state(0x%x)",
693 state);
694 /* Throw this CTX away and try submitting another */
695 del_timer(&ctx->timer);
696 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
697 usb_unlink_urb(ctx->outurb);
698 ezusb_req_queue_run(upriv);
699 break;
700 } /* switch */
701}
702
703
704static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,
705 struct request_context *ctx)
706{
707 switch (ctx->state) {
708 case EZUSB_CTX_QUEUED:
709 case EZUSB_CTX_REQ_SUBMITTED:
710 case EZUSB_CTX_REQ_COMPLETE:
711 case EZUSB_CTX_RESP_RECEIVED:
712 if (in_softirq()) {
713 /* If we get called from a timer, timeout timers don't
714 * get the chance to run themselves. So we make sure
715 * that we don't sleep for ever */
716 int msecs = DEF_TIMEOUT * (1000 / HZ);
717 while (!ctx->done.done && msecs--)
718 udelay(1000);
719 } else {
720 wait_event_interruptible(ctx->done.wait,
721 ctx->done.done);
722 }
723 break;
724 default:
725 /* Done or failed - nothing to wait for */
726 break;
727 }
728}
729
730static inline u16 build_crc(struct ezusb_packet *data)
731{
732 u16 crc = 0;
733 u8 *bytes = (u8 *)data;
734 int i;
735
736 for (i = 0; i < 8; i++)
737 crc = (crc << 1) + bytes[i];
738
739 return crc;
740}
741
742/**
743 * ezusb_fill_req:
744 *
745 * if data == NULL and length > 0 the data is assumed to be already in
746 * the target buffer and only the header is filled.
747 *
748 */
749static int ezusb_fill_req(struct ezusb_packet *req, u16 length, u16 rid,
750 const void *data, u16 frame_type, u8 reply_count)
751{
752 int total_size = sizeof(*req) + length;
753
754 BUG_ON(total_size > BULK_BUF_SIZE);
755
756 req->magic = cpu_to_le16(EZUSB_MAGIC);
757 req->req_reply_count = reply_count;
758 req->ans_reply_count = 0;
759 req->frame_type = cpu_to_le16(frame_type);
760 req->size = cpu_to_le16(length + 4);
761 req->crc = cpu_to_le16(build_crc(req));
762 req->hermes_len = cpu_to_le16(HERMES_BYTES_TO_RECLEN(length));
763 req->hermes_rid = cpu_to_le16(rid);
764 if (data)
765 memcpy(req->data, data, length);
766 return total_size;
767}
768
769static int ezusb_submit_in_urb(struct ezusb_priv *upriv)
770{
771 int retval = 0;
772 void *cur_buf = upriv->read_urb->transfer_buffer;
773
774 if (upriv->read_urb->status == -EINPROGRESS) {
775 dbg("urb busy, not resubmiting");
776 retval = -EBUSY;
777 goto exit;
778 }
779 usb_fill_bulk_urb(upriv->read_urb, upriv->udev, upriv->read_pipe,
780 cur_buf, BULK_BUF_SIZE,
781 ezusb_bulk_in_callback, upriv);
782 upriv->read_urb->transfer_flags = 0;
783 retval = usb_submit_urb(upriv->read_urb, GFP_ATOMIC);
784 if (retval)
785 err("%s submit failed %d", __func__, retval);
786
787 exit:
788 return retval;
789}
790
791static inline int ezusb_8051_cpucs(struct ezusb_priv *upriv, int reset)
792{
793 u8 res_val = reset; /* avoid argument promotion */
794
795 if (!upriv->udev) {
796 err("%s: !upriv->udev", __func__);
797 return -EFAULT;
798 }
799 return usb_control_msg(upriv->udev,
800 usb_sndctrlpipe(upriv->udev, 0),
801 EZUSB_REQUEST_FW_TRANS,
802 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
803 USB_DIR_OUT, EZUSB_CPUCS_REG, 0, &res_val,
804 sizeof(res_val), DEF_TIMEOUT);
805}
806
807static int ezusb_firmware_download(struct ezusb_priv *upriv,
808 struct ez_usb_fw *fw)
809{
810 u8 fw_buffer[FW_BUF_SIZE];
811 int retval, addr;
812 int variant_offset;
813
814 /*
815 * This byte is 1 and should be replaced with 0. The offset is
816 * 0x10AD in version 0.0.6. The byte in question should follow
817 * the end of the code pointed to by the jump in the beginning
818 * of the firmware. Also, it is read by code located at 0x358.
819 */
820 variant_offset = be16_to_cpup((__be16 *) &fw->code[FW_VAR_OFFSET_PTR]);
821 if (variant_offset >= fw->size) {
822 printk(KERN_ERR PFX "Invalid firmware variant offset: "
823 "0x%04x\n", variant_offset);
824 retval = -EINVAL;
825 goto fail;
826 }
827
828 retval = ezusb_8051_cpucs(upriv, 1);
829 if (retval < 0)
830 goto fail;
831 for (addr = 0; addr < fw->size; addr += FW_BUF_SIZE) {
832 /* 0x100-0x300 should be left alone, it contains card
833 * specific data, like USB enumeration information */
834 if ((addr >= FW_HOLE_START) && (addr < FW_HOLE_END))
835 continue;
836
837 memcpy(fw_buffer, &fw->code[addr], FW_BUF_SIZE);
838 if (variant_offset >= addr &&
839 variant_offset < addr + FW_BUF_SIZE) {
840 dbg("Patching card_variant byte at 0x%04X",
841 variant_offset);
842 fw_buffer[variant_offset - addr] = FW_VAR_VALUE;
843 }
844 retval = usb_control_msg(upriv->udev,
845 usb_sndctrlpipe(upriv->udev, 0),
846 EZUSB_REQUEST_FW_TRANS,
847 USB_TYPE_VENDOR | USB_RECIP_DEVICE
848 | USB_DIR_OUT,
849 addr, 0x0,
850 fw_buffer, FW_BUF_SIZE,
851 DEF_TIMEOUT);
852
853 if (retval < 0)
854 goto fail;
855 }
856 retval = ezusb_8051_cpucs(upriv, 0);
857 if (retval < 0)
858 goto fail;
859
860 goto exit;
861 fail:
862 printk(KERN_ERR PFX "Firmware download failed, error %d\n",
863 retval);
864 exit:
865 return retval;
866}
867
868static int ezusb_access_ltv(struct ezusb_priv *upriv,
869 struct request_context *ctx,
870 u16 length, const void *data, u16 frame_type,
871 void *ans_buff, int ans_size, u16 *ans_length)
872{
873 int req_size;
874 int retval = 0;
875 enum ezusb_state state;
876
877 BUG_ON(in_irq());
878
879 if (!upriv->udev) {
880 dbg("Device disconnected");
881 return -ENODEV;
882 }
883
884 if (upriv->read_urb->status != -EINPROGRESS)
885 err("%s: in urb not pending", __func__);
886
887 /* protect upriv->reply_count, guarantee sequential numbers */
888 spin_lock_bh(&upriv->reply_count_lock);
889 req_size = ezusb_fill_req(ctx->buf, length, ctx->out_rid, data,
890 frame_type, upriv->reply_count);
891 usb_fill_bulk_urb(ctx->outurb, upriv->udev, upriv->write_pipe,
892 ctx->buf, req_size,
893 ezusb_request_out_callback, ctx);
894
895 if (ctx->in_rid)
896 upriv->reply_count = ezusb_reply_inc(upriv->reply_count);
897
898 ezusb_req_enqueue_run(upriv, ctx);
899
900 spin_unlock_bh(&upriv->reply_count_lock);
901
902 if (ctx->in_rid)
903 ezusb_req_ctx_wait(upriv, ctx);
904
905 state = ctx->state;
906 switch (state) {
907 case EZUSB_CTX_COMPLETE:
908 retval = ctx->outurb->status;
909 break;
910
911 case EZUSB_CTX_QUEUED:
912 case EZUSB_CTX_REQ_SUBMITTED:
913 if (!ctx->in_rid)
914 break;
915 default:
916 err("%s: Unexpected context state %d", __func__,
917 state);
918 /* fall though */
919 case EZUSB_CTX_REQ_TIMEOUT:
920 case EZUSB_CTX_REQ_FAILED:
921 case EZUSB_CTX_RESP_TIMEOUT:
922 case EZUSB_CTX_REQSUBMIT_FAIL:
923 printk(KERN_ERR PFX "Access failed, resetting (state %d,"
924 " reply_count %d)\n", state, upriv->reply_count);
925 upriv->reply_count = 0;
926 if (state == EZUSB_CTX_REQ_TIMEOUT
927 || state == EZUSB_CTX_RESP_TIMEOUT) {
928 printk(KERN_ERR PFX "ctx timed out\n");
929 retval = -ETIMEDOUT;
930 } else {
931 printk(KERN_ERR PFX "ctx failed\n");
932 retval = -EFAULT;
933 }
934 goto exit;
935 break;
936 }
937 if (ctx->in_rid) {
938 struct ezusb_packet *ans = ctx->buf;
939 int exp_len;
940
941 if (ans->hermes_len != 0)
942 exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12;
943 else
944 exp_len = 14;
945
946 if (exp_len != ctx->buf_length) {
947 err("%s: length mismatch for RID 0x%04x: "
948 "expected %d, got %d", __func__,
949 ctx->in_rid, exp_len, ctx->buf_length);
950 retval = -EIO;
951 goto exit;
952 }
953
954 if (ans_buff)
955 memcpy(ans_buff, ans->data,
956 min_t(int, exp_len, ans_size));
957 if (ans_length)
958 *ans_length = le16_to_cpu(ans->hermes_len);
959 }
960 exit:
961 ezusb_request_context_put(ctx);
962 return retval;
963}
964
965static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid,
966 u16 length, const void *data)
967{
968 struct ezusb_priv *upriv = hw->priv;
969 u16 frame_type;
970 struct request_context *ctx;
971
972 if (length == 0)
973 return -EINVAL;
974
975 length = HERMES_RECLEN_TO_BYTES(length);
976
977 /* On memory mapped devices HERMES_RID_CNFGROUPADDRESSES can be
978 * set to be empty, but the USB bridge doesn't like it */
979 if (length == 0)
980 return 0;
981
982 ctx = ezusb_alloc_ctx(upriv, rid, EZUSB_RID_ACK);
983 if (!ctx)
984 return -ENOMEM;
985
986 if (rid == EZUSB_RID_TX)
987 frame_type = EZUSB_FRAME_DATA;
988 else
989 frame_type = EZUSB_FRAME_CONTROL;
990
991 return ezusb_access_ltv(upriv, ctx, length, data, frame_type,
992 NULL, 0, NULL);
993}
994
995static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid,
996 unsigned bufsize, u16 *length, void *buf)
997{
998 struct ezusb_priv *upriv = hw->priv;
999 struct request_context *ctx;
1000
1001 if ((bufsize < 0) || (bufsize % 2))
1002 return -EINVAL;
1003
1004 ctx = ezusb_alloc_ctx(upriv, rid, rid);
1005 if (!ctx)
1006 return -ENOMEM;
1007
1008 return ezusb_access_ltv(upriv, ctx, 0, NULL, EZUSB_FRAME_CONTROL,
1009 buf, bufsize, length);
1010}
1011
1012static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1,
1013 u16 parm2, struct hermes_response *resp)
1014{
1015 struct ezusb_priv *upriv = hw->priv;
1016 struct request_context *ctx;
1017
1018 __le16 data[4] = {
1019 cpu_to_le16(cmd),
1020 cpu_to_le16(parm0),
1021 cpu_to_le16(parm1),
1022 cpu_to_le16(parm2),
1023 };
1024 dbg("0x%04X, parm0 0x%04X, parm1 0x%04X, parm2 0x%04X",
1025 cmd, parm0, parm1, parm2);
1026 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK);
1027 if (!ctx)
1028 return -ENOMEM;
1029
1030 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1031 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1032}
1033
1034static int ezusb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
1035 struct hermes_response *resp)
1036{
1037 struct ezusb_priv *upriv = hw->priv;
1038 struct request_context *ctx;
1039
1040 __le16 data[4] = {
1041 cpu_to_le16(cmd),
1042 cpu_to_le16(parm0),
1043 0,
1044 0,
1045 };
1046 dbg("0x%04X, parm0 0x%04X", cmd, parm0);
1047 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK);
1048 if (!ctx)
1049 return -ENOMEM;
1050
1051 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1052 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1053}
1054
1055static int ezusb_bap_pread(struct hermes *hw, int bap,
1056 void *buf, int len, u16 id, u16 offset)
1057{
1058 struct ezusb_priv *upriv = hw->priv;
1059 struct ezusb_packet *ans = (void *) upriv->read_urb->transfer_buffer;
1060 int actual_length = upriv->read_urb->actual_length;
1061
1062 if (id == EZUSB_RID_RX) {
1063 if ((sizeof(*ans) + offset + len) > actual_length) {
1064 printk(KERN_ERR PFX "BAP read beyond buffer end "
1065 "in rx frame\n");
1066 return -EINVAL;
1067 }
1068 memcpy(buf, ans->data + offset, len);
1069 return 0;
1070 }
1071
1072 if (EZUSB_IS_INFO(id)) {
1073 /* Include 4 bytes for length/type */
1074 if ((sizeof(*ans) + offset + len - 4) > actual_length) {
1075 printk(KERN_ERR PFX "BAP read beyond buffer end "
1076 "in info frame\n");
1077 return -EFAULT;
1078 }
1079 memcpy(buf, ans->data + offset - 4, len);
1080 } else {
1081 printk(KERN_ERR PFX "Unexpected fid 0x%04x\n", id);
1082 return -EINVAL;
1083 }
1084
1085 return 0;
1086}
1087
1088static int ezusb_read_pda(struct hermes *hw, __le16 *pda,
1089 u32 pda_addr, u16 pda_len)
1090{
1091 struct ezusb_priv *upriv = hw->priv;
1092 struct request_context *ctx;
1093 __le16 data[] = {
1094 cpu_to_le16(pda_addr & 0xffff),
1095 cpu_to_le16(pda_len - 4)
1096 };
1097 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_READ_PDA, EZUSB_RID_READ_PDA);
1098 if (!ctx)
1099 return -ENOMEM;
1100
1101 /* wl_lkm does not include PDA size in the PDA area.
1102 * We will pad the information into pda, so other routines
1103 * don't have to be modified */
1104 pda[0] = cpu_to_le16(pda_len - 2);
1105 /* Includes CFG_PROD_DATA but not itself */
1106 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
1107
1108 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1109 EZUSB_FRAME_CONTROL, &pda[2], pda_len - 4,
1110 NULL);
1111}
1112
1113static int ezusb_program_init(struct hermes *hw, u32 entry_point)
1114{
1115 struct ezusb_priv *upriv = hw->priv;
1116 struct request_context *ctx;
1117 __le32 data = cpu_to_le32(entry_point);
1118
1119 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_INIT, EZUSB_RID_ACK);
1120 if (!ctx)
1121 return -ENOMEM;
1122
1123 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1124 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1125}
1126
1127static int ezusb_program_end(struct hermes *hw)
1128{
1129 struct ezusb_priv *upriv = hw->priv;
1130 struct request_context *ctx;
1131
1132 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_END, EZUSB_RID_ACK);
1133 if (!ctx)
1134 return -ENOMEM;
1135
1136 return ezusb_access_ltv(upriv, ctx, 0, NULL,
1137 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1138}
1139
1140static int ezusb_program_bytes(struct hermes *hw, const char *buf,
1141 u32 addr, u32 len)
1142{
1143 struct ezusb_priv *upriv = hw->priv;
1144 struct request_context *ctx;
1145 __le32 data = cpu_to_le32(addr);
1146 int err;
1147
1148 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_SET_ADDR, EZUSB_RID_ACK);
1149 if (!ctx)
1150 return -ENOMEM;
1151
1152 err = ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1153 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1154 if (err)
1155 return err;
1156
1157 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_BYTES, EZUSB_RID_ACK);
1158 if (!ctx)
1159 return -ENOMEM;
1160
1161 return ezusb_access_ltv(upriv, ctx, len, buf,
1162 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1163}
1164
1165static int ezusb_program(struct hermes *hw, const char *buf,
1166 u32 addr, u32 len)
1167{
1168 u32 ch_addr;
1169 u32 ch_len;
1170 int err = 0;
1171
1172 /* We can only send 2048 bytes out of the bulk xmit at a time,
1173 * so we have to split any programming into chunks of <2048
1174 * bytes. */
1175
1176 ch_len = (len < MAX_DL_SIZE) ? len : MAX_DL_SIZE;
1177 ch_addr = addr;
1178
1179 while (ch_addr < (addr + len)) {
1180 pr_debug("Programming subblock of length %d "
1181 "to address 0x%08x. Data @ %p\n",
1182 ch_len, ch_addr, &buf[ch_addr - addr]);
1183
1184 err = ezusb_program_bytes(hw, &buf[ch_addr - addr],
1185 ch_addr, ch_len);
1186 if (err)
1187 break;
1188
1189 ch_addr += ch_len;
1190 ch_len = ((addr + len - ch_addr) < MAX_DL_SIZE) ?
1191 (addr + len - ch_addr) : MAX_DL_SIZE;
1192 }
1193
1194 return err;
1195}
1196
1197static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
1198{
1199 struct orinoco_private *priv = ndev_priv(dev);
1200 struct net_device_stats *stats = &priv->stats;
1201 struct ezusb_priv *upriv = priv->card;
1202 u8 mic[MICHAEL_MIC_LEN+1];
1203 int err = 0;
1204 int tx_control;
1205 unsigned long flags;
1206 struct request_context *ctx;
1207 u8 *buf;
1208 int tx_size;
1209
1210 if (!netif_running(dev)) {
1211 printk(KERN_ERR "%s: Tx on stopped device!\n",
1212 dev->name);
1213 return NETDEV_TX_BUSY;
1214 }
1215
1216 if (netif_queue_stopped(dev)) {
1217 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
1218 dev->name);
1219 return NETDEV_TX_BUSY;
1220 }
1221
1222 if (orinoco_lock(priv, &flags) != 0) {
1223 printk(KERN_ERR
1224 "%s: ezusb_xmit() called while hw_unavailable\n",
1225 dev->name);
1226 return NETDEV_TX_BUSY;
1227 }
1228
1229 if (!netif_carrier_ok(dev) ||
1230 (priv->iw_mode == NL80211_IFTYPE_MONITOR)) {
1231 /* Oops, the firmware hasn't established a connection,
1232 silently drop the packet (this seems to be the
1233 safest approach). */
1234 goto drop;
1235 }
1236
1237 /* Check packet length */
1238 if (skb->len < ETH_HLEN)
1239 goto drop;
1240
1241 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0);
1242 if (!ctx)
1243 goto busy;
1244
1245 memset(ctx->buf, 0, BULK_BUF_SIZE);
1246 buf = ctx->buf->data;
1247
1248 tx_control = 0;
1249
1250 err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
1251 &mic[0]);
1252 if (err)
1253 goto drop;
1254
1255 {
1256 __le16 *tx_cntl = (__le16 *)buf;
1257 *tx_cntl = cpu_to_le16(tx_control);
1258 buf += sizeof(*tx_cntl);
1259 }
1260
1261 memcpy(buf, skb->data, skb->len);
1262 buf += skb->len;
1263
1264 if (tx_control & HERMES_TXCTRL_MIC) {
1265 u8 *m = mic;
1266 /* Mic has been offset so it can be copied to an even
1267 * address. We're copying eveything anyway, so we
1268 * don't need to copy that first byte. */
1269 if (skb->len % 2)
1270 m++;
1271 memcpy(buf, m, MICHAEL_MIC_LEN);
1272 buf += MICHAEL_MIC_LEN;
1273 }
1274
1275 /* Finally, we actually initiate the send */
1276 netif_stop_queue(dev);
1277
1278 /* The card may behave better if we send evenly sized usb transfers */
1279 tx_size = ALIGN(buf - ctx->buf->data, 2);
1280
1281 err = ezusb_access_ltv(upriv, ctx, tx_size, NULL,
1282 EZUSB_FRAME_DATA, NULL, 0, NULL);
1283
1284 if (err) {
1285 netif_start_queue(dev);
1286 if (net_ratelimit())
1287 printk(KERN_ERR "%s: Error %d transmitting packet\n",
1288 dev->name, err);
1289 goto busy;
1290 }
1291
1292 dev->trans_start = jiffies;
1293 stats->tx_bytes += skb->len;
1294 goto ok;
1295
1296 drop:
1297 stats->tx_errors++;
1298 stats->tx_dropped++;
1299
1300 ok:
1301 orinoco_unlock(priv, &flags);
1302 dev_kfree_skb(skb);
1303 return NETDEV_TX_OK;
1304
1305 busy:
1306 orinoco_unlock(priv, &flags);
1307 return NETDEV_TX_BUSY;
1308}
1309
1310static int ezusb_allocate(struct hermes *hw, u16 size, u16 *fid)
1311{
1312 *fid = EZUSB_RID_TX;
1313 return 0;
1314}
1315
1316
1317static int ezusb_hard_reset(struct orinoco_private *priv)
1318{
1319 struct ezusb_priv *upriv = priv->card;
1320 int retval = ezusb_8051_cpucs(upriv, 1);
1321
1322 if (retval < 0) {
1323 err("Failed to reset");
1324 return retval;
1325 }
1326
1327 retval = ezusb_8051_cpucs(upriv, 0);
1328 if (retval < 0) {
1329 err("Failed to unreset");
1330 return retval;
1331 }
1332
1333 dbg("sending control message");
1334 retval = usb_control_msg(upriv->udev,
1335 usb_sndctrlpipe(upriv->udev, 0),
1336 EZUSB_REQUEST_TRIGER,
1337 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1338 USB_DIR_OUT, 0x0, 0x0, NULL, 0,
1339 DEF_TIMEOUT);
1340 if (retval < 0) {
1341 err("EZUSB_REQUEST_TRIGER failed retval %d", retval);
1342 return retval;
1343 }
1344#if 0
1345 dbg("Sending EZUSB_REQUEST_TRIG_AC");
1346 retval = usb_control_msg(upriv->udev,
1347 usb_sndctrlpipe(upriv->udev, 0),
1348 EZUSB_REQUEST_TRIG_AC,
1349 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1350 USB_DIR_OUT, 0x00FA, 0x0, NULL, 0,
1351 DEF_TIMEOUT);
1352 if (retval < 0) {
1353 err("EZUSB_REQUEST_TRIG_AC failed retval %d", retval);
1354 return retval;
1355 }
1356#endif
1357
1358 return 0;
1359}
1360
1361
1362static int ezusb_init(hermes_t *hw)
1363{
1364 struct ezusb_priv *upriv = hw->priv;
1365 int retval;
1366
1367 BUG_ON(in_interrupt());
1368 BUG_ON(!upriv);
1369
1370 upriv->reply_count = 0;
1371 /* Write the MAGIC number on the simulated registers to keep
1372 * orinoco.c happy */
1373 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
1374 hermes_write_regn(hw, RXFID, EZUSB_RID_RX);
1375
1376 usb_kill_urb(upriv->read_urb);
1377 ezusb_submit_in_urb(upriv);
1378
1379 retval = ezusb_write_ltv(hw, 0, EZUSB_RID_INIT1,
1380 HERMES_BYTES_TO_RECLEN(2), "\x10\x00");
1381 if (retval < 0) {
1382 printk(KERN_ERR PFX "EZUSB_RID_INIT1 error %d\n", retval);
1383 return retval;
1384 }
1385
1386 retval = ezusb_docmd_wait(hw, HERMES_CMD_INIT, 0, NULL);
1387 if (retval < 0) {
1388 printk(KERN_ERR PFX "HERMES_CMD_INIT error %d\n", retval);
1389 return retval;
1390 }
1391
1392 return 0;
1393}
1394
1395static void ezusb_bulk_in_callback(struct urb *urb)
1396{
1397 struct ezusb_priv *upriv = (struct ezusb_priv *) urb->context;
1398 struct ezusb_packet *ans = urb->transfer_buffer;
1399 u16 crc;
1400 u16 hermes_rid;
1401
1402 if (upriv->udev == NULL) {
1403 dbg("disconnected");
1404 return;
1405 }
1406
1407 if (urb->status == -ETIMEDOUT) {
1408 /* When a device gets unplugged we get this every time
1409 * we resubmit, flooding the logs. Since we don't use
1410 * USB timeouts, it shouldn't happen any other time*/
1411 pr_warning("%s: urb timed out, not resubmiting", __func__);
1412 return;
1413 }
1414 if (urb->status == -ECONNABORTED) {
1415 pr_warning("%s: connection abort, resubmiting urb",
1416 __func__);
1417 goto resubmit;
1418 }
1419 if ((urb->status == -EILSEQ)
1420 || (urb->status == -ENOENT)
1421 || (urb->status == -ECONNRESET)) {
1422 dbg("status %d, not resubmiting", urb->status);
1423 return;
1424 }
1425 if (urb->status)
1426 dbg("status: %d length: %d",
1427 urb->status, urb->actual_length);
1428 if (urb->actual_length < sizeof(*ans)) {
1429 err("%s: short read, ignoring", __func__);
1430 goto resubmit;
1431 }
1432 crc = build_crc(ans);
1433 if (le16_to_cpu(ans->crc) != crc) {
1434 err("CRC error, ignoring packet");
1435 goto resubmit;
1436 }
1437
1438 hermes_rid = le16_to_cpu(ans->hermes_rid);
1439 if ((hermes_rid != EZUSB_RID_RX) && !EZUSB_IS_INFO(hermes_rid)) {
1440 ezusb_request_in_callback(upriv, urb);
1441 } else if (upriv->dev) {
1442 struct net_device *dev = upriv->dev;
1443 struct orinoco_private *priv = ndev_priv(dev);
1444 hermes_t *hw = &priv->hw;
1445
1446 if (hermes_rid == EZUSB_RID_RX) {
1447 __orinoco_ev_rx(dev, hw);
1448 } else {
1449 hermes_write_regn(hw, INFOFID,
1450 le16_to_cpu(ans->hermes_rid));
1451 __orinoco_ev_info(dev, hw);
1452 }
1453 }
1454
1455 resubmit:
1456 if (upriv->udev)
1457 ezusb_submit_in_urb(upriv);
1458}
1459
1460static inline void ezusb_delete(struct ezusb_priv *upriv)
1461{
1462 struct net_device *dev;
1463 struct list_head *item;
1464 struct list_head *tmp_item;
1465 unsigned long flags;
1466
1467 BUG_ON(in_interrupt());
1468 BUG_ON(!upriv);
1469
1470 dev = upriv->dev;
1471 mutex_lock(&upriv->mtx);
1472
1473 upriv->udev = NULL; /* No timer will be rearmed from here */
1474
1475 usb_kill_urb(upriv->read_urb);
1476
1477 spin_lock_irqsave(&upriv->req_lock, flags);
1478 list_for_each_safe(item, tmp_item, &upriv->req_active) {
1479 struct request_context *ctx;
1480 int err;
1481
1482 ctx = list_entry(item, struct request_context, list);
1483 atomic_inc(&ctx->refcount);
1484
1485 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
1486 err = usb_unlink_urb(ctx->outurb);
1487
1488 spin_unlock_irqrestore(&upriv->req_lock, flags);
1489 if (err == -EINPROGRESS)
1490 wait_for_completion(&ctx->done);
1491
1492 del_timer_sync(&ctx->timer);
1493 /* FIXME: there is an slight chance for the irq handler to
1494 * be running */
1495 if (!list_empty(&ctx->list))
1496 ezusb_ctx_complete(ctx);
1497
1498 ezusb_request_context_put(ctx);
1499 spin_lock_irqsave(&upriv->req_lock, flags);
1500 }
1501 spin_unlock_irqrestore(&upriv->req_lock, flags);
1502
1503 list_for_each_safe(item, tmp_item, &upriv->req_pending)
1504 ezusb_ctx_complete(list_entry(item,
1505 struct request_context, list));
1506
1507 if (upriv->read_urb->status == -EINPROGRESS)
1508 printk(KERN_ERR PFX "Some URB in progress\n");
1509
1510 mutex_unlock(&upriv->mtx);
1511
1512 kfree(upriv->read_urb->transfer_buffer);
1513 if (upriv->bap_buf != NULL)
1514 kfree(upriv->bap_buf);
1515 if (upriv->read_urb != NULL)
1516 usb_free_urb(upriv->read_urb);
1517 if (upriv->dev) {
1518 struct orinoco_private *priv = ndev_priv(upriv->dev);
1519 orinoco_if_del(priv);
1520 free_orinocodev(priv);
1521 }
1522}
1523
1524static void ezusb_lock_irqsave(spinlock_t *lock,
1525 unsigned long *flags) __acquires(lock)
1526{
1527 spin_lock_bh(lock);
1528}
1529
1530static void ezusb_unlock_irqrestore(spinlock_t *lock,
1531 unsigned long *flags) __releases(lock)
1532{
1533 spin_unlock_bh(lock);
1534}
1535
1536static void ezusb_lock_irq(spinlock_t *lock) __acquires(lock)
1537{
1538 spin_lock_bh(lock);
1539}
1540
1541static void ezusb_unlock_irq(spinlock_t *lock) __releases(lock)
1542{
1543 spin_unlock_bh(lock);
1544}
1545
1546static const struct hermes_ops ezusb_ops = {
1547 .init = ezusb_init,
1548 .cmd_wait = ezusb_docmd_wait,
1549 .init_cmd_wait = ezusb_doicmd_wait,
1550 .allocate = ezusb_allocate,
1551 .read_ltv = ezusb_read_ltv,
1552 .write_ltv = ezusb_write_ltv,
1553 .bap_pread = ezusb_bap_pread,
1554 .read_pda = ezusb_read_pda,
1555 .program_init = ezusb_program_init,
1556 .program_end = ezusb_program_end,
1557 .program = ezusb_program,
1558 .lock_irqsave = ezusb_lock_irqsave,
1559 .unlock_irqrestore = ezusb_unlock_irqrestore,
1560 .lock_irq = ezusb_lock_irq,
1561 .unlock_irq = ezusb_unlock_irq,
1562};
1563
1564static const struct net_device_ops ezusb_netdev_ops = {
1565 .ndo_open = orinoco_open,
1566 .ndo_stop = orinoco_stop,
1567 .ndo_start_xmit = ezusb_xmit,
1568 .ndo_set_multicast_list = orinoco_set_multicast_list,
1569 .ndo_change_mtu = orinoco_change_mtu,
1570 .ndo_set_mac_address = eth_mac_addr,
1571 .ndo_validate_addr = eth_validate_addr,
1572 .ndo_tx_timeout = orinoco_tx_timeout,
1573 .ndo_get_stats = orinoco_get_stats,
1574};
1575
1576static int ezusb_probe(struct usb_interface *interface,
1577 const struct usb_device_id *id)
1578{
1579 struct usb_device *udev = interface_to_usbdev(interface);
1580 struct orinoco_private *priv;
1581 hermes_t *hw;
1582 struct ezusb_priv *upriv = NULL;
1583 struct usb_interface_descriptor *iface_desc;
1584 struct usb_endpoint_descriptor *ep;
1585 const struct firmware *fw_entry;
1586 int retval = 0;
1587 int i;
1588
1589 priv = alloc_orinocodev(sizeof(*upriv), &udev->dev,
1590 ezusb_hard_reset, NULL);
1591 if (!priv) {
1592 err("Couldn't allocate orinocodev");
1593 goto exit;
1594 }
1595
1596 hw = &priv->hw;
1597
1598 upriv = priv->card;
1599
1600 mutex_init(&upriv->mtx);
1601 spin_lock_init(&upriv->reply_count_lock);
1602
1603 spin_lock_init(&upriv->req_lock);
1604 INIT_LIST_HEAD(&upriv->req_pending);
1605 INIT_LIST_HEAD(&upriv->req_active);
1606
1607 upriv->udev = udev;
1608
1609 hw->iobase = (void __force __iomem *) &upriv->hermes_reg_fake;
1610 hw->reg_spacing = HERMES_16BIT_REGSPACING;
1611 hw->priv = upriv;
1612 hw->ops = &ezusb_ops;
1613
1614 /* set up the endpoint information */
1615 /* check out the endpoints */
1616
1617 iface_desc = &interface->altsetting[0].desc;
1618 for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
1619 ep = &interface->altsetting[0].endpoint[i].desc;
1620
1621 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1622 == USB_DIR_IN) &&
1623 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1624 == USB_ENDPOINT_XFER_BULK)) {
1625 /* we found a bulk in endpoint */
1626 if (upriv->read_urb != NULL) {
1627 pr_warning("Found a second bulk in ep, ignored");
1628 continue;
1629 }
1630
1631 upriv->read_urb = usb_alloc_urb(0, GFP_KERNEL);
1632 if (!upriv->read_urb) {
1633 err("No free urbs available");
1634 goto error;
1635 }
1636 if (le16_to_cpu(ep->wMaxPacketSize) != 64)
1637 pr_warning("bulk in: wMaxPacketSize!= 64");
1638 if (ep->bEndpointAddress != (2 | USB_DIR_IN))
1639 pr_warning("bulk in: bEndpointAddress: %d",
1640 ep->bEndpointAddress);
1641 upriv->read_pipe = usb_rcvbulkpipe(udev,
1642 ep->
1643 bEndpointAddress);
1644 upriv->read_urb->transfer_buffer =
1645 kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
1646 if (!upriv->read_urb->transfer_buffer) {
1647 err("Couldn't allocate IN buffer");
1648 goto error;
1649 }
1650 }
1651
1652 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1653 == USB_DIR_OUT) &&
1654 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1655 == USB_ENDPOINT_XFER_BULK)) {
1656 /* we found a bulk out endpoint */
1657 if (upriv->bap_buf != NULL) {
1658 pr_warning("Found a second bulk out ep, ignored");
1659 continue;
1660 }
1661
1662 if (le16_to_cpu(ep->wMaxPacketSize) != 64)
1663 pr_warning("bulk out: wMaxPacketSize != 64");
1664 if (ep->bEndpointAddress != 2)
1665 pr_warning("bulk out: bEndpointAddress: %d",
1666 ep->bEndpointAddress);
1667 upriv->write_pipe = usb_sndbulkpipe(udev,
1668 ep->
1669 bEndpointAddress);
1670 upriv->bap_buf = kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
1671 if (!upriv->bap_buf) {
1672 err("Couldn't allocate bulk_out_buffer");
1673 goto error;
1674 }
1675 }
1676 }
1677 if (!upriv->bap_buf || !upriv->read_urb) {
1678 err("Didn't find the required bulk endpoints");
1679 goto error;
1680 }
1681
1682 if (request_firmware(&fw_entry, "orinoco_ezusb_fw",
1683 &interface->dev) == 0) {
1684 firmware.size = fw_entry->size;
1685 firmware.code = fw_entry->data;
1686 }
1687 if (firmware.size && firmware.code) {
1688 ezusb_firmware_download(upriv, &firmware);
1689 } else {
1690 err("No firmware to download");
1691 goto error;
1692 }
1693
1694 if (ezusb_hard_reset(priv) < 0) {
1695 err("Cannot reset the device");
1696 goto error;
1697 }
1698
1699 /* If the firmware is already downloaded orinoco.c will call
1700 * ezusb_init but if the firmware is not already there, that will make
1701 * the kernel very unstable, so we try initializing here and quit in
1702 * case of error */
1703 if (ezusb_init(hw) < 0) {
1704 err("Couldn't initialize the device");
1705 err("Firmware may not be downloaded or may be wrong.");
1706 goto error;
1707 }
1708
1709 /* Initialise the main driver */
1710 if (orinoco_init(priv) != 0) {
1711 err("orinoco_init() failed\n");
1712 goto error;
1713 }
1714
1715 if (orinoco_if_add(priv, 0, 0, &ezusb_netdev_ops) != 0) {
1716 upriv->dev = NULL;
1717 err("%s: orinoco_if_add() failed", __func__);
1718 goto error;
1719 }
1720 upriv->dev = priv->ndev;
1721
1722 goto exit;
1723
1724 error:
1725 ezusb_delete(upriv);
1726 if (upriv->dev) {
1727 /* upriv->dev was 0, so ezusb_delete() didn't free it */
1728 free_orinocodev(priv);
1729 }
1730 upriv = NULL;
1731 retval = -EFAULT;
1732 exit:
1733 if (fw_entry) {
1734 firmware.code = NULL;
1735 firmware.size = 0;
1736 release_firmware(fw_entry);
1737 }
1738 usb_set_intfdata(interface, upriv);
1739 return retval;
1740}
1741
1742
1743static void ezusb_disconnect(struct usb_interface *intf)
1744{
1745 struct ezusb_priv *upriv = usb_get_intfdata(intf);
1746 usb_set_intfdata(intf, NULL);
1747 ezusb_delete(upriv);
1748 printk(KERN_INFO PFX "Disconnected\n");
1749}
1750
1751
1752/* usb specific object needed to register this driver with the usb subsystem */
1753static struct usb_driver orinoco_driver = {
1754 .name = DRIVER_NAME,
1755 .probe = ezusb_probe,
1756 .disconnect = ezusb_disconnect,
1757 .id_table = ezusb_table,
1758};
1759
1760/* Can't be declared "const" or the whole __initdata section will
1761 * become const */
1762static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
1763 " (Manuel Estrada Sainz)";
1764
1765static int __init ezusb_module_init(void)
1766{
1767 int err;
1768
1769 printk(KERN_DEBUG "%s\n", version);
1770
1771 /* register this driver with the USB subsystem */
1772 err = usb_register(&orinoco_driver);
1773 if (err < 0) {
1774 printk(KERN_ERR PFX "usb_register failed, error %d\n",
1775 err);
1776 return err;
1777 }
1778
1779 return 0;
1780}
1781
1782static void __exit ezusb_module_exit(void)
1783{
1784 /* deregister this driver with the USB subsystem */
1785 usb_deregister(&orinoco_driver);
1786}
1787
1788
1789module_init(ezusb_module_init);
1790module_exit(ezusb_module_exit);
1791
1792MODULE_AUTHOR("Manuel Estrada Sainz");
1793MODULE_DESCRIPTION
1794 ("Driver for Orinoco wireless LAN cards using EZUSB bridge");
1795MODULE_LICENSE("Dual MPL/GPL");
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 330d42d45333..4300d9db7d8c 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -127,7 +127,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
127{ 127{
128 struct wiphy *wiphy = priv_to_wiphy(priv); 128 struct wiphy *wiphy = priv_to_wiphy(priv);
129 struct ieee80211_channel *channel; 129 struct ieee80211_channel *channel;
130 u8 *ie; 130 const u8 *ie;
131 u64 timestamp; 131 u64 timestamp;
132 s32 signal; 132 s32 signal;
133 u16 capability; 133 u16 capability;
@@ -136,7 +136,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
136 int chan, freq; 136 int chan, freq;
137 137
138 ie_len = len - sizeof(*bss); 138 ie_len = len - sizeof(*bss);
139 ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS); 139 ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
140 chan = ie ? ie[2] : 0; 140 chan = ie ? ie[2] : 0;
141 freq = ieee80211_dsss_chan_to_freq(chan); 141 freq = ieee80211_dsss_chan_to_freq(chan);
142 channel = ieee80211_get_channel(wiphy, freq); 142 channel = ieee80211_get_channel(wiphy, freq);
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 41b9ce425855..b51a9adc80f6 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -337,6 +337,7 @@ spectrum_cs_config(struct pcmcia_device *link)
337 goto failed; 337 goto failed;
338 338
339 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); 339 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
340 hw->eeprom_pda = true;
340 341
341 /* 342 /*
342 * This actually configures the PCMCIA socket -- setting up 343 * This actually configures the PCMCIA socket -- setting up
@@ -359,7 +360,7 @@ spectrum_cs_config(struct pcmcia_device *link)
359 360
360 /* Register an interface with the stack */ 361 /* Register an interface with the stack */
361 if (orinoco_if_add(priv, link->io.BasePort1, 362 if (orinoco_if_add(priv, link->io.BasePort1,
362 link->irq) != 0) { 363 link->irq, NULL) != 0) {
363 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 364 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
364 goto failed; 365 goto failed;
365 } 366 }
@@ -384,9 +385,9 @@ spectrum_cs_release(struct pcmcia_device *link)
384 385
385 /* We're committed to taking the device away now, so mark the 386 /* We're committed to taking the device away now, so mark the
386 * hardware as unavailable */ 387 * hardware as unavailable */
387 spin_lock_irqsave(&priv->lock, flags); 388 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
388 priv->hw_unavailable++; 389 priv->hw_unavailable++;
389 spin_unlock_irqrestore(&priv->lock, flags); 390 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
390 391
391 pcmcia_disable_device(link); 392 pcmcia_disable_device(link);
392 if (priv->hw.iobase) 393 if (priv->hw.iobase)
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index fbcc6e1a2e1d..5775124e2aee 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -458,7 +458,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
458 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 458 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
459 /* Fast channel change - no commit if successful */ 459 /* Fast channel change - no commit if successful */
460 hermes_t *hw = &priv->hw; 460 hermes_t *hw = &priv->hw;
461 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 461 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
462 HERMES_TEST_SET_CHANNEL, 462 HERMES_TEST_SET_CHANNEL,
463 chan, NULL); 463 chan, NULL);
464 } 464 }
@@ -538,125 +538,6 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
538 return -EINPROGRESS; /* Call commit handler */ 538 return -EINPROGRESS; /* Call commit handler */
539} 539}
540 540
541static int orinoco_ioctl_setrts(struct net_device *dev,
542 struct iw_request_info *info,
543 struct iw_param *rrq,
544 char *extra)
545{
546 struct orinoco_private *priv = ndev_priv(dev);
547 int val = rrq->value;
548 unsigned long flags;
549
550 if (rrq->disabled)
551 val = 2347;
552
553 if ((val < 0) || (val > 2347))
554 return -EINVAL;
555
556 if (orinoco_lock(priv, &flags) != 0)
557 return -EBUSY;
558
559 priv->rts_thresh = val;
560 orinoco_unlock(priv, &flags);
561
562 return -EINPROGRESS; /* Call commit handler */
563}
564
565static int orinoco_ioctl_getrts(struct net_device *dev,
566 struct iw_request_info *info,
567 struct iw_param *rrq,
568 char *extra)
569{
570 struct orinoco_private *priv = ndev_priv(dev);
571
572 rrq->value = priv->rts_thresh;
573 rrq->disabled = (rrq->value == 2347);
574 rrq->fixed = 1;
575
576 return 0;
577}
578
579static int orinoco_ioctl_setfrag(struct net_device *dev,
580 struct iw_request_info *info,
581 struct iw_param *frq,
582 char *extra)
583{
584 struct orinoco_private *priv = ndev_priv(dev);
585 int err = -EINPROGRESS; /* Call commit handler */
586 unsigned long flags;
587
588 if (orinoco_lock(priv, &flags) != 0)
589 return -EBUSY;
590
591 if (priv->has_mwo) {
592 if (frq->disabled)
593 priv->mwo_robust = 0;
594 else {
595 if (frq->fixed)
596 printk(KERN_WARNING "%s: Fixed fragmentation "
597 "is not supported on this firmware. "
598 "Using MWO robust instead.\n",
599 dev->name);
600 priv->mwo_robust = 1;
601 }
602 } else {
603 if (frq->disabled)
604 priv->frag_thresh = 2346;
605 else {
606 if ((frq->value < 256) || (frq->value > 2346))
607 err = -EINVAL;
608 else
609 /* must be even */
610 priv->frag_thresh = frq->value & ~0x1;
611 }
612 }
613
614 orinoco_unlock(priv, &flags);
615
616 return err;
617}
618
619static int orinoco_ioctl_getfrag(struct net_device *dev,
620 struct iw_request_info *info,
621 struct iw_param *frq,
622 char *extra)
623{
624 struct orinoco_private *priv = ndev_priv(dev);
625 hermes_t *hw = &priv->hw;
626 int err;
627 u16 val;
628 unsigned long flags;
629
630 if (orinoco_lock(priv, &flags) != 0)
631 return -EBUSY;
632
633 if (priv->has_mwo) {
634 err = hermes_read_wordrec(hw, USER_BAP,
635 HERMES_RID_CNFMWOROBUST_AGERE,
636 &val);
637 if (err)
638 val = 0;
639
640 frq->value = val ? 2347 : 0;
641 frq->disabled = !val;
642 frq->fixed = 0;
643 } else {
644 err = hermes_read_wordrec(hw, USER_BAP,
645 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
646 &val);
647 if (err)
648 val = 0;
649
650 frq->value = val;
651 frq->disabled = (val >= 2346);
652 frq->fixed = 1;
653 }
654
655 orinoco_unlock(priv, &flags);
656
657 return err;
658}
659
660static int orinoco_ioctl_setrate(struct net_device *dev, 541static int orinoco_ioctl_setrate(struct net_device *dev,
661 struct iw_request_info *info, 542 struct iw_request_info *info,
662 struct iw_param *rrq, 543 struct iw_param *rrq,
@@ -1201,60 +1082,6 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
1201 return ret; 1082 return ret;
1202} 1083}
1203 1084
1204static int orinoco_ioctl_getretry(struct net_device *dev,
1205 struct iw_request_info *info,
1206 struct iw_param *rrq,
1207 char *extra)
1208{
1209 struct orinoco_private *priv = ndev_priv(dev);
1210 hermes_t *hw = &priv->hw;
1211 int err = 0;
1212 u16 short_limit, long_limit, lifetime;
1213 unsigned long flags;
1214
1215 if (orinoco_lock(priv, &flags) != 0)
1216 return -EBUSY;
1217
1218 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
1219 &short_limit);
1220 if (err)
1221 goto out;
1222
1223 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
1224 &long_limit);
1225 if (err)
1226 goto out;
1227
1228 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
1229 &lifetime);
1230 if (err)
1231 goto out;
1232
1233 rrq->disabled = 0; /* Can't be disabled */
1234
1235 /* Note : by default, display the retry number */
1236 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1237 rrq->flags = IW_RETRY_LIFETIME;
1238 rrq->value = lifetime * 1000; /* ??? */
1239 } else {
1240 /* By default, display the min number */
1241 if ((rrq->flags & IW_RETRY_LONG)) {
1242 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1243 rrq->value = long_limit;
1244 } else {
1245 rrq->flags = IW_RETRY_LIMIT;
1246 rrq->value = short_limit;
1247 if (short_limit != long_limit)
1248 rrq->flags |= IW_RETRY_SHORT;
1249 }
1250 }
1251
1252 out:
1253 orinoco_unlock(priv, &flags);
1254
1255 return err;
1256}
1257
1258static int orinoco_ioctl_reset(struct net_device *dev, 1085static int orinoco_ioctl_reset(struct net_device *dev,
1259 struct iw_request_info *info, 1086 struct iw_request_info *info,
1260 void *wrqu, 1087 void *wrqu,
@@ -1446,8 +1273,8 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
1446 if (orinoco_lock(priv, &flags) != 0) 1273 if (orinoco_lock(priv, &flags) != 0)
1447 return -EBUSY; 1274 return -EBUSY;
1448 1275
1449 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, 1276 err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
1450 extra); 1277 extra);
1451 if (err) 1278 if (err)
1452 goto out; 1279 goto out;
1453 1280
@@ -1506,46 +1333,44 @@ static const struct iw_priv_args orinoco_privtab[] = {
1506 * Structures to export the Wireless Handlers 1333 * Structures to export the Wireless Handlers
1507 */ 1334 */
1508 1335
1509#define STD_IW_HANDLER(id, func) \
1510 [IW_IOCTL_IDX(id)] = (iw_handler) func
1511static const iw_handler orinoco_handler[] = { 1336static const iw_handler orinoco_handler[] = {
1512 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit), 1337 IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit),
1513 STD_IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname), 1338 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
1514 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq), 1339 IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq),
1515 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq), 1340 IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq),
1516 STD_IW_HANDLER(SIOCSIWMODE, cfg80211_wext_siwmode), 1341 IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode),
1517 STD_IW_HANDLER(SIOCGIWMODE, cfg80211_wext_giwmode), 1342 IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode),
1518 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens), 1343 IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens),
1519 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens), 1344 IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens),
1520 STD_IW_HANDLER(SIOCGIWRANGE, cfg80211_wext_giwrange), 1345 IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange),
1521 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy), 1346 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1522 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy), 1347 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1523 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy), 1348 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1524 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy), 1349 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1525 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap), 1350 IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap),
1526 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap), 1351 IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap),
1527 STD_IW_HANDLER(SIOCSIWSCAN, cfg80211_wext_siwscan), 1352 IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan),
1528 STD_IW_HANDLER(SIOCGIWSCAN, cfg80211_wext_giwscan), 1353 IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan),
1529 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid), 1354 IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid),
1530 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid), 1355 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1531 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate), 1356 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1532 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate), 1357 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1533 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts), 1358 IW_HANDLER(SIOCSIWRTS, (iw_handler)cfg80211_wext_siwrts),
1534 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts), 1359 IW_HANDLER(SIOCGIWRTS, (iw_handler)cfg80211_wext_giwrts),
1535 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag), 1360 IW_HANDLER(SIOCSIWFRAG, (iw_handler)cfg80211_wext_siwfrag),
1536 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag), 1361 IW_HANDLER(SIOCGIWFRAG, (iw_handler)cfg80211_wext_giwfrag),
1537 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry), 1362 IW_HANDLER(SIOCGIWRETRY, (iw_handler)cfg80211_wext_giwretry),
1538 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode), 1363 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1539 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode), 1364 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1540 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower), 1365 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),
1541 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower), 1366 IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower),
1542 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie), 1367 IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
1543 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie), 1368 IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
1544 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme), 1369 IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
1545 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth), 1370 IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
1546 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth), 1371 IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
1547 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext), 1372 IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
1548 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext), 1373 IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
1549}; 1374};
1550 1375
1551 1376
@@ -1553,15 +1378,15 @@ static const iw_handler orinoco_handler[] = {
1553 Added typecasting since we no longer use iwreq_data -- Moustafa 1378 Added typecasting since we no longer use iwreq_data -- Moustafa
1554 */ 1379 */
1555static const iw_handler orinoco_private_handler[] = { 1380static const iw_handler orinoco_private_handler[] = {
1556 [0] = (iw_handler) orinoco_ioctl_reset, 1381 [0] = (iw_handler)orinoco_ioctl_reset,
1557 [1] = (iw_handler) orinoco_ioctl_reset, 1382 [1] = (iw_handler)orinoco_ioctl_reset,
1558 [2] = (iw_handler) orinoco_ioctl_setport3, 1383 [2] = (iw_handler)orinoco_ioctl_setport3,
1559 [3] = (iw_handler) orinoco_ioctl_getport3, 1384 [3] = (iw_handler)orinoco_ioctl_getport3,
1560 [4] = (iw_handler) orinoco_ioctl_setpreamble, 1385 [4] = (iw_handler)orinoco_ioctl_setpreamble,
1561 [5] = (iw_handler) orinoco_ioctl_getpreamble, 1386 [5] = (iw_handler)orinoco_ioctl_getpreamble,
1562 [6] = (iw_handler) orinoco_ioctl_setibssport, 1387 [6] = (iw_handler)orinoco_ioctl_setibssport,
1563 [7] = (iw_handler) orinoco_ioctl_getibssport, 1388 [7] = (iw_handler)orinoco_ioctl_getibssport,
1564 [9] = (iw_handler) orinoco_ioctl_getrid, 1389 [9] = (iw_handler)orinoco_ioctl_getrid,
1565}; 1390};
1566 1391
1567const struct iw_handler_def orinoco_handler_def = { 1392const struct iw_handler_def orinoco_handler_def = {
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index a7cb9eb759a1..c072f41747ca 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -546,7 +546,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
546 IEEE80211_HW_SUPPORTS_PS | 546 IEEE80211_HW_SUPPORTS_PS |
547 IEEE80211_HW_PS_NULLFUNC_STACK | 547 IEEE80211_HW_PS_NULLFUNC_STACK |
548 IEEE80211_HW_BEACON_FILTER | 548 IEEE80211_HW_BEACON_FILTER |
549 IEEE80211_HW_NOISE_DBM; 549 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
550 550
551 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 551 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
552 BIT(NL80211_IFTYPE_ADHOC) | 552 BIT(NL80211_IFTYPE_ADHOC) |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index c24067f1a0cb..07c4528f6e6b 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -132,7 +132,7 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
132 132
133static void p54p_refill_rx_ring(struct ieee80211_hw *dev, 133static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
134 int ring_index, struct p54p_desc *ring, u32 ring_limit, 134 int ring_index, struct p54p_desc *ring, u32 ring_limit,
135 struct sk_buff **rx_buf) 135 struct sk_buff **rx_buf, u32 index)
136{ 136{
137 struct p54p_priv *priv = dev->priv; 137 struct p54p_priv *priv = dev->priv;
138 struct p54p_ring_control *ring_control = priv->ring_control; 138 struct p54p_ring_control *ring_control = priv->ring_control;
@@ -140,7 +140,7 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
140 140
141 idx = le32_to_cpu(ring_control->host_idx[ring_index]); 141 idx = le32_to_cpu(ring_control->host_idx[ring_index]);
142 limit = idx; 142 limit = idx;
143 limit -= le32_to_cpu(ring_control->device_idx[ring_index]); 143 limit -= index;
144 limit = ring_limit - limit; 144 limit = ring_limit - limit;
145 145
146 i = idx % ring_limit; 146 i = idx % ring_limit;
@@ -232,7 +232,7 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
232 i %= ring_limit; 232 i %= ring_limit;
233 } 233 }
234 234
235 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf); 235 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf, *index);
236} 236}
237 237
238static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, 238static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
@@ -445,10 +445,10 @@ static int p54p_open(struct ieee80211_hw *dev)
445 priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; 445 priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0;
446 446
447 p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data, 447 p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data,
448 ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data); 448 ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data, 0);
449 449
450 p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, 450 p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt,
451 ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); 451 ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt, 0);
452 452
453 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); 453 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
454 P54P_READ(ring_control_base); 454 P54P_READ(ring_control_base);
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 743a6c68b29d..d5b197b4d5bb 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -875,7 +875,6 @@ static void p54u_stop(struct ieee80211_hw *dev)
875 the hardware is still usable next time we want to start it. 875 the hardware is still usable next time we want to start it.
876 until then, we just stop listening to the hardware.. */ 876 until then, we just stop listening to the hardware.. */
877 p54u_free_urbs(dev); 877 p54u_free_urbs(dev);
878 return;
879} 878}
880 879
881static int __devinit p54u_probe(struct usb_interface *intf, 880static int __devinit p54u_probe(struct usb_interface *intf,
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 66057999a93c..4e6891099d43 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -38,7 +38,7 @@ static void p54_dump_tx_queue(struct p54_common *priv)
38 u32 largest_hole = 0, free; 38 u32 largest_hole = 0, free;
39 39
40 spin_lock_irqsave(&priv->tx_queue.lock, flags); 40 spin_lock_irqsave(&priv->tx_queue.lock, flags);
41 printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) --- \n", 41 printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n",
42 wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue)); 42 wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue));
43 43
44 prev_addr = priv->rx_start; 44 prev_addr = priv->rx_start;
@@ -350,7 +350,6 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
350 rx_status->flag |= RX_FLAG_MMIC_ERROR; 350 rx_status->flag |= RX_FLAG_MMIC_ERROR;
351 351
352 rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); 352 rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
353 rx_status->noise = priv->noise;
354 if (hdr->rate & 0x10) 353 if (hdr->rate & 0x10)
355 rx_status->flag |= RX_FLAG_SHORTPRE; 354 rx_status->flag |= RX_FLAG_SHORTPRE;
356 if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) 355 if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index a45818ebfdfb..8d1190c0f062 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -210,8 +210,6 @@ prism54_update_stats(struct work_struct *work)
210 priv->local_iwstatistics.discard.retries = r.u; 210 priv->local_iwstatistics.discard.retries = r.u;
211 211
212 mutex_unlock(&priv->stats_lock); 212 mutex_unlock(&priv->stats_lock);
213
214 return;
215} 213}
216 214
217struct iw_statistics * 215struct iw_statistics *
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 689d59a13d5b..2c8cc954d1b6 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -228,14 +228,14 @@ islpci_interrupt(int irq, void *config)
228 228
229#if VERBOSE > SHOW_ERROR_MESSAGES 229#if VERBOSE > SHOW_ERROR_MESSAGES
230 DEBUG(SHOW_FUNCTION_CALLS, 230 DEBUG(SHOW_FUNCTION_CALLS,
231 "IRQ: Identification register 0x%p 0x%x \n", device, reg); 231 "IRQ: Identification register 0x%p 0x%x\n", device, reg);
232#endif 232#endif
233 233
234 /* check for each bit in the register separately */ 234 /* check for each bit in the register separately */
235 if (reg & ISL38XX_INT_IDENT_UPDATE) { 235 if (reg & ISL38XX_INT_IDENT_UPDATE) {
236#if VERBOSE > SHOW_ERROR_MESSAGES 236#if VERBOSE > SHOW_ERROR_MESSAGES
237 /* Queue has been updated */ 237 /* Queue has been updated */
238 DEBUG(SHOW_TRACING, "IRQ: Update flag \n"); 238 DEBUG(SHOW_TRACING, "IRQ: Update flag\n");
239 239
240 DEBUG(SHOW_QUEUE_INDEXES, 240 DEBUG(SHOW_QUEUE_INDEXES,
241 "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n", 241 "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
@@ -301,7 +301,7 @@ islpci_interrupt(int irq, void *config)
301 ISL38XX_CB_RX_DATA_LQ) != 0) { 301 ISL38XX_CB_RX_DATA_LQ) != 0) {
302#if VERBOSE > SHOW_ERROR_MESSAGES 302#if VERBOSE > SHOW_ERROR_MESSAGES
303 DEBUG(SHOW_TRACING, 303 DEBUG(SHOW_TRACING,
304 "Received frame in Data Low Queue \n"); 304 "Received frame in Data Low Queue\n");
305#endif 305#endif
306 islpci_eth_receive(priv); 306 islpci_eth_receive(priv);
307 } 307 }
@@ -326,7 +326,7 @@ islpci_interrupt(int irq, void *config)
326 /* Device has been initialized */ 326 /* Device has been initialized */
327#if VERBOSE > SHOW_ERROR_MESSAGES 327#if VERBOSE > SHOW_ERROR_MESSAGES
328 DEBUG(SHOW_TRACING, 328 DEBUG(SHOW_TRACING,
329 "IRQ: Init flag, device initialized \n"); 329 "IRQ: Init flag, device initialized\n");
330#endif 330#endif
331 wake_up(&priv->reset_done); 331 wake_up(&priv->reset_done);
332 } 332 }
@@ -334,7 +334,7 @@ islpci_interrupt(int irq, void *config)
334 if (reg & ISL38XX_INT_IDENT_SLEEP) { 334 if (reg & ISL38XX_INT_IDENT_SLEEP) {
335 /* Device intends to move to powersave state */ 335 /* Device intends to move to powersave state */
336#if VERBOSE > SHOW_ERROR_MESSAGES 336#if VERBOSE > SHOW_ERROR_MESSAGES
337 DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n"); 337 DEBUG(SHOW_TRACING, "IRQ: Sleep flag\n");
338#endif 338#endif
339 isl38xx_handle_sleep_request(priv->control_block, 339 isl38xx_handle_sleep_request(priv->control_block,
340 &powerstate, 340 &powerstate,
@@ -344,7 +344,7 @@ islpci_interrupt(int irq, void *config)
344 if (reg & ISL38XX_INT_IDENT_WAKEUP) { 344 if (reg & ISL38XX_INT_IDENT_WAKEUP) {
345 /* Device has been woken up to active state */ 345 /* Device has been woken up to active state */
346#if VERBOSE > SHOW_ERROR_MESSAGES 346#if VERBOSE > SHOW_ERROR_MESSAGES
347 DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n"); 347 DEBUG(SHOW_TRACING, "IRQ: Wakeup flag\n");
348#endif 348#endif
349 349
350 isl38xx_handle_wakeup(priv->control_block, 350 isl38xx_handle_wakeup(priv->control_block,
@@ -635,7 +635,7 @@ islpci_alloc_memory(islpci_private *priv)
635 ioremap(pci_resource_start(priv->pdev, 0), 635 ioremap(pci_resource_start(priv->pdev, 0),
636 ISL38XX_PCI_MEM_SIZE))) { 636 ISL38XX_PCI_MEM_SIZE))) {
637 /* error in remapping the PCI device memory address range */ 637 /* error in remapping the PCI device memory address range */
638 printk(KERN_ERR "PCI memory remapping failed \n"); 638 printk(KERN_ERR "PCI memory remapping failed\n");
639 return -1; 639 return -1;
640 } 640 }
641 641
@@ -902,7 +902,7 @@ islpci_setup(struct pci_dev *pdev)
902 902
903 if (register_netdev(ndev)) { 903 if (register_netdev(ndev)) {
904 DEBUG(SHOW_ERROR_MESSAGES, 904 DEBUG(SHOW_ERROR_MESSAGES,
905 "ERROR: register_netdev() failed \n"); 905 "ERROR: register_netdev() failed\n");
906 goto do_islpci_free_memory; 906 goto do_islpci_free_memory;
907 } 907 }
908 908
@@ -946,7 +946,7 @@ islpci_set_state(islpci_private *priv, islpci_state_t new_state)
946 if (!priv->state_off) 946 if (!priv->state_off)
947 priv->state = new_state; 947 priv->state = new_state;
948 break; 948 break;
949 }; 949 }
950#if 0 950#if 0
951 printk(KERN_DEBUG "%s: state transition %d -> %d (off#%d)\n", 951 printk(KERN_DEBUG "%s: state transition %d -> %d (off#%d)\n",
952 priv->ndev->name, old_state, new_state, priv->state_off); 952 priv->ndev->name, old_state, new_state, priv->state_off);
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index ac99eaaeabce..2fc52bc2d7dd 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -90,7 +90,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
90 u32 curr_frag; 90 u32 curr_frag;
91 91
92#if VERBOSE > SHOW_ERROR_MESSAGES 92#if VERBOSE > SHOW_ERROR_MESSAGES
93 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n"); 93 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit\n");
94#endif 94#endif
95 95
96 /* lock the driver code */ 96 /* lock the driver code */
@@ -141,7 +141,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
141 } 141 }
142 142
143#if VERBOSE > SHOW_ERROR_MESSAGES 143#if VERBOSE > SHOW_ERROR_MESSAGES
144 DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data, 144 DEBUG(SHOW_TRACING, "memmove %p %p %i\n", skb->data,
145 src, skb->len); 145 src, skb->len);
146#endif 146#endif
147 } else { 147 } else {
@@ -224,8 +224,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
224 priv->data_low_tx_full = 1; 224 priv->data_low_tx_full = 1;
225 } 225 }
226 226
227 /* set the transmission time */
228 ndev->trans_start = jiffies;
229 ndev->stats.tx_packets++; 227 ndev->stats.tx_packets++;
230 ndev->stats.tx_bytes += skb->len; 228 ndev->stats.tx_bytes += skb->len;
231 229
@@ -320,7 +318,7 @@ islpci_eth_receive(islpci_private *priv)
320 int discard = 0; 318 int discard = 0;
321 319
322#if VERBOSE > SHOW_ERROR_MESSAGES 320#if VERBOSE > SHOW_ERROR_MESSAGES
323 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n"); 321 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive\n");
324#endif 322#endif
325 323
326 /* the device has written an Ethernet frame in the data area 324 /* the device has written an Ethernet frame in the data area
@@ -432,7 +430,7 @@ islpci_eth_receive(islpci_private *priv)
432 skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2); 430 skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
433 if (unlikely(skb == NULL)) { 431 if (unlikely(skb == NULL)) {
434 /* error allocating an sk_buff structure elements */ 432 /* error allocating an sk_buff structure elements */
435 DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n"); 433 DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb\n");
436 break; 434 break;
437 } 435 }
438 skb_reserve(skb, (4 - (long) skb->data) & 0x03); 436 skb_reserve(skb, (4 - (long) skb->data) & 0x03);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index adb289723a96..a5224f6160e4 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -114,7 +114,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
114 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]); 114 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
115 115
116#if VERBOSE > SHOW_ERROR_MESSAGES 116#if VERBOSE > SHOW_ERROR_MESSAGES
117 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill \n"); 117 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill\n");
118#endif 118#endif
119 119
120 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) { 120 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) {
@@ -212,7 +212,7 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
212 { 212 {
213 pimfor_header_t *h = buf.mem; 213 pimfor_header_t *h = buf.mem;
214 DEBUG(SHOW_PIMFOR_FRAMES, 214 DEBUG(SHOW_PIMFOR_FRAMES,
215 "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x \n", 215 "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x\n",
216 h->operation, oid, h->device_id, h->flags, length); 216 h->operation, oid, h->device_id, h->flags, length);
217 217
218 /* display the buffer contents for debugging */ 218 /* display the buffer contents for debugging */
@@ -280,7 +280,7 @@ islpci_mgt_receive(struct net_device *ndev)
280 u32 curr_frag; 280 u32 curr_frag;
281 281
282#if VERBOSE > SHOW_ERROR_MESSAGES 282#if VERBOSE > SHOW_ERROR_MESSAGES
283 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n"); 283 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive\n");
284#endif 284#endif
285 285
286 /* Only once per interrupt, determine fragment range to 286 /* Only once per interrupt, determine fragment range to
@@ -339,7 +339,7 @@ islpci_mgt_receive(struct net_device *ndev)
339 339
340#if VERBOSE > SHOW_ERROR_MESSAGES 340#if VERBOSE > SHOW_ERROR_MESSAGES
341 DEBUG(SHOW_PIMFOR_FRAMES, 341 DEBUG(SHOW_PIMFOR_FRAMES,
342 "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n", 342 "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x\n",
343 header->operation, header->oid, header->device_id, 343 header->operation, header->oid, header->device_id,
344 header->flags, header->length); 344 header->flags, header->length);
345 345
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index d66933d70fb9..9b796cae4afe 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -820,7 +820,7 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
820 k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr); 820 k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
821 for (i = 0; i < list->nr; i++) 821 for (i = 0; i < list->nr; i++)
822 k += snprintf(str + k, PRIV_STR_SIZE - k, 822 k += snprintf(str + k, PRIV_STR_SIZE - k,
823 "bss[%u] : \nage=%u\nchannel=%u\n" 823 "bss[%u] :\nage=%u\nchannel=%u\n"
824 "capinfo=0x%X\nrates=0x%X\n" 824 "capinfo=0x%X\nrates=0x%X\n"
825 "basic_rates=0x%X\n", 825 "basic_rates=0x%X\n",
826 i, list->bsslist[i].age, 826 i, list->bsslist[i].age,
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index f7d2a34ca531..abff8934db13 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -546,7 +546,7 @@ static int ray_init(struct net_device *dev)
546 local->fw_ver = local->startup_res.firmware_version[0]; 546 local->fw_ver = local->startup_res.firmware_version[0];
547 local->fw_bld = local->startup_res.firmware_version[1]; 547 local->fw_bld = local->startup_res.firmware_version[1];
548 local->fw_var = local->startup_res.firmware_version[2]; 548 local->fw_var = local->startup_res.firmware_version[2];
549 dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver, 549 dev_dbg(&link->dev, "ray_init firmware version %d.%d\n", local->fw_ver,
550 local->fw_bld); 550 local->fw_bld);
551 551
552 local->tib_length = 0x20; 552 local->tib_length = 0x20;
@@ -726,8 +726,6 @@ static void verify_dl_startup(u_long data)
726 start_net((u_long) local); 726 start_net((u_long) local);
727 else 727 else
728 join_net((u_long) local); 728 join_net((u_long) local);
729
730 return;
731} /* end verify_dl_startup */ 729} /* end verify_dl_startup */
732 730
733/*===========================================================================*/ 731/*===========================================================================*/
@@ -755,7 +753,6 @@ static void start_net(u_long data)
755 return; 753 return;
756 } 754 }
757 local->card_status = CARD_DOING_ACQ; 755 local->card_status = CARD_DOING_ACQ;
758 return;
759} /* end start_net */ 756} /* end start_net */
760 757
761/*===========================================================================*/ 758/*===========================================================================*/
@@ -786,7 +783,6 @@ static void join_net(u_long data)
786 return; 783 return;
787 } 784 }
788 local->card_status = CARD_DOING_ACQ; 785 local->card_status = CARD_DOING_ACQ;
789 return;
790} 786}
791 787
792/*============================================================================ 788/*============================================================================
@@ -932,7 +928,6 @@ static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
932 case XMIT_MSG_BAD: 928 case XMIT_MSG_BAD:
933 case XMIT_OK: 929 case XMIT_OK:
934 default: 930 default:
935 dev->trans_start = jiffies;
936 dev_kfree_skb(skb); 931 dev_kfree_skb(skb);
937 } 932 }
938 933
@@ -1103,10 +1098,10 @@ static const struct ethtool_ops netdev_ethtool_ops = {
1103/* 1098/*
1104 * Wireless Handler : get protocol name 1099 * Wireless Handler : get protocol name
1105 */ 1100 */
1106static int ray_get_name(struct net_device *dev, 1101static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1107 struct iw_request_info *info, char *cwrq, char *extra) 1102 union iwreq_data *wrqu, char *extra)
1108{ 1103{
1109 strcpy(cwrq, "IEEE 802.11-FH"); 1104 strcpy(wrqu->name, "IEEE 802.11-FH");
1110 return 0; 1105 return 0;
1111} 1106}
1112 1107
@@ -1114,9 +1109,8 @@ static int ray_get_name(struct net_device *dev,
1114/* 1109/*
1115 * Wireless Handler : set frequency 1110 * Wireless Handler : set frequency
1116 */ 1111 */
1117static int ray_set_freq(struct net_device *dev, 1112static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1118 struct iw_request_info *info, 1113 union iwreq_data *wrqu, char *extra)
1119 struct iw_freq *fwrq, char *extra)
1120{ 1114{
1121 ray_dev_t *local = netdev_priv(dev); 1115 ray_dev_t *local = netdev_priv(dev);
1122 int err = -EINPROGRESS; /* Call commit handler */ 1116 int err = -EINPROGRESS; /* Call commit handler */
@@ -1126,10 +1120,10 @@ static int ray_set_freq(struct net_device *dev,
1126 return -EBUSY; 1120 return -EBUSY;
1127 1121
1128 /* Setting by channel number */ 1122 /* Setting by channel number */
1129 if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) 1123 if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1130 err = -EOPNOTSUPP; 1124 err = -EOPNOTSUPP;
1131 else 1125 else
1132 local->sparm.b5.a_hop_pattern = fwrq->m; 1126 local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1133 1127
1134 return err; 1128 return err;
1135} 1129}
@@ -1138,14 +1132,13 @@ static int ray_set_freq(struct net_device *dev,
1138/* 1132/*
1139 * Wireless Handler : get frequency 1133 * Wireless Handler : get frequency
1140 */ 1134 */
1141static int ray_get_freq(struct net_device *dev, 1135static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1142 struct iw_request_info *info, 1136 union iwreq_data *wrqu, char *extra)
1143 struct iw_freq *fwrq, char *extra)
1144{ 1137{
1145 ray_dev_t *local = netdev_priv(dev); 1138 ray_dev_t *local = netdev_priv(dev);
1146 1139
1147 fwrq->m = local->sparm.b5.a_hop_pattern; 1140 wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1148 fwrq->e = 0; 1141 wrqu->freq.e = 0;
1149 return 0; 1142 return 0;
1150} 1143}
1151 1144
@@ -1153,9 +1146,8 @@ static int ray_get_freq(struct net_device *dev,
1153/* 1146/*
1154 * Wireless Handler : set ESSID 1147 * Wireless Handler : set ESSID
1155 */ 1148 */
1156static int ray_set_essid(struct net_device *dev, 1149static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1157 struct iw_request_info *info, 1150 union iwreq_data *wrqu, char *extra)
1158 struct iw_point *dwrq, char *extra)
1159{ 1151{
1160 ray_dev_t *local = netdev_priv(dev); 1152 ray_dev_t *local = netdev_priv(dev);
1161 1153
@@ -1164,19 +1156,17 @@ static int ray_set_essid(struct net_device *dev,
1164 return -EBUSY; 1156 return -EBUSY;
1165 1157
1166 /* Check if we asked for `any' */ 1158 /* Check if we asked for `any' */
1167 if (dwrq->flags == 0) { 1159 if (wrqu->essid.flags == 0)
1168 /* Corey : can you do that ? */ 1160 /* Corey : can you do that ? */
1169 return -EOPNOTSUPP; 1161 return -EOPNOTSUPP;
1170 } else {
1171 /* Check the size of the string */
1172 if (dwrq->length > IW_ESSID_MAX_SIZE) {
1173 return -E2BIG;
1174 }
1175 1162
1176 /* Set the ESSID in the card */ 1163 /* Check the size of the string */
1177 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); 1164 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1178 memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); 1165 return -E2BIG;
1179 } 1166
1167 /* Set the ESSID in the card */
1168 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1169 memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1180 1170
1181 return -EINPROGRESS; /* Call commit handler */ 1171 return -EINPROGRESS; /* Call commit handler */
1182} 1172}
@@ -1185,9 +1175,8 @@ static int ray_set_essid(struct net_device *dev,
1185/* 1175/*
1186 * Wireless Handler : get ESSID 1176 * Wireless Handler : get ESSID
1187 */ 1177 */
1188static int ray_get_essid(struct net_device *dev, 1178static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1189 struct iw_request_info *info, 1179 union iwreq_data *wrqu, char *extra)
1190 struct iw_point *dwrq, char *extra)
1191{ 1180{
1192 ray_dev_t *local = netdev_priv(dev); 1181 ray_dev_t *local = netdev_priv(dev);
1193 1182
@@ -1195,8 +1184,8 @@ static int ray_get_essid(struct net_device *dev,
1195 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); 1184 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1196 1185
1197 /* Push it out ! */ 1186 /* Push it out ! */
1198 dwrq->length = strlen(extra); 1187 wrqu->essid.length = strlen(extra);
1199 dwrq->flags = 1; /* active */ 1188 wrqu->essid.flags = 1; /* active */
1200 1189
1201 return 0; 1190 return 0;
1202} 1191}
@@ -1205,14 +1194,13 @@ static int ray_get_essid(struct net_device *dev,
1205/* 1194/*
1206 * Wireless Handler : get AP address 1195 * Wireless Handler : get AP address
1207 */ 1196 */
1208static int ray_get_wap(struct net_device *dev, 1197static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1209 struct iw_request_info *info, 1198 union iwreq_data *wrqu, char *extra)
1210 struct sockaddr *awrq, char *extra)
1211{ 1199{
1212 ray_dev_t *local = netdev_priv(dev); 1200 ray_dev_t *local = netdev_priv(dev);
1213 1201
1214 memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); 1202 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1215 awrq->sa_family = ARPHRD_ETHER; 1203 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1216 1204
1217 return 0; 1205 return 0;
1218} 1206}
@@ -1221,9 +1209,8 @@ static int ray_get_wap(struct net_device *dev,
1221/* 1209/*
1222 * Wireless Handler : set Bit-Rate 1210 * Wireless Handler : set Bit-Rate
1223 */ 1211 */
1224static int ray_set_rate(struct net_device *dev, 1212static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1225 struct iw_request_info *info, 1213 union iwreq_data *wrqu, char *extra)
1226 struct iw_param *vwrq, char *extra)
1227{ 1214{
1228 ray_dev_t *local = netdev_priv(dev); 1215 ray_dev_t *local = netdev_priv(dev);
1229 1216
@@ -1232,15 +1219,15 @@ static int ray_set_rate(struct net_device *dev,
1232 return -EBUSY; 1219 return -EBUSY;
1233 1220
1234 /* Check if rate is in range */ 1221 /* Check if rate is in range */
1235 if ((vwrq->value != 1000000) && (vwrq->value != 2000000)) 1222 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1236 return -EINVAL; 1223 return -EINVAL;
1237 1224
1238 /* Hack for 1.5 Mb/s instead of 2 Mb/s */ 1225 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1239 if ((local->fw_ver == 0x55) && /* Please check */ 1226 if ((local->fw_ver == 0x55) && /* Please check */
1240 (vwrq->value == 2000000)) 1227 (wrqu->bitrate.value == 2000000))
1241 local->net_default_tx_rate = 3; 1228 local->net_default_tx_rate = 3;
1242 else 1229 else
1243 local->net_default_tx_rate = vwrq->value / 500000; 1230 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1244 1231
1245 return 0; 1232 return 0;
1246} 1233}
@@ -1249,17 +1236,16 @@ static int ray_set_rate(struct net_device *dev,
1249/* 1236/*
1250 * Wireless Handler : get Bit-Rate 1237 * Wireless Handler : get Bit-Rate
1251 */ 1238 */
1252static int ray_get_rate(struct net_device *dev, 1239static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1253 struct iw_request_info *info, 1240 union iwreq_data *wrqu, char *extra)
1254 struct iw_param *vwrq, char *extra)
1255{ 1241{
1256 ray_dev_t *local = netdev_priv(dev); 1242 ray_dev_t *local = netdev_priv(dev);
1257 1243
1258 if (local->net_default_tx_rate == 3) 1244 if (local->net_default_tx_rate == 3)
1259 vwrq->value = 2000000; /* Hum... */ 1245 wrqu->bitrate.value = 2000000; /* Hum... */
1260 else 1246 else
1261 vwrq->value = local->net_default_tx_rate * 500000; 1247 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1262 vwrq->fixed = 0; /* We are in auto mode */ 1248 wrqu->bitrate.fixed = 0; /* We are in auto mode */
1263 1249
1264 return 0; 1250 return 0;
1265} 1251}
@@ -1268,19 +1254,18 @@ static int ray_get_rate(struct net_device *dev,
1268/* 1254/*
1269 * Wireless Handler : set RTS threshold 1255 * Wireless Handler : set RTS threshold
1270 */ 1256 */
1271static int ray_set_rts(struct net_device *dev, 1257static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1272 struct iw_request_info *info, 1258 union iwreq_data *wrqu, char *extra)
1273 struct iw_param *vwrq, char *extra)
1274{ 1259{
1275 ray_dev_t *local = netdev_priv(dev); 1260 ray_dev_t *local = netdev_priv(dev);
1276 int rthr = vwrq->value; 1261 int rthr = wrqu->rts.value;
1277 1262
1278 /* Reject if card is already initialised */ 1263 /* Reject if card is already initialised */
1279 if (local->card_status != CARD_AWAITING_PARAM) 1264 if (local->card_status != CARD_AWAITING_PARAM)
1280 return -EBUSY; 1265 return -EBUSY;
1281 1266
1282 /* if(wrq->u.rts.fixed == 0) we should complain */ 1267 /* if(wrq->u.rts.fixed == 0) we should complain */
1283 if (vwrq->disabled) 1268 if (wrqu->rts.disabled)
1284 rthr = 32767; 1269 rthr = 32767;
1285 else { 1270 else {
1286 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ 1271 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
@@ -1296,16 +1281,15 @@ static int ray_set_rts(struct net_device *dev,
1296/* 1281/*
1297 * Wireless Handler : get RTS threshold 1282 * Wireless Handler : get RTS threshold
1298 */ 1283 */
1299static int ray_get_rts(struct net_device *dev, 1284static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1300 struct iw_request_info *info, 1285 union iwreq_data *wrqu, char *extra)
1301 struct iw_param *vwrq, char *extra)
1302{ 1286{
1303 ray_dev_t *local = netdev_priv(dev); 1287 ray_dev_t *local = netdev_priv(dev);
1304 1288
1305 vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) 1289 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1306 + local->sparm.b5.a_rts_threshold[1]; 1290 + local->sparm.b5.a_rts_threshold[1];
1307 vwrq->disabled = (vwrq->value == 32767); 1291 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1308 vwrq->fixed = 1; 1292 wrqu->rts.fixed = 1;
1309 1293
1310 return 0; 1294 return 0;
1311} 1295}
@@ -1314,19 +1298,18 @@ static int ray_get_rts(struct net_device *dev,
1314/* 1298/*
1315 * Wireless Handler : set Fragmentation threshold 1299 * Wireless Handler : set Fragmentation threshold
1316 */ 1300 */
1317static int ray_set_frag(struct net_device *dev, 1301static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1318 struct iw_request_info *info, 1302 union iwreq_data *wrqu, char *extra)
1319 struct iw_param *vwrq, char *extra)
1320{ 1303{
1321 ray_dev_t *local = netdev_priv(dev); 1304 ray_dev_t *local = netdev_priv(dev);
1322 int fthr = vwrq->value; 1305 int fthr = wrqu->frag.value;
1323 1306
1324 /* Reject if card is already initialised */ 1307 /* Reject if card is already initialised */
1325 if (local->card_status != CARD_AWAITING_PARAM) 1308 if (local->card_status != CARD_AWAITING_PARAM)
1326 return -EBUSY; 1309 return -EBUSY;
1327 1310
1328 /* if(wrq->u.frag.fixed == 0) should complain */ 1311 /* if(wrq->u.frag.fixed == 0) should complain */
1329 if (vwrq->disabled) 1312 if (wrqu->frag.disabled)
1330 fthr = 32767; 1313 fthr = 32767;
1331 else { 1314 else {
1332 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */ 1315 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */
@@ -1342,16 +1325,15 @@ static int ray_set_frag(struct net_device *dev,
1342/* 1325/*
1343 * Wireless Handler : get Fragmentation threshold 1326 * Wireless Handler : get Fragmentation threshold
1344 */ 1327 */
1345static int ray_get_frag(struct net_device *dev, 1328static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1346 struct iw_request_info *info, 1329 union iwreq_data *wrqu, char *extra)
1347 struct iw_param *vwrq, char *extra)
1348{ 1330{
1349 ray_dev_t *local = netdev_priv(dev); 1331 ray_dev_t *local = netdev_priv(dev);
1350 1332
1351 vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) 1333 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1352 + local->sparm.b5.a_frag_threshold[1]; 1334 + local->sparm.b5.a_frag_threshold[1];
1353 vwrq->disabled = (vwrq->value == 32767); 1335 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1354 vwrq->fixed = 1; 1336 wrqu->frag.fixed = 1;
1355 1337
1356 return 0; 1338 return 0;
1357} 1339}
@@ -1360,8 +1342,8 @@ static int ray_get_frag(struct net_device *dev,
1360/* 1342/*
1361 * Wireless Handler : set Mode of Operation 1343 * Wireless Handler : set Mode of Operation
1362 */ 1344 */
1363static int ray_set_mode(struct net_device *dev, 1345static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1364 struct iw_request_info *info, __u32 *uwrq, char *extra) 1346 union iwreq_data *wrqu, char *extra)
1365{ 1347{
1366 ray_dev_t *local = netdev_priv(dev); 1348 ray_dev_t *local = netdev_priv(dev);
1367 int err = -EINPROGRESS; /* Call commit handler */ 1349 int err = -EINPROGRESS; /* Call commit handler */
@@ -1371,7 +1353,7 @@ static int ray_set_mode(struct net_device *dev,
1371 if (local->card_status != CARD_AWAITING_PARAM) 1353 if (local->card_status != CARD_AWAITING_PARAM)
1372 return -EBUSY; 1354 return -EBUSY;
1373 1355
1374 switch (*uwrq) { 1356 switch (wrqu->mode) {
1375 case IW_MODE_ADHOC: 1357 case IW_MODE_ADHOC:
1376 card_mode = 0; 1358 card_mode = 0;
1377 /* Fall through */ 1359 /* Fall through */
@@ -1389,15 +1371,15 @@ static int ray_set_mode(struct net_device *dev,
1389/* 1371/*
1390 * Wireless Handler : get Mode of Operation 1372 * Wireless Handler : get Mode of Operation
1391 */ 1373 */
1392static int ray_get_mode(struct net_device *dev, 1374static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1393 struct iw_request_info *info, __u32 *uwrq, char *extra) 1375 union iwreq_data *wrqu, char *extra)
1394{ 1376{
1395 ray_dev_t *local = netdev_priv(dev); 1377 ray_dev_t *local = netdev_priv(dev);
1396 1378
1397 if (local->sparm.b5.a_network_type) 1379 if (local->sparm.b5.a_network_type)
1398 *uwrq = IW_MODE_INFRA; 1380 wrqu->mode = IW_MODE_INFRA;
1399 else 1381 else
1400 *uwrq = IW_MODE_ADHOC; 1382 wrqu->mode = IW_MODE_ADHOC;
1401 1383
1402 return 0; 1384 return 0;
1403} 1385}
@@ -1406,16 +1388,15 @@ static int ray_get_mode(struct net_device *dev,
1406/* 1388/*
1407 * Wireless Handler : get range info 1389 * Wireless Handler : get range info
1408 */ 1390 */
1409static int ray_get_range(struct net_device *dev, 1391static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1410 struct iw_request_info *info, 1392 union iwreq_data *wrqu, char *extra)
1411 struct iw_point *dwrq, char *extra)
1412{ 1393{
1413 struct iw_range *range = (struct iw_range *)extra; 1394 struct iw_range *range = (struct iw_range *)extra;
1414 1395
1415 memset((char *)range, 0, sizeof(struct iw_range)); 1396 memset(range, 0, sizeof(struct iw_range));
1416 1397
1417 /* Set the length (very important for backward compatibility) */ 1398 /* Set the length (very important for backward compatibility) */
1418 dwrq->length = sizeof(struct iw_range); 1399 wrqu->data.length = sizeof(struct iw_range);
1419 1400
1420 /* Set the Wireless Extension versions */ 1401 /* Set the Wireless Extension versions */
1421 range->we_version_compiled = WIRELESS_EXT; 1402 range->we_version_compiled = WIRELESS_EXT;
@@ -1438,8 +1419,7 @@ static int ray_get_range(struct net_device *dev,
1438/* 1419/*
1439 * Wireless Private Handler : set framing mode 1420 * Wireless Private Handler : set framing mode
1440 */ 1421 */
1441static int ray_set_framing(struct net_device *dev, 1422static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1442 struct iw_request_info *info,
1443 union iwreq_data *wrqu, char *extra) 1423 union iwreq_data *wrqu, char *extra)
1444{ 1424{
1445 translate = *(extra); /* Set framing mode */ 1425 translate = *(extra); /* Set framing mode */
@@ -1451,8 +1431,7 @@ static int ray_set_framing(struct net_device *dev,
1451/* 1431/*
1452 * Wireless Private Handler : get framing mode 1432 * Wireless Private Handler : get framing mode
1453 */ 1433 */
1454static int ray_get_framing(struct net_device *dev, 1434static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1455 struct iw_request_info *info,
1456 union iwreq_data *wrqu, char *extra) 1435 union iwreq_data *wrqu, char *extra)
1457{ 1436{
1458 *(extra) = translate; 1437 *(extra) = translate;
@@ -1464,8 +1443,7 @@ static int ray_get_framing(struct net_device *dev,
1464/* 1443/*
1465 * Wireless Private Handler : get country 1444 * Wireless Private Handler : get country
1466 */ 1445 */
1467static int ray_get_country(struct net_device *dev, 1446static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1468 struct iw_request_info *info,
1469 union iwreq_data *wrqu, char *extra) 1447 union iwreq_data *wrqu, char *extra)
1470{ 1448{
1471 *(extra) = country; 1449 *(extra) = country;
@@ -1477,10 +1455,9 @@ static int ray_get_country(struct net_device *dev,
1477/* 1455/*
1478 * Commit handler : called after a bunch of SET operations 1456 * Commit handler : called after a bunch of SET operations
1479 */ 1457 */
1480static int ray_commit(struct net_device *dev, struct iw_request_info *info, /* NULL */ 1458static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1481 void *zwrq, /* NULL */ 1459 union iwreq_data *wrqu, char *extra)
1482 char *extra) 1460{
1483{ /* NULL */
1484 return 0; 1461 return 0;
1485} 1462}
1486 1463
@@ -1521,28 +1498,28 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1521 */ 1498 */
1522 1499
1523static const iw_handler ray_handler[] = { 1500static const iw_handler ray_handler[] = {
1524 [SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit, 1501 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1525 [SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name, 1502 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1526 [SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq, 1503 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1527 [SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq, 1504 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1528 [SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode, 1505 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1529 [SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode, 1506 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1530 [SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range, 1507 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1531#ifdef WIRELESS_SPY 1508#ifdef WIRELESS_SPY
1532 [SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, 1509 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1533 [SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy, 1510 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1534 [SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy, 1511 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1535 [SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy, 1512 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1536#endif /* WIRELESS_SPY */ 1513#endif /* WIRELESS_SPY */
1537 [SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap, 1514 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1538 [SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid, 1515 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1539 [SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid, 1516 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1540 [SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate, 1517 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1541 [SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate, 1518 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1542 [SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts, 1519 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1543 [SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts, 1520 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1544 [SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag, 1521 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1545 [SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag, 1522 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1546}; 1523};
1547 1524
1548#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ 1525#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
@@ -1550,9 +1527,9 @@ static const iw_handler ray_handler[] = {
1550#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ 1527#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
1551 1528
1552static const iw_handler ray_private_handler[] = { 1529static const iw_handler ray_private_handler[] = {
1553 [0] = (iw_handler) ray_set_framing, 1530 [0] = ray_set_framing,
1554 [1] = (iw_handler) ray_get_framing, 1531 [1] = ray_get_framing,
1555 [3] = (iw_handler) ray_get_country, 1532 [3] = ray_get_country,
1556}; 1533};
1557 1534
1558static const struct iw_priv_args ray_private_args[] = { 1535static const struct iw_priv_args ray_private_args[] = {
@@ -1636,7 +1613,6 @@ static int ray_dev_close(struct net_device *dev)
1636static void ray_reset(struct net_device *dev) 1613static void ray_reset(struct net_device *dev)
1637{ 1614{
1638 pr_debug("ray_reset entered\n"); 1615 pr_debug("ray_reset entered\n");
1639 return;
1640} 1616}
1641 1617
1642/*===========================================================================*/ 1618/*===========================================================================*/
@@ -1883,17 +1859,17 @@ static void ray_update_multi_list(struct net_device *dev, int all)
1883 writeb(0xff, &pccs->var); 1859 writeb(0xff, &pccs->var);
1884 local->num_multi = 0xff; 1860 local->num_multi = 0xff;
1885 } else { 1861 } else {
1886 struct dev_mc_list *dmi; 1862 struct netdev_hw_addr *ha;
1887 int i = 0; 1863 int i = 0;
1888 1864
1889 /* Copy the kernel's list of MC addresses to card */ 1865 /* Copy the kernel's list of MC addresses to card */
1890 netdev_for_each_mc_addr(dmi, dev) { 1866 netdev_for_each_mc_addr(ha, dev) {
1891 memcpy_toio(p, dmi->dmi_addr, ETH_ALEN); 1867 memcpy_toio(p, ha->addr, ETH_ALEN);
1892 dev_dbg(&link->dev, 1868 dev_dbg(&link->dev,
1893 "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n", 1869 "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
1894 dmi->dmi_addr[0], dmi->dmi_addr[1], 1870 ha->addr[0], ha->addr[1],
1895 dmi->dmi_addr[2], dmi->dmi_addr[3], 1871 ha->addr[2], ha->addr[3],
1896 dmi->dmi_addr[4], dmi->dmi_addr[5]); 1872 ha->addr[4], ha->addr[5]);
1897 p += ETH_ALEN; 1873 p += ETH_ALEN;
1898 i++; 1874 i++;
1899 } 1875 }
@@ -2242,7 +2218,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2242 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + 2218 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2243 FCS_LEN)) { 2219 FCS_LEN)) {
2244 pr_debug( 2220 pr_debug(
2245 "ray_cs invalid packet length %d received \n", 2221 "ray_cs invalid packet length %d received\n",
2246 rx_len); 2222 rx_len);
2247 return; 2223 return;
2248 } 2224 }
@@ -2253,7 +2229,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
2253 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + 2229 (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
2254 FCS_LEN)) { 2230 FCS_LEN)) {
2255 pr_debug( 2231 pr_debug(
2256 "ray_cs invalid packet length %d received \n", 2232 "ray_cs invalid packet length %d received\n",
2257 rx_len); 2233 rx_len);
2258 return; 2234 return;
2259 } 2235 }
@@ -2761,11 +2737,11 @@ static int ray_cs_proc_show(struct seq_file *m, void *v)
2761 seq_printf(m, "Hop dwell = %d Kus\n", 2737 seq_printf(m, "Hop dwell = %d Kus\n",
2762 pfh->dwell_time[0] + 2738 pfh->dwell_time[0] +
2763 256 * pfh->dwell_time[1]); 2739 256 * pfh->dwell_time[1]);
2764 seq_printf(m, "Hop set = %d \n", 2740 seq_printf(m, "Hop set = %d\n",
2765 pfh->hop_set); 2741 pfh->hop_set);
2766 seq_printf(m, "Hop pattern = %d \n", 2742 seq_printf(m, "Hop pattern = %d\n",
2767 pfh->hop_pattern); 2743 pfh->hop_pattern);
2768 seq_printf(m, "Hop index = %d \n", 2744 seq_printf(m, "Hop index = %d\n",
2769 pfh->hop_index); 2745 pfh->hop_index);
2770 p += p[1] + 2; 2746 p += p[1] + 2;
2771 } else { 2747 } else {
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 1de5b22d3efe..2d2890878dea 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -118,6 +118,7 @@ MODULE_PARM_DESC(workaround_interval,
118#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) 118#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
119#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) 119#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
120#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) 120#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
121#define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122)
121#define OID_802_11_PMKID cpu_to_le32(0x0d010123) 122#define OID_802_11_PMKID cpu_to_le32(0x0d010123)
122#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) 123#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
123#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) 124#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
@@ -359,6 +360,30 @@ struct ndis_80211_assoc_info {
359 __le32 offset_resp_ies; 360 __le32 offset_resp_ies;
360} __attribute__((packed)); 361} __attribute__((packed));
361 362
363struct ndis_80211_auth_encr_pair {
364 __le32 auth_mode;
365 __le32 encr_mode;
366} __attribute__((packed));
367
368struct ndis_80211_capability {
369 __le32 length;
370 __le32 version;
371 __le32 num_pmkids;
372 __le32 num_auth_encr_pair;
373 struct ndis_80211_auth_encr_pair auth_encr_pair[0];
374} __attribute__((packed));
375
376struct ndis_80211_bssid_info {
377 u8 bssid[6];
378 u8 pmkid[16];
379};
380
381struct ndis_80211_pmkid {
382 __le32 length;
383 __le32 bssid_info_count;
384 struct ndis_80211_bssid_info bssid_info[0];
385};
386
362/* 387/*
363 * private data 388 * private data
364 */ 389 */
@@ -477,13 +502,7 @@ struct rndis_wlan_private {
477 /* encryption stuff */ 502 /* encryption stuff */
478 int encr_tx_key_index; 503 int encr_tx_key_index;
479 struct rndis_wlan_encr_key encr_keys[4]; 504 struct rndis_wlan_encr_key encr_keys[4];
480 enum nl80211_auth_type wpa_auth_type;
481 int wpa_version; 505 int wpa_version;
482 int wpa_keymgmt;
483 int wpa_ie_len;
484 u8 *wpa_ie;
485 int wpa_cipher_pair;
486 int wpa_cipher_group;
487 506
488 u8 command_buffer[COMMAND_BUFFER_SIZE]; 507 u8 command_buffer[COMMAND_BUFFER_SIZE];
489}; 508};
@@ -516,7 +535,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
516 535
517static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev); 536static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
518 537
519static int rndis_set_channel(struct wiphy *wiphy, 538static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
520 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); 539 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
521 540
522static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, 541static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
@@ -535,6 +554,14 @@ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
535static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, 554static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
536 int idx, u8 *mac, struct station_info *sinfo); 555 int idx, u8 *mac, struct station_info *sinfo);
537 556
557static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
558 struct cfg80211_pmksa *pmksa);
559
560static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
561 struct cfg80211_pmksa *pmksa);
562
563static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev);
564
538static struct cfg80211_ops rndis_config_ops = { 565static struct cfg80211_ops rndis_config_ops = {
539 .change_virtual_intf = rndis_change_virtual_intf, 566 .change_virtual_intf = rndis_change_virtual_intf,
540 .scan = rndis_scan, 567 .scan = rndis_scan,
@@ -551,6 +578,9 @@ static struct cfg80211_ops rndis_config_ops = {
551 .set_default_key = rndis_set_default_key, 578 .set_default_key = rndis_set_default_key,
552 .get_station = rndis_get_station, 579 .get_station = rndis_get_station,
553 .dump_station = rndis_dump_station, 580 .dump_station = rndis_dump_station,
581 .set_pmksa = rndis_set_pmksa,
582 .del_pmksa = rndis_del_pmksa,
583 .flush_pmksa = rndis_flush_pmksa,
554}; 584};
555 585
556static void *rndis_wiphy_privid = &rndis_wiphy_privid; 586static void *rndis_wiphy_privid = &rndis_wiphy_privid;
@@ -705,6 +735,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
705 struct rndis_query_c *get_c; 735 struct rndis_query_c *get_c;
706 } u; 736 } u;
707 int ret, buflen; 737 int ret, buflen;
738 int resplen, respoffs, copylen;
708 739
709 buflen = *len + sizeof(*u.get); 740 buflen = *len + sizeof(*u.get);
710 if (buflen < CONTROL_BUFFER_SIZE) 741 if (buflen < CONTROL_BUFFER_SIZE)
@@ -734,11 +765,34 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
734 le32_to_cpu(u.get_c->status)); 765 le32_to_cpu(u.get_c->status));
735 766
736 if (ret == 0) { 767 if (ret == 0) {
737 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); 768 resplen = le32_to_cpu(u.get_c->len);
769 respoffs = le32_to_cpu(u.get_c->offset) + 8;
738 770
739 ret = le32_to_cpu(u.get_c->len); 771 if (respoffs > buflen) {
740 if (ret > *len) 772 /* Device returned data offset outside buffer, error. */
741 *len = ret; 773 netdev_dbg(dev->net, "%s(%s): received invalid "
774 "data offset: %d > %d\n", __func__,
775 oid_to_string(oid), respoffs, buflen);
776
777 ret = -EINVAL;
778 goto exit_unlock;
779 }
780
781 if ((resplen + respoffs) > buflen) {
782 /* Device would have returned more data if buffer would
783 * have been big enough. Copy just the bits that we got.
784 */
785 copylen = buflen - respoffs;
786 } else {
787 copylen = resplen;
788 }
789
790 if (copylen > *len)
791 copylen = *len;
792
793 memcpy(data, u.buf + respoffs, copylen);
794
795 *len = resplen;
742 796
743 ret = rndis_error_status(u.get_c->status); 797 ret = rndis_error_status(u.get_c->status);
744 if (ret < 0) 798 if (ret < 0)
@@ -747,6 +801,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
747 le32_to_cpu(u.get_c->status), ret); 801 le32_to_cpu(u.get_c->status), ret);
748 } 802 }
749 803
804exit_unlock:
750 mutex_unlock(&priv->command_lock); 805 mutex_unlock(&priv->command_lock);
751 806
752 if (u.buf != priv->command_buffer) 807 if (u.buf != priv->command_buffer)
@@ -1092,8 +1147,6 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
1092 } 1147 }
1093 1148
1094 priv->wpa_version = wpa_version; 1149 priv->wpa_version = wpa_version;
1095 priv->wpa_auth_type = auth_type;
1096 priv->wpa_keymgmt = keymgmt;
1097 1150
1098 return 0; 1151 return 0;
1099} 1152}
@@ -1118,7 +1171,6 @@ static int set_priv_filter(struct usbnet *usbdev)
1118 1171
1119static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) 1172static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1120{ 1173{
1121 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1122 __le32 tmp; 1174 __le32 tmp;
1123 int encr_mode, ret; 1175 int encr_mode, ret;
1124 1176
@@ -1147,8 +1199,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
1147 return ret; 1199 return ret;
1148 } 1200 }
1149 1201
1150 priv->wpa_cipher_pair = pairwise;
1151 priv->wpa_cipher_group = groupwise;
1152 return 0; 1202 return 0;
1153} 1203}
1154 1204
@@ -1496,7 +1546,7 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
1496static void set_multicast_list(struct usbnet *usbdev) 1546static void set_multicast_list(struct usbnet *usbdev)
1497{ 1547{
1498 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1548 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1499 struct dev_mc_list *mclist; 1549 struct netdev_hw_addr *ha;
1500 __le32 filter, basefilter; 1550 __le32 filter, basefilter;
1501 int ret; 1551 int ret;
1502 char *mc_addrs = NULL; 1552 char *mc_addrs = NULL;
@@ -1535,9 +1585,9 @@ static void set_multicast_list(struct usbnet *usbdev)
1535 return; 1585 return;
1536 } 1586 }
1537 1587
1538 netdev_for_each_mc_addr(mclist, usbdev->net) 1588 netdev_for_each_mc_addr(ha, usbdev->net)
1539 memcpy(mc_addrs + i++ * ETH_ALEN, 1589 memcpy(mc_addrs + i++ * ETH_ALEN,
1540 mclist->dmi_addr, ETH_ALEN); 1590 ha->addr, ETH_ALEN);
1541 } 1591 }
1542 netif_addr_unlock_bh(usbdev->net); 1592 netif_addr_unlock_bh(usbdev->net);
1543 1593
@@ -1569,6 +1619,194 @@ set_filter:
1569 le32_to_cpu(filter), ret); 1619 le32_to_cpu(filter), ret);
1570} 1620}
1571 1621
1622#ifdef DEBUG
1623static void debug_print_pmkids(struct usbnet *usbdev,
1624 struct ndis_80211_pmkid *pmkids,
1625 const char *func_str)
1626{
1627 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1628 int i, len, count, max_pmkids, entry_len;
1629
1630 max_pmkids = priv->wdev.wiphy->max_num_pmkids;
1631 len = le32_to_cpu(pmkids->length);
1632 count = le32_to_cpu(pmkids->bssid_info_count);
1633
1634 entry_len = (count > 0) ? (len - sizeof(*pmkids)) / count : -1;
1635
1636 netdev_dbg(usbdev->net, "%s(): %d PMKIDs (data len: %d, entry len: "
1637 "%d)\n", func_str, count, len, entry_len);
1638
1639 if (count > max_pmkids)
1640 count = max_pmkids;
1641
1642 for (i = 0; i < count; i++) {
1643 u32 *tmp = (u32 *)pmkids->bssid_info[i].pmkid;
1644
1645 netdev_dbg(usbdev->net, "%s(): bssid: %pM, "
1646 "pmkid: %08X:%08X:%08X:%08X\n",
1647 func_str, pmkids->bssid_info[i].bssid,
1648 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
1649 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
1650 }
1651}
1652#else
1653static void debug_print_pmkids(struct usbnet *usbdev,
1654 struct ndis_80211_pmkid *pmkids,
1655 const char *func_str)
1656{
1657 return;
1658}
1659#endif
1660
1661static struct ndis_80211_pmkid *get_device_pmkids(struct usbnet *usbdev)
1662{
1663 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1664 struct ndis_80211_pmkid *pmkids;
1665 int len, ret, max_pmkids;
1666
1667 max_pmkids = priv->wdev.wiphy->max_num_pmkids;
1668 len = sizeof(*pmkids) + max_pmkids * sizeof(pmkids->bssid_info[0]);
1669
1670 pmkids = kzalloc(len, GFP_KERNEL);
1671 if (!pmkids)
1672 return ERR_PTR(-ENOMEM);
1673
1674 pmkids->length = cpu_to_le32(len);
1675 pmkids->bssid_info_count = cpu_to_le32(max_pmkids);
1676
1677 ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len);
1678 if (ret < 0) {
1679 netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)"
1680 " -> %d\n", __func__, len, max_pmkids, ret);
1681
1682 kfree(pmkids);
1683 return ERR_PTR(ret);
1684 }
1685
1686 if (le32_to_cpu(pmkids->bssid_info_count) > max_pmkids)
1687 pmkids->bssid_info_count = cpu_to_le32(max_pmkids);
1688
1689 debug_print_pmkids(usbdev, pmkids, __func__);
1690
1691 return pmkids;
1692}
1693
1694static int set_device_pmkids(struct usbnet *usbdev,
1695 struct ndis_80211_pmkid *pmkids)
1696{
1697 int ret, len, num_pmkids;
1698
1699 num_pmkids = le32_to_cpu(pmkids->bssid_info_count);
1700 len = sizeof(*pmkids) + num_pmkids * sizeof(pmkids->bssid_info[0]);
1701 pmkids->length = cpu_to_le32(len);
1702
1703 debug_print_pmkids(usbdev, pmkids, __func__);
1704
1705 ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids,
1706 le32_to_cpu(pmkids->length));
1707 if (ret < 0) {
1708 netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d"
1709 "\n", __func__, len, num_pmkids, ret);
1710 }
1711
1712 kfree(pmkids);
1713 return ret;
1714}
1715
1716static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
1717 struct ndis_80211_pmkid *pmkids,
1718 struct cfg80211_pmksa *pmksa,
1719 int max_pmkids)
1720{
1721 int i, len, count, newlen, err;
1722
1723 len = le32_to_cpu(pmkids->length);
1724 count = le32_to_cpu(pmkids->bssid_info_count);
1725
1726 if (count > max_pmkids)
1727 count = max_pmkids;
1728
1729 for (i = 0; i < count; i++)
1730 if (!compare_ether_addr(pmkids->bssid_info[i].bssid,
1731 pmksa->bssid))
1732 break;
1733
1734 /* pmkid not found */
1735 if (i == count) {
1736 netdev_dbg(usbdev->net, "%s(): bssid not found (%pM)\n",
1737 __func__, pmksa->bssid);
1738 err = -ENOENT;
1739 goto error;
1740 }
1741
1742 for (; i + 1 < count; i++)
1743 pmkids->bssid_info[i] = pmkids->bssid_info[i + 1];
1744
1745 count--;
1746 newlen = sizeof(*pmkids) + count * sizeof(pmkids->bssid_info[0]);
1747
1748 pmkids->length = cpu_to_le32(newlen);
1749 pmkids->bssid_info_count = cpu_to_le32(count);
1750
1751 return pmkids;
1752error:
1753 kfree(pmkids);
1754 return ERR_PTR(err);
1755}
1756
1757static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
1758 struct ndis_80211_pmkid *pmkids,
1759 struct cfg80211_pmksa *pmksa,
1760 int max_pmkids)
1761{
1762 int i, err, len, count, newlen;
1763
1764 len = le32_to_cpu(pmkids->length);
1765 count = le32_to_cpu(pmkids->bssid_info_count);
1766
1767 if (count > max_pmkids)
1768 count = max_pmkids;
1769
1770 /* update with new pmkid */
1771 for (i = 0; i < count; i++) {
1772 if (compare_ether_addr(pmkids->bssid_info[i].bssid,
1773 pmksa->bssid))
1774 continue;
1775
1776 memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid,
1777 WLAN_PMKID_LEN);
1778
1779 return pmkids;
1780 }
1781
1782 /* out of space, return error */
1783 if (i == max_pmkids) {
1784 netdev_dbg(usbdev->net, "%s(): out of space\n", __func__);
1785 err = -ENOSPC;
1786 goto error;
1787 }
1788
1789 /* add new pmkid */
1790 newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]);
1791
1792 pmkids = krealloc(pmkids, newlen, GFP_KERNEL);
1793 if (!pmkids) {
1794 err = -ENOMEM;
1795 goto error;
1796 }
1797
1798 pmkids->length = cpu_to_le32(newlen);
1799 pmkids->bssid_info_count = cpu_to_le32(count + 1);
1800
1801 memcpy(pmkids->bssid_info[count].bssid, pmksa->bssid, ETH_ALEN);
1802 memcpy(pmkids->bssid_info[count].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
1803
1804 return pmkids;
1805error:
1806 kfree(pmkids);
1807 return ERR_PTR(err);
1808}
1809
1572/* 1810/*
1573 * cfg80211 ops 1811 * cfg80211 ops
1574 */ 1812 */
@@ -2053,7 +2291,7 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2053 return deauthenticate(usbdev); 2291 return deauthenticate(usbdev);
2054} 2292}
2055 2293
2056static int rndis_set_channel(struct wiphy *wiphy, 2294static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
2057 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) 2295 struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
2058{ 2296{
2059 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2297 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
@@ -2179,6 +2417,78 @@ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
2179 return 0; 2417 return 0;
2180} 2418}
2181 2419
2420static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2421 struct cfg80211_pmksa *pmksa)
2422{
2423 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2424 struct usbnet *usbdev = priv->usbdev;
2425 struct ndis_80211_pmkid *pmkids;
2426 u32 *tmp = (u32 *)pmksa->pmkid;
2427
2428 netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__,
2429 pmksa->bssid,
2430 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
2431 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
2432
2433 pmkids = get_device_pmkids(usbdev);
2434 if (IS_ERR(pmkids)) {
2435 /* couldn't read PMKID cache from device */
2436 return PTR_ERR(pmkids);
2437 }
2438
2439 pmkids = update_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids);
2440 if (IS_ERR(pmkids)) {
2441 /* not found, list full, etc */
2442 return PTR_ERR(pmkids);
2443 }
2444
2445 return set_device_pmkids(usbdev, pmkids);
2446}
2447
2448static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
2449 struct cfg80211_pmksa *pmksa)
2450{
2451 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2452 struct usbnet *usbdev = priv->usbdev;
2453 struct ndis_80211_pmkid *pmkids;
2454 u32 *tmp = (u32 *)pmksa->pmkid;
2455
2456 netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__,
2457 pmksa->bssid,
2458 cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]),
2459 cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3]));
2460
2461 pmkids = get_device_pmkids(usbdev);
2462 if (IS_ERR(pmkids)) {
2463 /* Couldn't read PMKID cache from device */
2464 return PTR_ERR(pmkids);
2465 }
2466
2467 pmkids = remove_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids);
2468 if (IS_ERR(pmkids)) {
2469 /* not found, etc */
2470 return PTR_ERR(pmkids);
2471 }
2472
2473 return set_device_pmkids(usbdev, pmkids);
2474}
2475
2476static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
2477{
2478 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2479 struct usbnet *usbdev = priv->usbdev;
2480 struct ndis_80211_pmkid pmkid;
2481
2482 netdev_dbg(usbdev->net, "%s()\n", __func__);
2483
2484 memset(&pmkid, 0, sizeof(pmkid));
2485
2486 pmkid.length = cpu_to_le32(sizeof(pmkid));
2487 pmkid.bssid_info_count = cpu_to_le32(0);
2488
2489 return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
2490}
2491
2182/* 2492/*
2183 * workers, indication handlers, device poller 2493 * workers, indication handlers, device poller
2184 */ 2494 */
@@ -2523,12 +2833,14 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
2523 } 2833 }
2524} 2834}
2525 2835
2526static int rndis_wlan_get_caps(struct usbnet *usbdev) 2836static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
2527{ 2837{
2528 struct { 2838 struct {
2529 __le32 num_items; 2839 __le32 num_items;
2530 __le32 items[8]; 2840 __le32 items[8];
2531 } networks_supported; 2841 } networks_supported;
2842 struct ndis_80211_capability *caps;
2843 u8 caps_buf[sizeof(*caps) + sizeof(caps->auth_encr_pair) * 16];
2532 int len, retval, i, n; 2844 int len, retval, i, n;
2533 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2845 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2534 2846
@@ -2556,6 +2868,21 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev)
2556 } 2868 }
2557 } 2869 }
2558 2870
2871 /* get device 802.11 capabilities, number of PMKIDs */
2872 caps = (struct ndis_80211_capability *)caps_buf;
2873 len = sizeof(caps_buf);
2874 retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len);
2875 if (retval >= 0) {
2876 netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, "
2877 "ver %d, pmkids %d, auth-encr-pairs %d\n",
2878 le32_to_cpu(caps->length),
2879 le32_to_cpu(caps->version),
2880 le32_to_cpu(caps->num_pmkids),
2881 le32_to_cpu(caps->num_auth_encr_pair));
2882 wiphy->max_num_pmkids = le32_to_cpu(caps->num_pmkids);
2883 } else
2884 wiphy->max_num_pmkids = 0;
2885
2559 return retval; 2886 return retval;
2560} 2887}
2561 2888
@@ -2803,7 +3130,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
2803 wiphy->max_scan_ssids = 1; 3130 wiphy->max_scan_ssids = 1;
2804 3131
2805 /* TODO: fill-out band/encr information based on priv->caps */ 3132 /* TODO: fill-out band/encr information based on priv->caps */
2806 rndis_wlan_get_caps(usbdev); 3133 rndis_wlan_get_caps(usbdev, wiphy);
2807 3134
2808 memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); 3135 memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
2809 memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); 3136 memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
@@ -2863,9 +3190,6 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
2863 flush_workqueue(priv->workqueue); 3190 flush_workqueue(priv->workqueue);
2864 destroy_workqueue(priv->workqueue); 3191 destroy_workqueue(priv->workqueue);
2865 3192
2866 if (priv && priv->wpa_ie_len)
2867 kfree(priv->wpa_ie);
2868
2869 rndis_unbind(usbdev, intf); 3193 rndis_unbind(usbdev, intf);
2870 3194
2871 wiphy_unregister(priv->wdev.wiphy); 3195 wiphy_unregister(priv->wdev.wiphy);
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 5239e082cd0f..eea1ef2f502b 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -87,7 +87,7 @@ if RT2800PCI
87 87
88config RT2800PCI_RT30XX 88config RT2800PCI_RT30XX
89 bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" 89 bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"
90 default n 90 default y
91 ---help--- 91 ---help---
92 This adds support for rt30xx wireless chipset family to the 92 This adds support for rt30xx wireless chipset family to the
93 rt2800pci driver. 93 rt2800pci driver.
@@ -156,7 +156,7 @@ if RT2800USB
156 156
157config RT2800USB_RT30XX 157config RT2800USB_RT30XX
158 bool "rt2800usb - Include support for rt30xx (USB) devices" 158 bool "rt2800usb - Include support for rt30xx (USB) devices"
159 default n 159 default y
160 ---help--- 160 ---help---
161 This adds support for rt30xx wireless chipset family to the 161 This adds support for rt30xx wireless chipset family to the
162 rt2800usb driver. 162 rt2800usb driver.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5f5204b82891..4ba7b038928f 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -526,6 +526,10 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
526 526
527 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1); 527 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
528 rt2x00pci_register_write(rt2x00dev, CSR20, reg); 528 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
529 } else {
530 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
531 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
532 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
529 } 533 }
530 534
531 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 535 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
@@ -1003,19 +1007,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1003{ 1007{
1004 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1008 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1005 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; 1009 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
1006 __le32 *txd = skbdesc->desc; 1010 __le32 *txd = entry_priv->desc;
1007 u32 word; 1011 u32 word;
1008 1012
1009 /* 1013 /*
1010 * Start writing the descriptor words. 1014 * Start writing the descriptor words.
1011 */ 1015 */
1012 rt2x00_desc_read(entry_priv->desc, 1, &word); 1016 rt2x00_desc_read(txd, 1, &word);
1013 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1017 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
1014 rt2x00_desc_write(entry_priv->desc, 1, word); 1018 rt2x00_desc_write(txd, 1, word);
1015 1019
1016 rt2x00_desc_read(txd, 2, &word); 1020 rt2x00_desc_read(txd, 2, &word);
1017 rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); 1021 rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, txdesc->length);
1018 rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); 1022 rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, txdesc->length);
1019 rt2x00_desc_write(txd, 2, word); 1023 rt2x00_desc_write(txd, 2, word);
1020 1024
1021 rt2x00_desc_read(txd, 3, &word); 1025 rt2x00_desc_read(txd, 3, &word);
@@ -1036,6 +1040,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1036 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); 1040 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1);
1037 rt2x00_desc_write(txd, 4, word); 1041 rt2x00_desc_write(txd, 4, word);
1038 1042
1043 /*
1044 * Writing TXD word 0 must the last to prevent a race condition with
1045 * the device, whereby the device may take hold of the TXD before we
1046 * finished updating it.
1047 */
1039 rt2x00_desc_read(txd, 0, &word); 1048 rt2x00_desc_read(txd, 0, &word);
1040 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); 1049 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
1041 rt2x00_set_field32(&word, TXD_W0_VALID, 1); 1050 rt2x00_set_field32(&word, TXD_W0_VALID, 1);
@@ -1051,12 +1060,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1051 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, 1060 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
1052 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); 1061 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
1053 rt2x00_desc_write(txd, 0, word); 1062 rt2x00_desc_write(txd, 0, word);
1063
1064 /*
1065 * Register descriptor details in skb frame descriptor.
1066 */
1067 skbdesc->desc = txd;
1068 skbdesc->desc_len = TXD_DESC_SIZE;
1054} 1069}
1055 1070
1056/* 1071/*
1057 * TX data initialization 1072 * TX data initialization
1058 */ 1073 */
1059static void rt2400pci_write_beacon(struct queue_entry *entry) 1074static void rt2400pci_write_beacon(struct queue_entry *entry,
1075 struct txentry_desc *txdesc)
1060{ 1076{
1061 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1077 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1062 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1078 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
@@ -1072,20 +1088,19 @@ static void rt2400pci_write_beacon(struct queue_entry *entry)
1072 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); 1088 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
1073 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1089 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1074 1090
1075 /*
1076 * Replace rt2x00lib allocated descriptor with the
1077 * pointer to the _real_ hardware descriptor.
1078 * After that, map the beacon to DMA and update the
1079 * descriptor.
1080 */
1081 memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
1082 skbdesc->desc = entry_priv->desc;
1083
1084 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1091 rt2x00queue_map_txskb(rt2x00dev, entry->skb);
1085 1092
1086 rt2x00_desc_read(entry_priv->desc, 1, &word); 1093 rt2x00_desc_read(entry_priv->desc, 1, &word);
1087 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1094 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
1088 rt2x00_desc_write(entry_priv->desc, 1, word); 1095 rt2x00_desc_write(entry_priv->desc, 1, word);
1096
1097 /*
1098 * Enable beaconing again.
1099 */
1100 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1101 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1102 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1103 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1089} 1104}
1090 1105
1091static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 1106static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
@@ -1093,17 +1108,6 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1093{ 1108{
1094 u32 reg; 1109 u32 reg;
1095 1110
1096 if (queue == QID_BEACON) {
1097 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
1098 if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
1099 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1100 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1101 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1102 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1103 }
1104 return;
1105 }
1106
1107 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg); 1111 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1108 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); 1112 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
1109 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK)); 1113 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 2a73f593aab0..89d132d4af12 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -574,6 +574,10 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
574 574
575 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1); 575 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
576 rt2x00pci_register_write(rt2x00dev, CSR20, reg); 576 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
577 } else {
578 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
579 rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
580 rt2x00pci_register_write(rt2x00dev, CSR20, reg);
577 } 581 }
578 582
579 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 583 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
@@ -1161,15 +1165,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1161{ 1165{
1162 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1166 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1163 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; 1167 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
1164 __le32 *txd = skbdesc->desc; 1168 __le32 *txd = entry_priv->desc;
1165 u32 word; 1169 u32 word;
1166 1170
1167 /* 1171 /*
1168 * Start writing the descriptor words. 1172 * Start writing the descriptor words.
1169 */ 1173 */
1170 rt2x00_desc_read(entry_priv->desc, 1, &word); 1174 rt2x00_desc_read(txd, 1, &word);
1171 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1175 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
1172 rt2x00_desc_write(entry_priv->desc, 1, word); 1176 rt2x00_desc_write(txd, 1, word);
1173 1177
1174 rt2x00_desc_read(txd, 2, &word); 1178 rt2x00_desc_read(txd, 2, &word);
1175 rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); 1179 rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
@@ -1190,6 +1194,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1190 test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); 1194 test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
1191 rt2x00_desc_write(txd, 10, word); 1195 rt2x00_desc_write(txd, 10, word);
1192 1196
1197 /*
1198 * Writing TXD word 0 must the last to prevent a race condition with
1199 * the device, whereby the device may take hold of the TXD before we
1200 * finished updating it.
1201 */
1193 rt2x00_desc_read(txd, 0, &word); 1202 rt2x00_desc_read(txd, 0, &word);
1194 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); 1203 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
1195 rt2x00_set_field32(&word, TXD_W0_VALID, 1); 1204 rt2x00_set_field32(&word, TXD_W0_VALID, 1);
@@ -1205,15 +1214,22 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1205 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); 1214 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1206 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, 1215 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
1207 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); 1216 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
1208 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); 1217 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
1209 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); 1218 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
1210 rt2x00_desc_write(txd, 0, word); 1219 rt2x00_desc_write(txd, 0, word);
1220
1221 /*
1222 * Register descriptor details in skb frame descriptor.
1223 */
1224 skbdesc->desc = txd;
1225 skbdesc->desc_len = TXD_DESC_SIZE;
1211} 1226}
1212 1227
1213/* 1228/*
1214 * TX data initialization 1229 * TX data initialization
1215 */ 1230 */
1216static void rt2500pci_write_beacon(struct queue_entry *entry) 1231static void rt2500pci_write_beacon(struct queue_entry *entry,
1232 struct txentry_desc *txdesc)
1217{ 1233{
1218 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1234 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1219 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1235 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
@@ -1229,20 +1245,19 @@ static void rt2500pci_write_beacon(struct queue_entry *entry)
1229 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); 1245 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
1230 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1246 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1231 1247
1232 /*
1233 * Replace rt2x00lib allocated descriptor with the
1234 * pointer to the _real_ hardware descriptor.
1235 * After that, map the beacon to DMA and update the
1236 * descriptor.
1237 */
1238 memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
1239 skbdesc->desc = entry_priv->desc;
1240
1241 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1248 rt2x00queue_map_txskb(rt2x00dev, entry->skb);
1242 1249
1243 rt2x00_desc_read(entry_priv->desc, 1, &word); 1250 rt2x00_desc_read(entry_priv->desc, 1, &word);
1244 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1251 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
1245 rt2x00_desc_write(entry_priv->desc, 1, word); 1252 rt2x00_desc_write(entry_priv->desc, 1, word);
1253
1254 /*
1255 * Enable beaconing again.
1256 */
1257 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1258 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1259 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1260 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1246} 1261}
1247 1262
1248static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 1263static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
@@ -1250,17 +1265,6 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1250{ 1265{
1251 u32 reg; 1266 u32 reg;
1252 1267
1253 if (queue == QID_BEACON) {
1254 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
1255 if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
1256 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1257 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1258 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1259 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1260 }
1261 return;
1262 }
1263
1264 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg); 1268 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1265 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); 1269 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
1266 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK)); 1270 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 8ebb705fe106..9ae96a626e6d 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -649,6 +649,10 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
649 649
650 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1); 650 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1);
651 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); 651 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
652 } else {
653 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
654 rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 0);
655 rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
652 } 656 }
653 657
654 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 658 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
@@ -1030,12 +1034,30 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1030 struct txentry_desc *txdesc) 1034 struct txentry_desc *txdesc)
1031{ 1035{
1032 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1036 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1033 __le32 *txd = skbdesc->desc; 1037 __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
1034 u32 word; 1038 u32 word;
1035 1039
1036 /* 1040 /*
1037 * Start writing the descriptor words. 1041 * Start writing the descriptor words.
1038 */ 1042 */
1043 rt2x00_desc_read(txd, 0, &word);
1044 rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit);
1045 rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
1046 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
1047 rt2x00_set_field32(&word, TXD_W0_ACK,
1048 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
1049 rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
1050 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
1051 rt2x00_set_field32(&word, TXD_W0_OFDM,
1052 (txdesc->rate_mode == RATE_MODE_OFDM));
1053 rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
1054 test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
1055 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1056 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
1057 rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher);
1058 rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx);
1059 rt2x00_desc_write(txd, 0, word);
1060
1039 rt2x00_desc_read(txd, 1, &word); 1061 rt2x00_desc_read(txd, 1, &word);
1040 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); 1062 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
1041 rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); 1063 rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs);
@@ -1055,23 +1077,11 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1055 _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); 1077 _rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
1056 } 1078 }
1057 1079
1058 rt2x00_desc_read(txd, 0, &word); 1080 /*
1059 rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); 1081 * Register descriptor details in skb frame descriptor.
1060 rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, 1082 */
1061 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); 1083 skbdesc->desc = txd;
1062 rt2x00_set_field32(&word, TXD_W0_ACK, 1084 skbdesc->desc_len = TXD_DESC_SIZE;
1063 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
1064 rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
1065 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
1066 rt2x00_set_field32(&word, TXD_W0_OFDM,
1067 (txdesc->rate_mode == RATE_MODE_OFDM));
1068 rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
1069 test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
1070 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1071 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
1072 rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher);
1073 rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx);
1074 rt2x00_desc_write(txd, 0, word);
1075} 1085}
1076 1086
1077/* 1087/*
@@ -1079,22 +1089,15 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1079 */ 1089 */
1080static void rt2500usb_beacondone(struct urb *urb); 1090static void rt2500usb_beacondone(struct urb *urb);
1081 1091
1082static void rt2500usb_write_beacon(struct queue_entry *entry) 1092static void rt2500usb_write_beacon(struct queue_entry *entry,
1093 struct txentry_desc *txdesc)
1083{ 1094{
1084 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1095 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1085 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 1096 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
1086 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; 1097 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
1087 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1088 int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint); 1098 int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint);
1089 int length; 1099 int length;
1090 u16 reg; 1100 u16 reg, reg0;
1091
1092 /*
1093 * Add the descriptor in front of the skb.
1094 */
1095 skb_push(entry->skb, entry->queue->desc_size);
1096 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
1097 skbdesc->desc = entry->skb->data;
1098 1101
1099 /* 1102 /*
1100 * Disable beaconing while we are reloading the beacon data, 1103 * Disable beaconing while we are reloading the beacon data,
@@ -1105,6 +1108,11 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1105 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); 1108 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1106 1109
1107 /* 1110 /*
1111 * Take the descriptor in front of the skb into account.
1112 */
1113 skb_push(entry->skb, TXD_DESC_SIZE);
1114
1115 /*
1108 * USB devices cannot blindly pass the skb->len as the 1116 * USB devices cannot blindly pass the skb->len as the
1109 * length of the data to usb_fill_bulk_urb. Pass the skb 1117 * length of the data to usb_fill_bulk_urb. Pass the skb
1110 * to the driver to determine what the length should be. 1118 * to the driver to determine what the length should be.
@@ -1129,6 +1137,26 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1129 * Send out the guardian byte. 1137 * Send out the guardian byte.
1130 */ 1138 */
1131 usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); 1139 usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
1140
1141 /*
1142 * Enable beaconing again.
1143 */
1144 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
1145 rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
1146 reg0 = reg;
1147 rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
1148 /*
1149 * Beacon generation will fail initially.
1150 * To prevent this we need to change the TXRX_CSR19
1151 * register several times (reg0 is the same as reg
1152 * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
1153 * and 1 in reg).
1154 */
1155 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1156 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
1157 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1158 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
1159 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1132} 1160}
1133 1161
1134static int rt2500usb_get_tx_data_len(struct queue_entry *entry) 1162static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
@@ -1145,37 +1173,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
1145 return length; 1173 return length;
1146} 1174}
1147 1175
1148static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1149 const enum data_queue_qid queue)
1150{
1151 u16 reg, reg0;
1152
1153 if (queue != QID_BEACON) {
1154 rt2x00usb_kick_tx_queue(rt2x00dev, queue);
1155 return;
1156 }
1157
1158 rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
1159 if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
1160 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
1161 rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
1162 reg0 = reg;
1163 rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
1164 /*
1165 * Beacon generation will fail initially.
1166 * To prevent this we need to change the TXRX_CSR19
1167 * register several times (reg0 is the same as reg
1168 * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
1169 * and 1 in reg).
1170 */
1171 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1172 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
1173 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1174 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
1175 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1176 }
1177}
1178
1179/* 1176/*
1180 * RX control handlers 1177 * RX control handlers
1181 */ 1178 */
@@ -1210,11 +1207,9 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
1210 if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) 1207 if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
1211 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; 1208 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
1212 1209
1213 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 1210 rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER);
1214 rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER); 1211 if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
1215 if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) 1212 rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY;
1216 rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY;
1217 }
1218 1213
1219 if (rxdesc->cipher != CIPHER_NONE) { 1214 if (rxdesc->cipher != CIPHER_NONE) {
1220 _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); 1215 _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
@@ -1644,11 +1639,6 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1644 unsigned int i; 1639 unsigned int i;
1645 1640
1646 /* 1641 /*
1647 * Disable powersaving as default.
1648 */
1649 rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
1650
1651 /*
1652 * Initialize all hw fields. 1642 * Initialize all hw fields.
1653 */ 1643 */
1654 rt2x00dev->hw->flags = 1644 rt2x00dev->hw->flags =
@@ -1781,7 +1771,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1781 .write_tx_data = rt2x00usb_write_tx_data, 1771 .write_tx_data = rt2x00usb_write_tx_data,
1782 .write_beacon = rt2500usb_write_beacon, 1772 .write_beacon = rt2500usb_write_beacon,
1783 .get_tx_data_len = rt2500usb_get_tx_data_len, 1773 .get_tx_data_len = rt2500usb_get_tx_data_len,
1784 .kick_tx_queue = rt2500usb_kick_tx_queue, 1774 .kick_tx_queue = rt2x00usb_kick_tx_queue,
1785 .kill_tx_queue = rt2x00usb_kill_tx_queue, 1775 .kill_tx_queue = rt2x00usb_kill_tx_queue,
1786 .fill_rxdone = rt2500usb_fill_rxdone, 1776 .fill_rxdone = rt2500usb_fill_rxdone,
1787 .config_shared_key = rt2500usb_config_key, 1777 .config_shared_key = rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 74c0433dba37..2aa03751c341 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -56,15 +56,20 @@
56#define RF3021 0x0007 56#define RF3021 0x0007
57#define RF3022 0x0008 57#define RF3022 0x0008
58#define RF3052 0x0009 58#define RF3052 0x0009
59#define RF3320 0x000b
59 60
60/* 61/*
61 * Chipset version. 62 * Chipset revisions.
62 */ 63 */
63#define RT2860C_VERSION 0x0100 64#define REV_RT2860C 0x0100
64#define RT2860D_VERSION 0x0101 65#define REV_RT2860D 0x0101
65#define RT2880E_VERSION 0x0200 66#define REV_RT2870D 0x0101
66#define RT2883_VERSION 0x0300 67#define REV_RT2872E 0x0200
67#define RT3070_VERSION 0x0200 68#define REV_RT3070E 0x0200
69#define REV_RT3070F 0x0201
70#define REV_RT3071E 0x0211
71#define REV_RT3090E 0x0211
72#define REV_RT3390E 0x0211
68 73
69/* 74/*
70 * Signal information. 75 * Signal information.
@@ -90,13 +95,19 @@
90#define NUM_TX_QUEUES 4 95#define NUM_TX_QUEUES 4
91 96
92/* 97/*
93 * USB registers. 98 * Registers.
94 */ 99 */
95 100
96/* 101/*
102 * OPT_14: Unknown register used by rt3xxx devices.
103 */
104#define OPT_14_CSR 0x0114
105#define OPT_14_CSR_BIT0 FIELD32(0x00000001)
106
107/*
97 * INT_SOURCE_CSR: Interrupt source register. 108 * INT_SOURCE_CSR: Interrupt source register.
98 * Write one to clear corresponding bit. 109 * Write one to clear corresponding bit.
99 * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c 110 * TX_FIFO_STATUS: FIFO Statistics is full, sw should read TX_STA_FIFO
100 */ 111 */
101#define INT_SOURCE_CSR 0x0200 112#define INT_SOURCE_CSR 0x0200
102#define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001) 113#define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001)
@@ -398,6 +409,31 @@
398#define EFUSE_DATA3 0x059c 409#define EFUSE_DATA3 0x059c
399 410
400/* 411/*
412 * LDO_CFG0
413 */
414#define LDO_CFG0 0x05d4
415#define LDO_CFG0_DELAY3 FIELD32(0x000000ff)
416#define LDO_CFG0_DELAY2 FIELD32(0x0000ff00)
417#define LDO_CFG0_DELAY1 FIELD32(0x00ff0000)
418#define LDO_CFG0_BGSEL FIELD32(0x03000000)
419#define LDO_CFG0_LDO_CORE_VLEVEL FIELD32(0x1c000000)
420#define LD0_CFG0_LDO25_LEVEL FIELD32(0x60000000)
421#define LDO_CFG0_LDO25_LARGEA FIELD32(0x80000000)
422
423/*
424 * GPIO_SWITCH
425 */
426#define GPIO_SWITCH 0x05dc
427#define GPIO_SWITCH_0 FIELD32(0x00000001)
428#define GPIO_SWITCH_1 FIELD32(0x00000002)
429#define GPIO_SWITCH_2 FIELD32(0x00000004)
430#define GPIO_SWITCH_3 FIELD32(0x00000008)
431#define GPIO_SWITCH_4 FIELD32(0x00000010)
432#define GPIO_SWITCH_5 FIELD32(0x00000020)
433#define GPIO_SWITCH_6 FIELD32(0x00000040)
434#define GPIO_SWITCH_7 FIELD32(0x00000080)
435
436/*
401 * MAC Control/Status Registers(CSR). 437 * MAC Control/Status Registers(CSR).
402 * Some values are set in TU, whereas 1 TU == 1024 us. 438 * Some values are set in TU, whereas 1 TU == 1024 us.
403 */ 439 */
@@ -809,7 +845,7 @@
809 * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz 845 * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
810 */ 846 */
811#define TX_BAND_CFG 0x132c 847#define TX_BAND_CFG 0x132c
812#define TX_BAND_CFG_HT40_PLUS FIELD32(0x00000001) 848#define TX_BAND_CFG_HT40_MINUS FIELD32(0x00000001)
813#define TX_BAND_CFG_A FIELD32(0x00000002) 849#define TX_BAND_CFG_A FIELD32(0x00000002)
814#define TX_BAND_CFG_BG FIELD32(0x00000004) 850#define TX_BAND_CFG_BG FIELD32(0x00000004)
815 851
@@ -1483,7 +1519,7 @@ struct mac_iveiv_entry {
1483 * BBP 3: RX Antenna 1519 * BBP 3: RX Antenna
1484 */ 1520 */
1485#define BBP3_RX_ANTENNA FIELD8(0x18) 1521#define BBP3_RX_ANTENNA FIELD8(0x18)
1486#define BBP3_HT40_PLUS FIELD8(0x20) 1522#define BBP3_HT40_MINUS FIELD8(0x20)
1487 1523
1488/* 1524/*
1489 * BBP 4: Bandwidth 1525 * BBP 4: Bandwidth
@@ -1492,14 +1528,32 @@ struct mac_iveiv_entry {
1492#define BBP4_BANDWIDTH FIELD8(0x18) 1528#define BBP4_BANDWIDTH FIELD8(0x18)
1493 1529
1494/* 1530/*
1531 * BBP 138: Unknown
1532 */
1533#define BBP138_RX_ADC1 FIELD8(0x02)
1534#define BBP138_RX_ADC2 FIELD8(0x04)
1535#define BBP138_TX_DAC1 FIELD8(0x20)
1536#define BBP138_TX_DAC2 FIELD8(0x40)
1537
1538/*
1495 * RFCSR registers 1539 * RFCSR registers
1496 * The wordsize of the RFCSR is 8 bits. 1540 * The wordsize of the RFCSR is 8 bits.
1497 */ 1541 */
1498 1542
1499/* 1543/*
1544 * RFCSR 1:
1545 */
1546#define RFCSR1_RF_BLOCK_EN FIELD8(0x01)
1547#define RFCSR1_RX0_PD FIELD8(0x04)
1548#define RFCSR1_TX0_PD FIELD8(0x08)
1549#define RFCSR1_RX1_PD FIELD8(0x10)
1550#define RFCSR1_TX1_PD FIELD8(0x20)
1551
1552/*
1500 * RFCSR 6: 1553 * RFCSR 6:
1501 */ 1554 */
1502#define RFCSR6_R FIELD8(0x03) 1555#define RFCSR6_R1 FIELD8(0x03)
1556#define RFCSR6_R2 FIELD8(0x40)
1503 1557
1504/* 1558/*
1505 * RFCSR 7: 1559 * RFCSR 7:
@@ -1512,6 +1566,33 @@ struct mac_iveiv_entry {
1512#define RFCSR12_TX_POWER FIELD8(0x1f) 1566#define RFCSR12_TX_POWER FIELD8(0x1f)
1513 1567
1514/* 1568/*
1569 * RFCSR 13:
1570 */
1571#define RFCSR13_TX_POWER FIELD8(0x1f)
1572
1573/*
1574 * RFCSR 15:
1575 */
1576#define RFCSR15_TX_LO2_EN FIELD8(0x08)
1577
1578/*
1579 * RFCSR 17:
1580 */
1581#define RFCSR17_TXMIXER_GAIN FIELD8(0x07)
1582#define RFCSR17_TX_LO1_EN FIELD8(0x08)
1583#define RFCSR17_R FIELD8(0x20)
1584
1585/*
1586 * RFCSR 20:
1587 */
1588#define RFCSR20_RX_LO1_EN FIELD8(0x08)
1589
1590/*
1591 * RFCSR 21:
1592 */
1593#define RFCSR21_RX_LO2_EN FIELD8(0x08)
1594
1595/*
1515 * RFCSR 22: 1596 * RFCSR 22:
1516 */ 1597 */
1517#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01) 1598#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
@@ -1522,6 +1603,14 @@ struct mac_iveiv_entry {
1522#define RFCSR23_FREQ_OFFSET FIELD8(0x7f) 1603#define RFCSR23_FREQ_OFFSET FIELD8(0x7f)
1523 1604
1524/* 1605/*
1606 * RFCSR 27:
1607 */
1608#define RFCSR27_R1 FIELD8(0x03)
1609#define RFCSR27_R2 FIELD8(0x04)
1610#define RFCSR27_R3 FIELD8(0x30)
1611#define RFCSR27_R4 FIELD8(0x40)
1612
1613/*
1525 * RFCSR 30: 1614 * RFCSR 30:
1526 */ 1615 */
1527#define RFCSR30_RF_CALIBRATION FIELD8(0x80) 1616#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
@@ -1603,6 +1692,8 @@ struct mac_iveiv_entry {
1603#define EEPROM_NIC_WPS_PBC FIELD16(0x0080) 1692#define EEPROM_NIC_WPS_PBC FIELD16(0x0080)
1604#define EEPROM_NIC_BW40M_BG FIELD16(0x0100) 1693#define EEPROM_NIC_BW40M_BG FIELD16(0x0100)
1605#define EEPROM_NIC_BW40M_A FIELD16(0x0200) 1694#define EEPROM_NIC_BW40M_A FIELD16(0x0200)
1695#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800)
1696#define EEPROM_NIC_DAC_TEST FIELD16(0x8000)
1606 1697
1607/* 1698/*
1608 * EEPROM frequency 1699 * EEPROM frequency
@@ -1659,6 +1750,12 @@ struct mac_iveiv_entry {
1659#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00) 1750#define EEPROM_RSSI_BG2_LNA_A1 FIELD16(0xff00)
1660 1751
1661/* 1752/*
1753 * EEPROM TXMIXER GAIN BG offset (note overlaps with EEPROM RSSI BG2).
1754 */
1755#define EEPROM_TXMIXER_GAIN_BG 0x0024
1756#define EEPROM_TXMIXER_GAIN_BG_VAL FIELD16(0x0007)
1757
1758/*
1662 * EEPROM RSSI A offset 1759 * EEPROM RSSI A offset
1663 */ 1760 */
1664#define EEPROM_RSSI_A 0x0025 1761#define EEPROM_RSSI_A 0x0025
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c015ce9fdd09..db4250d1c8b3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -41,9 +41,6 @@
41#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) 41#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
42#include "rt2x00usb.h" 42#include "rt2x00usb.h"
43#endif 43#endif
44#if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE)
45#include "rt2x00pci.h"
46#endif
47#include "rt2800lib.h" 44#include "rt2800lib.h"
48#include "rt2800.h" 45#include "rt2800.h"
49#include "rt2800usb.h" 46#include "rt2800usb.h"
@@ -76,6 +73,23 @@ MODULE_LICENSE("GPL");
76 rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \ 73 rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \
77 H2M_MAILBOX_CSR_OWNER, (__reg)) 74 H2M_MAILBOX_CSR_OWNER, (__reg))
78 75
76static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev)
77{
78 /* check for rt2872 on SoC */
79 if (!rt2x00_is_soc(rt2x00dev) ||
80 !rt2x00_rt(rt2x00dev, RT2872))
81 return false;
82
83 /* we know for sure that these rf chipsets are used on rt305x boards */
84 if (rt2x00_rf(rt2x00dev, RF3020) ||
85 rt2x00_rf(rt2x00dev, RF3021) ||
86 rt2x00_rf(rt2x00dev, RF3022))
87 return true;
88
89 NOTICE(rt2x00dev, "Unknown RF chipset on rt305x\n");
90 return false;
91}
92
79static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, 93static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
80 const unsigned int word, const u8 value) 94 const unsigned int word, const u8 value)
81{ 95{
@@ -268,6 +282,104 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
268} 282}
269EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); 283EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
270 284
285void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc)
286{
287 __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE);
288 u32 word;
289
290 /*
291 * Initialize TX Info descriptor
292 */
293 rt2x00_desc_read(txwi, 0, &word);
294 rt2x00_set_field32(&word, TXWI_W0_FRAG,
295 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
296 rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
297 rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
298 rt2x00_set_field32(&word, TXWI_W0_TS,
299 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
300 rt2x00_set_field32(&word, TXWI_W0_AMPDU,
301 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
302 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
303 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop);
304 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
305 rt2x00_set_field32(&word, TXWI_W0_BW,
306 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
307 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
308 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
309 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
310 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
311 rt2x00_desc_write(txwi, 0, word);
312
313 rt2x00_desc_read(txwi, 1, &word);
314 rt2x00_set_field32(&word, TXWI_W1_ACK,
315 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
316 rt2x00_set_field32(&word, TXWI_W1_NSEQ,
317 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
318 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
319 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
320 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
321 txdesc->key_idx : 0xff);
322 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
323 txdesc->length);
324 rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1);
325 rt2x00_desc_write(txwi, 1, word);
326
327 /*
328 * Always write 0 to IV/EIV fields, hardware will insert the IV
329 * from the IVEIV register when TXD_W3_WIV is set to 0.
330 * When TXD_W3_WIV is set to 1 it will use the IV data
331 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
332 * crypto entry in the registers should be used to encrypt the frame.
333 */
334 _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
335 _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
336}
337EXPORT_SYMBOL_GPL(rt2800_write_txwi);
338
339void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc)
340{
341 __le32 *rxwi = (__le32 *) skb->data;
342 u32 word;
343
344 rt2x00_desc_read(rxwi, 0, &word);
345
346 rxdesc->cipher = rt2x00_get_field32(word, RXWI_W0_UDF);
347 rxdesc->size = rt2x00_get_field32(word, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
348
349 rt2x00_desc_read(rxwi, 1, &word);
350
351 if (rt2x00_get_field32(word, RXWI_W1_SHORT_GI))
352 rxdesc->flags |= RX_FLAG_SHORT_GI;
353
354 if (rt2x00_get_field32(word, RXWI_W1_BW))
355 rxdesc->flags |= RX_FLAG_40MHZ;
356
357 /*
358 * Detect RX rate, always use MCS as signal type.
359 */
360 rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
361 rxdesc->signal = rt2x00_get_field32(word, RXWI_W1_MCS);
362 rxdesc->rate_mode = rt2x00_get_field32(word, RXWI_W1_PHYMODE);
363
364 /*
365 * Mask of 0x8 bit to remove the short preamble flag.
366 */
367 if (rxdesc->rate_mode == RATE_MODE_CCK)
368 rxdesc->signal &= ~0x8;
369
370 rt2x00_desc_read(rxwi, 2, &word);
371
372 rxdesc->rssi =
373 (rt2x00_get_field32(word, RXWI_W2_RSSI0) +
374 rt2x00_get_field32(word, RXWI_W2_RSSI1)) / 2;
375
376 /*
377 * Remove RXWI descriptor from start of buffer.
378 */
379 skb_pull(skb, RXWI_DESC_SIZE);
380}
381EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
382
271#ifdef CONFIG_RT2X00_LIB_DEBUGFS 383#ifdef CONFIG_RT2X00_LIB_DEBUGFS
272const struct rt2x00debug rt2800_rt2x00debug = { 384const struct rt2x00debug rt2800_rt2x00debug = {
273 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
@@ -360,11 +472,6 @@ static int rt2800_blink_set(struct led_classdev *led_cdev,
360 rt2800_register_read(led->rt2x00dev, LED_CFG, &reg); 472 rt2800_register_read(led->rt2x00dev, LED_CFG, &reg);
361 rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on); 473 rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
362 rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off); 474 rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
363 rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
364 rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
365 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
366 rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
367 rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
368 rt2800_register_write(led->rt2x00dev, LED_CFG, reg); 475 rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
369 476
370 return 0; 477 return 0;
@@ -610,10 +717,6 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
610{ 717{
611 u32 reg; 718 u32 reg;
612 719
613 rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
614 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
615 rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
616
617 rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg); 720 rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
618 rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY, 721 rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
619 !!erp->short_preamble); 722 !!erp->short_preamble);
@@ -632,15 +735,10 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp)
632 735
633 rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg); 736 rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
634 rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); 737 rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
635 rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
636 rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); 738 rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
637 739
638 rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg); 740 rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
639 rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
640 rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
641 rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
642 rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs); 741 rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
643 rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
644 rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); 742 rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
645 743
646 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg); 744 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
@@ -718,10 +816,10 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
718 rt2x00dev->lna_gain = lna_gain; 816 rt2x00dev->lna_gain = lna_gain;
719} 817}
720 818
721static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev, 819static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
722 struct ieee80211_conf *conf, 820 struct ieee80211_conf *conf,
723 struct rf_channel *rf, 821 struct rf_channel *rf,
724 struct channel_info *info) 822 struct channel_info *info)
725{ 823{
726 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); 824 rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
727 825
@@ -787,10 +885,10 @@ static void rt2800_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
787 rt2800_rf_write(rt2x00dev, 4, rf->rf4); 885 rt2800_rf_write(rt2x00dev, 4, rf->rf4);
788} 886}
789 887
790static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, 888static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
791 struct ieee80211_conf *conf, 889 struct ieee80211_conf *conf,
792 struct rf_channel *rf, 890 struct rf_channel *rf,
793 struct channel_info *info) 891 struct channel_info *info)
794{ 892{
795 u8 rfcsr; 893 u8 rfcsr;
796 894
@@ -798,7 +896,7 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
798 rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); 896 rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
799 897
800 rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); 898 rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
801 rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2); 899 rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
802 rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); 900 rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
803 901
804 rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); 902 rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr);
@@ -806,6 +904,11 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
806 TXPOWER_G_TO_DEV(info->tx_power1)); 904 TXPOWER_G_TO_DEV(info->tx_power1));
807 rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); 905 rt2800_rfcsr_write(rt2x00dev, 12, rfcsr);
808 906
907 rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr);
908 rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
909 TXPOWER_G_TO_DEV(info->tx_power2));
910 rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
911
809 rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); 912 rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
810 rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); 913 rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
811 rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); 914 rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
@@ -827,15 +930,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
827 unsigned int tx_pin; 930 unsigned int tx_pin;
828 u8 bbp; 931 u8 bbp;
829 932
830 if ((rt2x00_rt(rt2x00dev, RT3070) || 933 if (rt2x00_rf(rt2x00dev, RF2020) ||
831 rt2x00_rt(rt2x00dev, RT3090)) && 934 rt2x00_rf(rt2x00dev, RF3020) ||
832 (rt2x00_rf(rt2x00dev, RF2020) || 935 rt2x00_rf(rt2x00dev, RF3021) ||
833 rt2x00_rf(rt2x00dev, RF3020) || 936 rt2x00_rf(rt2x00dev, RF3022))
834 rt2x00_rf(rt2x00dev, RF3021) || 937 rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
835 rt2x00_rf(rt2x00dev, RF3022)))
836 rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info);
837 else 938 else
838 rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info); 939 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
839 940
840 /* 941 /*
841 * Change BBP settings 942 * Change BBP settings
@@ -863,7 +964,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
863 } 964 }
864 965
865 rt2800_register_read(rt2x00dev, TX_BAND_CFG, &reg); 966 rt2800_register_read(rt2x00dev, TX_BAND_CFG, &reg);
866 rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf)); 967 rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_MINUS, conf_is_ht40_minus(conf));
867 rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14); 968 rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
868 rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14); 969 rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
869 rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); 970 rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg);
@@ -896,11 +997,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
896 rt2800_bbp_write(rt2x00dev, 4, bbp); 997 rt2800_bbp_write(rt2x00dev, 4, bbp);
897 998
898 rt2800_bbp_read(rt2x00dev, 3, &bbp); 999 rt2800_bbp_read(rt2x00dev, 3, &bbp);
899 rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf)); 1000 rt2x00_set_field8(&bbp, BBP3_HT40_MINUS, conf_is_ht40_minus(conf));
900 rt2800_bbp_write(rt2x00dev, 3, bbp); 1001 rt2800_bbp_write(rt2x00dev, 3, bbp);
901 1002
902 if (rt2x00_rt(rt2x00dev, RT2860) && 1003 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
903 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) {
904 if (conf_is_ht40(conf)) { 1004 if (conf_is_ht40(conf)) {
905 rt2800_bbp_write(rt2x00dev, 69, 0x1a); 1005 rt2800_bbp_write(rt2x00dev, 69, 0x1a);
906 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 1006 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
@@ -988,10 +1088,6 @@ static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
988 libconf->conf->short_frame_max_tx_count); 1088 libconf->conf->short_frame_max_tx_count);
989 rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 1089 rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
990 libconf->conf->long_frame_max_tx_count); 1090 libconf->conf->long_frame_max_tx_count);
991 rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
992 rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
993 rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
994 rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
995 rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg); 1091 rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
996} 1092}
997 1093
@@ -1015,13 +1111,13 @@ static void rt2800_config_ps(struct rt2x00_dev *rt2x00dev,
1015 1111
1016 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); 1112 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1017 } else { 1113 } else {
1018 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1019
1020 rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg); 1114 rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
1021 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0); 1115 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
1022 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0); 1116 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
1023 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0); 1117 rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
1024 rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg); 1118 rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
1119
1120 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
1025 } 1121 }
1026} 1122}
1027 1123
@@ -1062,9 +1158,10 @@ EXPORT_SYMBOL_GPL(rt2800_link_stats);
1062static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) 1158static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
1063{ 1159{
1064 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { 1160 if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
1065 if (rt2x00_is_usb(rt2x00dev) && 1161 if (rt2x00_rt(rt2x00dev, RT3070) ||
1066 rt2x00_rt(rt2x00dev, RT3070) && 1162 rt2x00_rt(rt2x00dev, RT3071) ||
1067 (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) 1163 rt2x00_rt(rt2x00dev, RT3090) ||
1164 rt2x00_rt(rt2x00dev, RT3390))
1068 return 0x1c + (2 * rt2x00dev->lna_gain); 1165 return 0x1c + (2 * rt2x00dev->lna_gain);
1069 else 1166 else
1070 return 0x2e + rt2x00dev->lna_gain; 1167 return 0x2e + rt2x00dev->lna_gain;
@@ -1095,8 +1192,7 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
1095void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, 1192void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
1096 const u32 count) 1193 const u32 count)
1097{ 1194{
1098 if (rt2x00_rt(rt2x00dev, RT2860) && 1195 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C))
1099 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION))
1100 return; 1196 return;
1101 1197
1102 /* 1198 /*
@@ -1114,8 +1210,17 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
1114int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) 1210int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1115{ 1211{
1116 u32 reg; 1212 u32 reg;
1213 u16 eeprom;
1117 unsigned int i; 1214 unsigned int i;
1118 1215
1216 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
1217 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
1218 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
1219 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
1220 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
1221 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
1222 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
1223
1119 if (rt2x00_is_usb(rt2x00dev)) { 1224 if (rt2x00_is_usb(rt2x00dev)) {
1120 /* 1225 /*
1121 * Wait until BBP and RF are ready. 1226 * Wait until BBP and RF are ready.
@@ -1135,8 +1240,25 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1135 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg); 1240 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
1136 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 1241 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
1137 reg & ~0x00002000); 1242 reg & ~0x00002000);
1138 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) 1243 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
1244 /*
1245 * Reset DMA indexes
1246 */
1247 rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
1248 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
1249 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
1250 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
1251 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
1252 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
1253 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
1254 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
1255 rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
1256
1257 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
1258 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
1259
1139 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); 1260 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
1261 }
1140 1262
1141 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg); 1263 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
1142 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1); 1264 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
@@ -1181,12 +1303,42 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1181 rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0); 1303 rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
1182 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 1304 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
1183 1305
1184 if (rt2x00_is_usb(rt2x00dev) && 1306 rt2800_config_filter(rt2x00dev, FIF_ALLMULTI);
1185 rt2x00_rt(rt2x00dev, RT3070) && 1307
1186 (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) { 1308 rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
1309 rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, 9);
1310 rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
1311 rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
1312
1313 if (rt2x00_rt(rt2x00dev, RT3071) ||
1314 rt2x00_rt(rt2x00dev, RT3090) ||
1315 rt2x00_rt(rt2x00dev, RT3390)) {
1187 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); 1316 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
1188 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); 1317 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
1189 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); 1318 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
1319 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
1320 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
1321 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
1322 if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
1323 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
1324 0x0000002c);
1325 else
1326 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
1327 0x0000000f);
1328 } else {
1329 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
1330 }
1331 rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg);
1332 } else if (rt2x00_rt(rt2x00dev, RT3070)) {
1333 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
1334
1335 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
1336 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
1337 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000002c);
1338 } else {
1339 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
1340 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
1341 }
1190 } else { 1342 } else {
1191 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); 1343 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
1192 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 1344 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -1205,19 +1357,15 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1205 1357
1206 rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg); 1358 rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
1207 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9); 1359 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
1360 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 32);
1208 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10); 1361 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
1209 rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg); 1362 rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
1210 1363
1211 rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg); 1364 rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
1212 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); 1365 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
1213 if ((rt2x00_rt(rt2x00dev, RT2872) && 1366 if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
1214 (rt2x00_rev(rt2x00dev) >= RT2880E_VERSION)) ||
1215 rt2x00_rt(rt2x00dev, RT2880) ||
1216 rt2x00_rt(rt2x00dev, RT2883) || 1367 rt2x00_rt(rt2x00dev, RT2883) ||
1217 rt2x00_rt(rt2x00dev, RT2890) || 1368 rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
1218 rt2x00_rt(rt2x00dev, RT3052) ||
1219 (rt2x00_rt(rt2x00dev, RT3070) &&
1220 (rt2x00_rev(rt2x00dev) < RT3070_VERSION)))
1221 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2); 1369 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
1222 else 1370 else
1223 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1); 1371 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
@@ -1225,38 +1373,61 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1225 rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0); 1373 rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
1226 rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg); 1374 rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
1227 1375
1376 rt2800_register_read(rt2x00dev, LED_CFG, &reg);
1377 rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, 70);
1378 rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, 30);
1379 rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
1380 rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
1381 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
1382 rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
1383 rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
1384 rt2800_register_write(rt2x00dev, LED_CFG, reg);
1385
1228 rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f); 1386 rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
1229 1387
1388 rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
1389 rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
1390 rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
1391 rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
1392 rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
1393 rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
1394 rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
1395 rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
1396
1230 rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg); 1397 rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
1231 rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1); 1398 rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
1399 rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY, 1);
1232 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0); 1400 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
1233 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0); 1401 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
1402 rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE, 1);
1234 rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0); 1403 rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
1235 rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0); 1404 rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
1236 rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); 1405 rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
1237 1406
1238 rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg); 1407 rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
1239 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8); 1408 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 3);
1240 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0); 1409 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
1241 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1); 1410 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
1242 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); 1411 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
1243 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); 1412 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
1244 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); 1413 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
1245 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1); 1414 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
1246 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1415 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1247 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1); 1416 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
1417 rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, 1);
1248 rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg); 1418 rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
1249 1419
1250 rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg); 1420 rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
1251 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8); 1421 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 3);
1252 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0); 1422 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
1253 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1); 1423 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
1254 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); 1424 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
1255 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); 1425 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
1256 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); 1426 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
1257 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1); 1427 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
1258 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1428 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1259 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1); 1429 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
1430 rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, 1);
1260 rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); 1431 rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
1261 1432
1262 rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg); 1433 rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
@@ -1269,11 +1440,13 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1269 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0); 1440 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
1270 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1441 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1271 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0); 1442 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
1443 rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, 0);
1272 rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); 1444 rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
1273 1445
1274 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg); 1446 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
1275 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084); 1447 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
1276 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0); 1448 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL,
1449 !rt2x00_is_usb(rt2x00dev));
1277 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1); 1450 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
1278 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); 1451 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
1279 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); 1452 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
@@ -1281,6 +1454,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1281 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1); 1454 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
1282 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1455 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1283 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1); 1456 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
1457 rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, 0);
1284 rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); 1458 rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
1285 1459
1286 rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg); 1460 rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
@@ -1293,6 +1467,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1293 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0); 1467 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
1294 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1468 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1295 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0); 1469 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
1470 rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, 0);
1296 rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); 1471 rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
1297 1472
1298 rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg); 1473 rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
@@ -1305,6 +1480,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1305 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1); 1480 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
1306 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1); 1481 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
1307 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1); 1482 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
1483 rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, 0);
1308 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); 1484 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
1309 1485
1310 if (rt2x00_is_usb(rt2x00dev)) { 1486 if (rt2x00_is_usb(rt2x00dev)) {
@@ -1334,6 +1510,22 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1334 rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg); 1510 rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
1335 1511
1336 rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca); 1512 rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
1513
1514 /*
1515 * Usually the CCK SIFS time should be set to 10 and the OFDM SIFS
1516 * time should be set to 16. However, the original Ralink driver uses
1517 * 16 for both and indeed using a value of 10 for CCK SIFS results in
1518 * connection problems with 11g + CTS protection. Hence, use the same
1519 * defaults as the Ralink driver: 16 for both, CCK and OFDM SIFS.
1520 */
1521 rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
1522 rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, 16);
1523 rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, 16);
1524 rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
1525 rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, 314);
1526 rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
1527 rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
1528
1337 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); 1529 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
1338 1530
1339 /* 1531 /*
@@ -1481,45 +1673,79 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
1481 rt2800_wait_bbp_ready(rt2x00dev))) 1673 rt2800_wait_bbp_ready(rt2x00dev)))
1482 return -EACCES; 1674 return -EACCES;
1483 1675
1676 if (rt2800_is_305x_soc(rt2x00dev))
1677 rt2800_bbp_write(rt2x00dev, 31, 0x08);
1678
1484 rt2800_bbp_write(rt2x00dev, 65, 0x2c); 1679 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
1485 rt2800_bbp_write(rt2x00dev, 66, 0x38); 1680 rt2800_bbp_write(rt2x00dev, 66, 0x38);
1486 rt2800_bbp_write(rt2x00dev, 69, 0x12); 1681
1682 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
1683 rt2800_bbp_write(rt2x00dev, 69, 0x16);
1684 rt2800_bbp_write(rt2x00dev, 73, 0x12);
1685 } else {
1686 rt2800_bbp_write(rt2x00dev, 69, 0x12);
1687 rt2800_bbp_write(rt2x00dev, 73, 0x10);
1688 }
1689
1487 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 1690 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
1488 rt2800_bbp_write(rt2x00dev, 73, 0x10); 1691
1489 rt2800_bbp_write(rt2x00dev, 81, 0x37); 1692 if (rt2x00_rt(rt2x00dev, RT3070) ||
1693 rt2x00_rt(rt2x00dev, RT3071) ||
1694 rt2x00_rt(rt2x00dev, RT3090) ||
1695 rt2x00_rt(rt2x00dev, RT3390)) {
1696 rt2800_bbp_write(rt2x00dev, 79, 0x13);
1697 rt2800_bbp_write(rt2x00dev, 80, 0x05);
1698 rt2800_bbp_write(rt2x00dev, 81, 0x33);
1699 } else if (rt2800_is_305x_soc(rt2x00dev)) {
1700 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
1701 rt2800_bbp_write(rt2x00dev, 80, 0x08);
1702 } else {
1703 rt2800_bbp_write(rt2x00dev, 81, 0x37);
1704 }
1705
1490 rt2800_bbp_write(rt2x00dev, 82, 0x62); 1706 rt2800_bbp_write(rt2x00dev, 82, 0x62);
1491 rt2800_bbp_write(rt2x00dev, 83, 0x6a); 1707 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
1492 rt2800_bbp_write(rt2x00dev, 84, 0x99); 1708
1709 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) ||
1710 rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D))
1711 rt2800_bbp_write(rt2x00dev, 84, 0x19);
1712 else
1713 rt2800_bbp_write(rt2x00dev, 84, 0x99);
1714
1493 rt2800_bbp_write(rt2x00dev, 86, 0x00); 1715 rt2800_bbp_write(rt2x00dev, 86, 0x00);
1494 rt2800_bbp_write(rt2x00dev, 91, 0x04); 1716 rt2800_bbp_write(rt2x00dev, 91, 0x04);
1495 rt2800_bbp_write(rt2x00dev, 92, 0x00); 1717 rt2800_bbp_write(rt2x00dev, 92, 0x00);
1496 rt2800_bbp_write(rt2x00dev, 103, 0x00);
1497 rt2800_bbp_write(rt2x00dev, 105, 0x05);
1498 1718
1499 if (rt2x00_rt(rt2x00dev, RT2860) && 1719 if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
1500 (rt2x00_rev(rt2x00dev) == RT2860C_VERSION)) { 1720 rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
1501 rt2800_bbp_write(rt2x00dev, 69, 0x16); 1721 rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
1502 rt2800_bbp_write(rt2x00dev, 73, 0x12); 1722 rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
1503 } 1723 rt2800_is_305x_soc(rt2x00dev))
1504 1724 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
1505 if (rt2x00_rt(rt2x00dev, RT2860) && 1725 else
1506 (rt2x00_rev(rt2x00dev) > RT2860D_VERSION)) 1726 rt2800_bbp_write(rt2x00dev, 103, 0x00);
1507 rt2800_bbp_write(rt2x00dev, 84, 0x19);
1508 1727
1509 if (rt2x00_is_usb(rt2x00dev) && 1728 if (rt2800_is_305x_soc(rt2x00dev))
1510 rt2x00_rt(rt2x00dev, RT3070) && 1729 rt2800_bbp_write(rt2x00dev, 105, 0x01);
1511 (rt2x00_rev(rt2x00dev) == RT3070_VERSION)) { 1730 else
1512 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
1513 rt2800_bbp_write(rt2x00dev, 84, 0x99);
1514 rt2800_bbp_write(rt2x00dev, 105, 0x05); 1731 rt2800_bbp_write(rt2x00dev, 105, 0x05);
1515 } 1732 rt2800_bbp_write(rt2x00dev, 106, 0x35);
1516 1733
1517 if (rt2x00_rt(rt2x00dev, RT3052)) { 1734 if (rt2x00_rt(rt2x00dev, RT3071) ||
1518 rt2800_bbp_write(rt2x00dev, 31, 0x08); 1735 rt2x00_rt(rt2x00dev, RT3090) ||
1519 rt2800_bbp_write(rt2x00dev, 78, 0x0e); 1736 rt2x00_rt(rt2x00dev, RT3390)) {
1520 rt2800_bbp_write(rt2x00dev, 80, 0x08); 1737 rt2800_bbp_read(rt2x00dev, 138, &value);
1738
1739 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
1740 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
1741 value |= 0x20;
1742 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
1743 value &= ~0x02;
1744
1745 rt2800_bbp_write(rt2x00dev, 138, value);
1521 } 1746 }
1522 1747
1748
1523 for (i = 0; i < EEPROM_BBP_SIZE; i++) { 1749 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
1524 rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); 1750 rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
1525 1751
@@ -1598,19 +1824,16 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1598{ 1824{
1599 u8 rfcsr; 1825 u8 rfcsr;
1600 u8 bbp; 1826 u8 bbp;
1827 u32 reg;
1828 u16 eeprom;
1601 1829
1602 if (rt2x00_is_usb(rt2x00dev) && 1830 if (!rt2x00_rt(rt2x00dev, RT3070) &&
1603 rt2x00_rt(rt2x00dev, RT3070) && 1831 !rt2x00_rt(rt2x00dev, RT3071) &&
1604 (rt2x00_rev(rt2x00dev) != RT3070_VERSION)) 1832 !rt2x00_rt(rt2x00dev, RT3090) &&
1833 !rt2x00_rt(rt2x00dev, RT3390) &&
1834 !rt2800_is_305x_soc(rt2x00dev))
1605 return 0; 1835 return 0;
1606 1836
1607 if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
1608 if (!rt2x00_rf(rt2x00dev, RF3020) &&
1609 !rt2x00_rf(rt2x00dev, RF3021) &&
1610 !rt2x00_rf(rt2x00dev, RF3022))
1611 return 0;
1612 }
1613
1614 /* 1837 /*
1615 * Init RF calibration. 1838 * Init RF calibration.
1616 */ 1839 */
@@ -1621,13 +1844,15 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1621 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); 1844 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
1622 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); 1845 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
1623 1846
1624 if (rt2x00_is_usb(rt2x00dev)) { 1847 if (rt2x00_rt(rt2x00dev, RT3070) ||
1848 rt2x00_rt(rt2x00dev, RT3071) ||
1849 rt2x00_rt(rt2x00dev, RT3090)) {
1625 rt2800_rfcsr_write(rt2x00dev, 4, 0x40); 1850 rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
1626 rt2800_rfcsr_write(rt2x00dev, 5, 0x03); 1851 rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
1627 rt2800_rfcsr_write(rt2x00dev, 6, 0x02); 1852 rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
1628 rt2800_rfcsr_write(rt2x00dev, 7, 0x70); 1853 rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
1629 rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); 1854 rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
1630 rt2800_rfcsr_write(rt2x00dev, 10, 0x71); 1855 rt2800_rfcsr_write(rt2x00dev, 10, 0x41);
1631 rt2800_rfcsr_write(rt2x00dev, 11, 0x21); 1856 rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
1632 rt2800_rfcsr_write(rt2x00dev, 12, 0x7b); 1857 rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
1633 rt2800_rfcsr_write(rt2x00dev, 14, 0x90); 1858 rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
@@ -1640,9 +1865,41 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1640 rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); 1865 rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
1641 rt2800_rfcsr_write(rt2x00dev, 24, 0x16); 1866 rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
1642 rt2800_rfcsr_write(rt2x00dev, 25, 0x01); 1867 rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
1643 rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
1644 rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); 1868 rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
1645 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) { 1869 } else if (rt2x00_rt(rt2x00dev, RT3390)) {
1870 rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
1871 rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
1872 rt2800_rfcsr_write(rt2x00dev, 2, 0xf1);
1873 rt2800_rfcsr_write(rt2x00dev, 3, 0x62);
1874 rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
1875 rt2800_rfcsr_write(rt2x00dev, 5, 0x8b);
1876 rt2800_rfcsr_write(rt2x00dev, 6, 0x42);
1877 rt2800_rfcsr_write(rt2x00dev, 7, 0x34);
1878 rt2800_rfcsr_write(rt2x00dev, 8, 0x00);
1879 rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
1880 rt2800_rfcsr_write(rt2x00dev, 10, 0x61);
1881 rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
1882 rt2800_rfcsr_write(rt2x00dev, 12, 0x3b);
1883 rt2800_rfcsr_write(rt2x00dev, 13, 0xe0);
1884 rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
1885 rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
1886 rt2800_rfcsr_write(rt2x00dev, 16, 0xe0);
1887 rt2800_rfcsr_write(rt2x00dev, 17, 0x94);
1888 rt2800_rfcsr_write(rt2x00dev, 18, 0x5c);
1889 rt2800_rfcsr_write(rt2x00dev, 19, 0x4a);
1890 rt2800_rfcsr_write(rt2x00dev, 20, 0xb2);
1891 rt2800_rfcsr_write(rt2x00dev, 21, 0xf6);
1892 rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
1893 rt2800_rfcsr_write(rt2x00dev, 23, 0x14);
1894 rt2800_rfcsr_write(rt2x00dev, 24, 0x08);
1895 rt2800_rfcsr_write(rt2x00dev, 25, 0x3d);
1896 rt2800_rfcsr_write(rt2x00dev, 26, 0x85);
1897 rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
1898 rt2800_rfcsr_write(rt2x00dev, 28, 0x41);
1899 rt2800_rfcsr_write(rt2x00dev, 29, 0x8f);
1900 rt2800_rfcsr_write(rt2x00dev, 30, 0x20);
1901 rt2800_rfcsr_write(rt2x00dev, 31, 0x0f);
1902 } else if (rt2800_is_305x_soc(rt2x00dev)) {
1646 rt2800_rfcsr_write(rt2x00dev, 0, 0x50); 1903 rt2800_rfcsr_write(rt2x00dev, 0, 0x50);
1647 rt2800_rfcsr_write(rt2x00dev, 1, 0x01); 1904 rt2800_rfcsr_write(rt2x00dev, 1, 0x01);
1648 rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); 1905 rt2800_rfcsr_write(rt2x00dev, 2, 0xf7);
@@ -1673,15 +1930,57 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1673 rt2800_rfcsr_write(rt2x00dev, 27, 0x23); 1930 rt2800_rfcsr_write(rt2x00dev, 27, 0x23);
1674 rt2800_rfcsr_write(rt2x00dev, 28, 0x13); 1931 rt2800_rfcsr_write(rt2x00dev, 28, 0x13);
1675 rt2800_rfcsr_write(rt2x00dev, 29, 0x83); 1932 rt2800_rfcsr_write(rt2x00dev, 29, 0x83);
1933 rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
1934 rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
1935 return 0;
1936 }
1937
1938 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
1939 rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
1940 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
1941 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
1942 rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
1943 } else if (rt2x00_rt(rt2x00dev, RT3071) ||
1944 rt2x00_rt(rt2x00dev, RT3090)) {
1945 rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
1946 rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1);
1947 rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
1948
1949 rt2800_rfcsr_write(rt2x00dev, 31, 0x14);
1950
1951 rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
1952 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
1953 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
1954 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
1955 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
1956 if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST))
1957 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
1958 else
1959 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
1960 }
1961 rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
1962 } else if (rt2x00_rt(rt2x00dev, RT3390)) {
1963 rt2800_register_read(rt2x00dev, GPIO_SWITCH, &reg);
1964 rt2x00_set_field32(&reg, GPIO_SWITCH_5, 0);
1965 rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg);
1676 } 1966 }
1677 1967
1678 /* 1968 /*
1679 * Set RX Filter calibration for 20MHz and 40MHz 1969 * Set RX Filter calibration for 20MHz and 40MHz
1680 */ 1970 */
1681 rt2x00dev->calibration[0] = 1971 if (rt2x00_rt(rt2x00dev, RT3070)) {
1682 rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16); 1972 rt2x00dev->calibration[0] =
1683 rt2x00dev->calibration[1] = 1973 rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
1684 rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); 1974 rt2x00dev->calibration[1] =
1975 rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
1976 } else if (rt2x00_rt(rt2x00dev, RT3071) ||
1977 rt2x00_rt(rt2x00dev, RT3090) ||
1978 rt2x00_rt(rt2x00dev, RT3390)) {
1979 rt2x00dev->calibration[0] =
1980 rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
1981 rt2x00dev->calibration[1] =
1982 rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
1983 }
1685 1984
1686 /* 1985 /*
1687 * Set back to initial state 1986 * Set back to initial state
@@ -1699,6 +1998,81 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1699 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); 1998 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
1700 rt2800_bbp_write(rt2x00dev, 4, bbp); 1999 rt2800_bbp_write(rt2x00dev, 4, bbp);
1701 2000
2001 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
2002 rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
2003 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
2004 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E))
2005 rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
2006
2007 rt2800_register_read(rt2x00dev, OPT_14_CSR, &reg);
2008 rt2x00_set_field32(&reg, OPT_14_CSR_BIT0, 1);
2009 rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
2010
2011 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
2012 rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
2013 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
2014 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
2015 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
2016 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
2017 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
2018 rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
2019 }
2020 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
2021 if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
2022 rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
2023 rt2x00_get_field16(eeprom,
2024 EEPROM_TXMIXER_GAIN_BG_VAL));
2025 rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
2026
2027 if (rt2x00_rt(rt2x00dev, RT3090)) {
2028 rt2800_bbp_read(rt2x00dev, 138, &bbp);
2029
2030 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
2031 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1)
2032 rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
2033 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
2034 rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
2035
2036 rt2800_bbp_write(rt2x00dev, 138, bbp);
2037 }
2038
2039 if (rt2x00_rt(rt2x00dev, RT3071) ||
2040 rt2x00_rt(rt2x00dev, RT3090) ||
2041 rt2x00_rt(rt2x00dev, RT3390)) {
2042 rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
2043 rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
2044 rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
2045 rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
2046 rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
2047 rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
2048 rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
2049
2050 rt2800_rfcsr_read(rt2x00dev, 15, &rfcsr);
2051 rt2x00_set_field8(&rfcsr, RFCSR15_TX_LO2_EN, 0);
2052 rt2800_rfcsr_write(rt2x00dev, 15, rfcsr);
2053
2054 rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
2055 rt2x00_set_field8(&rfcsr, RFCSR20_RX_LO1_EN, 0);
2056 rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
2057
2058 rt2800_rfcsr_read(rt2x00dev, 21, &rfcsr);
2059 rt2x00_set_field8(&rfcsr, RFCSR21_RX_LO2_EN, 0);
2060 rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
2061 }
2062
2063 if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071)) {
2064 rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr);
2065 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
2066 rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E))
2067 rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3);
2068 else
2069 rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0);
2070 rt2x00_set_field8(&rfcsr, RFCSR27_R2, 0);
2071 rt2x00_set_field8(&rfcsr, RFCSR27_R3, 0);
2072 rt2x00_set_field8(&rfcsr, RFCSR27_R4, 0);
2073 rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
2074 }
2075
1702 return 0; 2076 return 0;
1703} 2077}
1704EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); 2078EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
@@ -1774,10 +2148,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
1774 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); 2148 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
1775 } else if (rt2x00_rt(rt2x00dev, RT2860) || 2149 } else if (rt2x00_rt(rt2x00dev, RT2860) ||
1776 rt2x00_rt(rt2x00dev, RT2870) || 2150 rt2x00_rt(rt2x00dev, RT2870) ||
1777 rt2x00_rt(rt2x00dev, RT2872) || 2151 rt2x00_rt(rt2x00dev, RT2872)) {
1778 rt2x00_rt(rt2x00dev, RT2880) ||
1779 (rt2x00_rt(rt2x00dev, RT2883) &&
1780 (rt2x00_rev(rt2x00dev) < RT2883_VERSION))) {
1781 /* 2152 /*
1782 * There is a max of 2 RX streams for RT28x0 series 2153 * There is a max of 2 RX streams for RT28x0 series
1783 */ 2154 */
@@ -1882,10 +2253,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
1882 if (!rt2x00_rt(rt2x00dev, RT2860) && 2253 if (!rt2x00_rt(rt2x00dev, RT2860) &&
1883 !rt2x00_rt(rt2x00dev, RT2870) && 2254 !rt2x00_rt(rt2x00dev, RT2870) &&
1884 !rt2x00_rt(rt2x00dev, RT2872) && 2255 !rt2x00_rt(rt2x00dev, RT2872) &&
1885 !rt2x00_rt(rt2x00dev, RT2880) &&
1886 !rt2x00_rt(rt2x00dev, RT2883) && 2256 !rt2x00_rt(rt2x00dev, RT2883) &&
1887 !rt2x00_rt(rt2x00dev, RT2890) &&
1888 !rt2x00_rt(rt2x00dev, RT3052) &&
1889 !rt2x00_rt(rt2x00dev, RT3070) && 2257 !rt2x00_rt(rt2x00dev, RT3070) &&
1890 !rt2x00_rt(rt2x00dev, RT3071) && 2258 !rt2x00_rt(rt2x00dev, RT3071) &&
1891 !rt2x00_rt(rt2x00dev, RT3090) && 2259 !rt2x00_rt(rt2x00dev, RT3090) &&
@@ -1954,7 +2322,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
1954EXPORT_SYMBOL_GPL(rt2800_init_eeprom); 2322EXPORT_SYMBOL_GPL(rt2800_init_eeprom);
1955 2323
1956/* 2324/*
1957 * RF value list for rt28x0 2325 * RF value list for rt28xx
1958 * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) 2326 * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
1959 */ 2327 */
1960static const struct rf_channel rf_vals[] = { 2328static const struct rf_channel rf_vals[] = {
@@ -2029,10 +2397,10 @@ static const struct rf_channel rf_vals[] = {
2029}; 2397};
2030 2398
2031/* 2399/*
2032 * RF value list for rt3070 2400 * RF value list for rt3xxx
2033 * Supports: 2.4 GHz 2401 * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052)
2034 */ 2402 */
2035static const struct rf_channel rf_vals_302x[] = { 2403static const struct rf_channel rf_vals_3x[] = {
2036 {1, 241, 2, 2 }, 2404 {1, 241, 2, 2 },
2037 {2, 241, 2, 7 }, 2405 {2, 241, 2, 7 },
2038 {3, 242, 2, 2 }, 2406 {3, 242, 2, 2 },
@@ -2047,6 +2415,51 @@ static const struct rf_channel rf_vals_302x[] = {
2047 {12, 246, 2, 7 }, 2415 {12, 246, 2, 7 },
2048 {13, 247, 2, 2 }, 2416 {13, 247, 2, 2 },
2049 {14, 248, 2, 4 }, 2417 {14, 248, 2, 4 },
2418
2419 /* 802.11 UNI / HyperLan 2 */
2420 {36, 0x56, 0, 4},
2421 {38, 0x56, 0, 6},
2422 {40, 0x56, 0, 8},
2423 {44, 0x57, 0, 0},
2424 {46, 0x57, 0, 2},
2425 {48, 0x57, 0, 4},
2426 {52, 0x57, 0, 8},
2427 {54, 0x57, 0, 10},
2428 {56, 0x58, 0, 0},
2429 {60, 0x58, 0, 4},
2430 {62, 0x58, 0, 6},
2431 {64, 0x58, 0, 8},
2432
2433 /* 802.11 HyperLan 2 */
2434 {100, 0x5b, 0, 8},
2435 {102, 0x5b, 0, 10},
2436 {104, 0x5c, 0, 0},
2437 {108, 0x5c, 0, 4},
2438 {110, 0x5c, 0, 6},
2439 {112, 0x5c, 0, 8},
2440 {116, 0x5d, 0, 0},
2441 {118, 0x5d, 0, 2},
2442 {120, 0x5d, 0, 4},
2443 {124, 0x5d, 0, 8},
2444 {126, 0x5d, 0, 10},
2445 {128, 0x5e, 0, 0},
2446 {132, 0x5e, 0, 4},
2447 {134, 0x5e, 0, 6},
2448 {136, 0x5e, 0, 8},
2449 {140, 0x5f, 0, 0},
2450
2451 /* 802.11 UNII */
2452 {149, 0x5f, 0, 9},
2453 {151, 0x5f, 0, 11},
2454 {153, 0x60, 0, 1},
2455 {157, 0x60, 0, 5},
2456 {159, 0x60, 0, 7},
2457 {161, 0x60, 0, 9},
2458 {165, 0x61, 0, 1},
2459 {167, 0x61, 0, 3},
2460 {169, 0x61, 0, 5},
2461 {171, 0x61, 0, 7},
2462 {173, 0x61, 0, 9},
2050}; 2463};
2051 2464
2052int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 2465int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
@@ -2087,11 +2500,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2087 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 2500 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
2088 2501
2089 if (rt2x00_rf(rt2x00dev, RF2820) || 2502 if (rt2x00_rf(rt2x00dev, RF2820) ||
2090 rt2x00_rf(rt2x00dev, RF2720) || 2503 rt2x00_rf(rt2x00dev, RF2720)) {
2091 rt2x00_rf(rt2x00dev, RF3052)) {
2092 spec->num_channels = 14; 2504 spec->num_channels = 14;
2093 spec->channels = rf_vals; 2505 spec->channels = rf_vals;
2094 } else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) { 2506 } else if (rt2x00_rf(rt2x00dev, RF2850) ||
2507 rt2x00_rf(rt2x00dev, RF2750)) {
2095 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2508 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2096 spec->num_channels = ARRAY_SIZE(rf_vals); 2509 spec->num_channels = ARRAY_SIZE(rf_vals);
2097 spec->channels = rf_vals; 2510 spec->channels = rf_vals;
@@ -2099,8 +2512,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2099 rt2x00_rf(rt2x00dev, RF2020) || 2512 rt2x00_rf(rt2x00dev, RF2020) ||
2100 rt2x00_rf(rt2x00dev, RF3021) || 2513 rt2x00_rf(rt2x00dev, RF3021) ||
2101 rt2x00_rf(rt2x00dev, RF3022)) { 2514 rt2x00_rf(rt2x00dev, RF3022)) {
2102 spec->num_channels = ARRAY_SIZE(rf_vals_302x); 2515 spec->num_channels = 14;
2103 spec->channels = rf_vals_302x; 2516 spec->channels = rf_vals_3x;
2517 } else if (rt2x00_rf(rt2x00dev, RF3052)) {
2518 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2519 spec->num_channels = ARRAY_SIZE(rf_vals_3x);
2520 spec->channels = rf_vals_3x;
2104 } 2521 }
2105 2522
2106 /* 2523 /*
@@ -2111,8 +2528,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2111 else 2528 else
2112 spec->ht.ht_supported = false; 2529 spec->ht.ht_supported = false;
2113 2530
2531 /*
2532 * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes
2533 * reception problems with HT40 capable 11n APs
2534 */
2114 spec->ht.cap = 2535 spec->ht.cap =
2115 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2116 IEEE80211_HT_CAP_GRN_FLD | 2536 IEEE80211_HT_CAP_GRN_FLD |
2117 IEEE80211_HT_CAP_SGI_20 | 2537 IEEE80211_HT_CAP_SGI_20 |
2118 IEEE80211_HT_CAP_SGI_40 | 2538 IEEE80211_HT_CAP_SGI_40 |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index ebabeae62d1b..94de999e2290 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -111,6 +111,9 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
111 const u8 command, const u8 token, 111 const u8 command, const u8 token,
112 const u8 arg0, const u8 arg1); 112 const u8 arg0, const u8 arg1);
113 113
114void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc);
115void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
116
114extern const struct rt2x00debug rt2800_rt2x00debug; 117extern const struct rt2x00debug rt2800_rt2x00debug;
115 118
116int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); 119int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 91cce2d0f6db..b2f23272c3aa 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -60,6 +60,12 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
60 unsigned int i; 60 unsigned int i;
61 u32 reg; 61 u32 reg;
62 62
63 /*
64 * SOC devices don't support MCU requests.
65 */
66 if (rt2x00_is_soc(rt2x00dev))
67 return;
68
63 for (i = 0; i < 200; i++) { 69 for (i = 0; i < 200; i++) {
64 rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg); 70 rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
65 71
@@ -341,19 +347,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
341 struct queue_entry_priv_pci *entry_priv; 347 struct queue_entry_priv_pci *entry_priv;
342 u32 reg; 348 u32 reg;
343 349
344 rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
345 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
346 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
347 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
348 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
349 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
350 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
351 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
352 rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
353
354 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
355 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
356
357 /* 350 /*
358 * Initialize registers. 351 * Initialize registers.
359 */ 352 */
@@ -620,64 +613,31 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
620/* 613/*
621 * TX descriptor initialization 614 * TX descriptor initialization
622 */ 615 */
616static int rt2800pci_write_tx_data(struct queue_entry* entry,
617 struct txentry_desc *txdesc)
618{
619 int ret;
620
621 ret = rt2x00pci_write_tx_data(entry, txdesc);
622 if (ret)
623 return ret;
624
625 rt2800_write_txwi(entry->skb, txdesc);
626
627 return 0;
628}
629
630
623static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, 631static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
624 struct sk_buff *skb, 632 struct sk_buff *skb,
625 struct txentry_desc *txdesc) 633 struct txentry_desc *txdesc)
626{ 634{
627 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 635 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
628 __le32 *txd = skbdesc->desc; 636 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
629 __le32 *txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom); 637 __le32 *txd = entry_priv->desc;
630 u32 word; 638 u32 word;
631 639
632 /* 640 /*
633 * Initialize TX Info descriptor
634 */
635 rt2x00_desc_read(txwi, 0, &word);
636 rt2x00_set_field32(&word, TXWI_W0_FRAG,
637 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
638 rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
639 rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
640 rt2x00_set_field32(&word, TXWI_W0_TS,
641 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
642 rt2x00_set_field32(&word, TXWI_W0_AMPDU,
643 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
644 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
645 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
646 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
647 rt2x00_set_field32(&word, TXWI_W0_BW,
648 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
649 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
650 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
651 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
652 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
653 rt2x00_desc_write(txwi, 0, word);
654
655 rt2x00_desc_read(txwi, 1, &word);
656 rt2x00_set_field32(&word, TXWI_W1_ACK,
657 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
658 rt2x00_set_field32(&word, TXWI_W1_NSEQ,
659 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
660 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
661 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
662 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
663 txdesc->key_idx : 0xff);
664 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
665 skb->len - txdesc->l2pad);
666 rt2x00_set_field32(&word, TXWI_W1_PACKETID,
667 skbdesc->entry->queue->qid + 1);
668 rt2x00_desc_write(txwi, 1, word);
669
670 /*
671 * Always write 0 to IV/EIV fields, hardware will insert the IV
672 * from the IVEIV register when TXD_W3_WIV is set to 0.
673 * When TXD_W3_WIV is set to 1 it will use the IV data
674 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
675 * crypto entry in the registers should be used to encrypt the frame.
676 */
677 _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
678 _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
679
680 /*
681 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 641 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
682 * must contains a TXWI structure + 802.11 header + padding + 802.11 642 * must contains a TXWI structure + 802.11 header + padding + 802.11
683 * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and 643 * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and
@@ -698,15 +658,14 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
698 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); 658 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
699 rt2x00_set_field32(&word, TXD_W1_BURST, 659 rt2x00_set_field32(&word, TXD_W1_BURST,
700 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 660 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
701 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, 661 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE);
702 rt2x00dev->ops->extra_tx_headroom);
703 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); 662 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
704 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); 663 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
705 rt2x00_desc_write(txd, 1, word); 664 rt2x00_desc_write(txd, 1, word);
706 665
707 rt2x00_desc_read(txd, 2, &word); 666 rt2x00_desc_read(txd, 2, &word);
708 rt2x00_set_field32(&word, TXD_W2_SD_PTR1, 667 rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
709 skbdesc->skb_dma + rt2x00dev->ops->extra_tx_headroom); 668 skbdesc->skb_dma + TXWI_DESC_SIZE);
710 rt2x00_desc_write(txd, 2, word); 669 rt2x00_desc_write(txd, 2, word);
711 670
712 rt2x00_desc_read(txd, 3, &word); 671 rt2x00_desc_read(txd, 3, &word);
@@ -714,15 +673,21 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
714 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); 673 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
715 rt2x00_set_field32(&word, TXD_W3_QSEL, 2); 674 rt2x00_set_field32(&word, TXD_W3_QSEL, 2);
716 rt2x00_desc_write(txd, 3, word); 675 rt2x00_desc_write(txd, 3, word);
676
677 /*
678 * Register descriptor details in skb frame descriptor.
679 */
680 skbdesc->desc = txd;
681 skbdesc->desc_len = TXD_DESC_SIZE;
717} 682}
718 683
719/* 684/*
720 * TX data initialization 685 * TX data initialization
721 */ 686 */
722static void rt2800pci_write_beacon(struct queue_entry *entry) 687static void rt2800pci_write_beacon(struct queue_entry *entry,
688 struct txentry_desc *txdesc)
723{ 689{
724 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 690 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
725 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
726 unsigned int beacon_base; 691 unsigned int beacon_base;
727 u32 reg; 692 u32 reg;
728 693
@@ -735,15 +700,25 @@ static void rt2800pci_write_beacon(struct queue_entry *entry)
735 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 700 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
736 701
737 /* 702 /*
738 * Write entire beacon with descriptor to register. 703 * Add the TXWI for the beacon to the skb.
704 */
705 rt2800_write_txwi(entry->skb, txdesc);
706 skb_push(entry->skb, TXWI_DESC_SIZE);
707
708 /*
709 * Write entire beacon with TXWI to register.
739 */ 710 */
740 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 711 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
741 rt2800_register_multiwrite(rt2x00dev, 712 rt2800_register_multiwrite(rt2x00dev, beacon_base,
742 beacon_base, 713 entry->skb->data, entry->skb->len);
743 skbdesc->desc, skbdesc->desc_len); 714
744 rt2800_register_multiwrite(rt2x00dev, 715 /*
745 beacon_base + skbdesc->desc_len, 716 * Enable beaconing again.
746 entry->skb->data, entry->skb->len); 717 */
718 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
719 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
720 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
721 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
747 722
748 /* 723 /*
749 * Clean up beacon skb. 724 * Clean up beacon skb.
@@ -757,18 +732,6 @@ static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
757{ 732{
758 struct data_queue *queue; 733 struct data_queue *queue;
759 unsigned int idx, qidx = 0; 734 unsigned int idx, qidx = 0;
760 u32 reg;
761
762 if (queue_idx == QID_BEACON) {
763 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
764 if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
765 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
766 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
767 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
768 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
769 }
770 return;
771 }
772 735
773 if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) 736 if (queue_idx > QID_HCCA && queue_idx != QID_MGMT)
774 return; 737 return;
@@ -811,34 +774,21 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
811 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 774 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
812 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 775 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
813 __le32 *rxd = entry_priv->desc; 776 __le32 *rxd = entry_priv->desc;
814 __le32 *rxwi = (__le32 *)entry->skb->data; 777 u32 word;
815 u32 rxd3; 778
816 u32 rxwi0; 779 rt2x00_desc_read(rxd, 3, &word);
817 u32 rxwi1; 780
818 u32 rxwi2; 781 if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR))
819 u32 rxwi3;
820
821 rt2x00_desc_read(rxd, 3, &rxd3);
822 rt2x00_desc_read(rxwi, 0, &rxwi0);
823 rt2x00_desc_read(rxwi, 1, &rxwi1);
824 rt2x00_desc_read(rxwi, 2, &rxwi2);
825 rt2x00_desc_read(rxwi, 3, &rxwi3);
826
827 if (rt2x00_get_field32(rxd3, RXD_W3_CRC_ERROR))
828 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 782 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
829 783
830 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 784 /*
831 /* 785 * Unfortunately we don't know the cipher type used during
832 * Unfortunately we don't know the cipher type used during 786 * decryption. This prevents us from correct providing
833 * decryption. This prevents us from correct providing 787 * correct statistics through debugfs.
834 * correct statistics through debugfs. 788 */
835 */ 789 rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR);
836 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
837 rxdesc->cipher_status =
838 rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
839 }
840 790
841 if (rt2x00_get_field32(rxd3, RXD_W3_DECRYPTED)) { 791 if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) {
842 /* 792 /*
843 * Hardware has stripped IV/EIV data from 802.11 frame during 793 * Hardware has stripped IV/EIV data from 802.11 frame during
844 * decryption. Unfortunately the descriptor doesn't contain 794 * decryption. Unfortunately the descriptor doesn't contain
@@ -853,51 +803,22 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry,
853 rxdesc->flags |= RX_FLAG_MMIC_ERROR; 803 rxdesc->flags |= RX_FLAG_MMIC_ERROR;
854 } 804 }
855 805
856 if (rt2x00_get_field32(rxd3, RXD_W3_MY_BSS)) 806 if (rt2x00_get_field32(word, RXD_W3_MY_BSS))
857 rxdesc->dev_flags |= RXDONE_MY_BSS; 807 rxdesc->dev_flags |= RXDONE_MY_BSS;
858 808
859 if (rt2x00_get_field32(rxd3, RXD_W3_L2PAD)) 809 if (rt2x00_get_field32(word, RXD_W3_L2PAD))
860 rxdesc->dev_flags |= RXDONE_L2PAD; 810 rxdesc->dev_flags |= RXDONE_L2PAD;
861 811
862 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
863 rxdesc->flags |= RX_FLAG_SHORT_GI;
864
865 if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
866 rxdesc->flags |= RX_FLAG_40MHZ;
867
868 /* 812 /*
869 * Detect RX rate, always use MCS as signal type. 813 * Process the RXWI structure that is at the start of the buffer.
870 */ 814 */
871 rxdesc->dev_flags |= RXDONE_SIGNAL_MCS; 815 rt2800_process_rxwi(entry->skb, rxdesc);
872 rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
873 rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
874
875 /*
876 * Mask of 0x8 bit to remove the short preamble flag.
877 */
878 if (rxdesc->rate_mode == RATE_MODE_CCK)
879 rxdesc->signal &= ~0x8;
880
881 rxdesc->rssi =
882 (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
883 rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
884
885 rxdesc->noise =
886 (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
887 rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
888
889 rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
890 816
891 /* 817 /*
892 * Set RX IDX in register to inform hardware that we have handled 818 * Set RX IDX in register to inform hardware that we have handled
893 * this entry and it is available for reuse again. 819 * this entry and it is available for reuse again.
894 */ 820 */
895 rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); 821 rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
896
897 /*
898 * Remove TXWI descriptor from start of buffer.
899 */
900 skb_pull(entry->skb, RXWI_DESC_SIZE);
901} 822}
902 823
903/* 824/*
@@ -907,14 +828,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
907{ 828{
908 struct data_queue *queue; 829 struct data_queue *queue;
909 struct queue_entry *entry; 830 struct queue_entry *entry;
910 struct queue_entry *entry_done; 831 __le32 *txwi;
911 struct queue_entry_priv_pci *entry_priv;
912 struct txdone_entry_desc txdesc; 832 struct txdone_entry_desc txdesc;
913 u32 word; 833 u32 word;
914 u32 reg; 834 u32 reg;
915 u32 old_reg; 835 u32 old_reg;
916 unsigned int type; 836 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
917 unsigned int index;
918 u16 mcs, real_mcs; 837 u16 mcs, real_mcs;
919 838
920 /* 839 /*
@@ -936,76 +855,89 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
936 break; 855 break;
937 old_reg = reg; 856 old_reg = reg;
938 857
858 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
859 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
860 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
861
939 /* 862 /*
940 * Skip this entry when it contains an invalid 863 * Skip this entry when it contains an invalid
941 * queue identication number. 864 * queue identication number.
942 */ 865 */
943 type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; 866 if (pid <= 0 || pid > QID_RX)
944 if (type >= QID_RX)
945 continue; 867 continue;
946 868
947 queue = rt2x00queue_get_queue(rt2x00dev, type); 869 queue = rt2x00queue_get_queue(rt2x00dev, pid - 1);
948 if (unlikely(!queue)) 870 if (unlikely(!queue))
949 continue; 871 continue;
950 872
951 /* 873 /*
952 * Skip this entry when it contains an invalid 874 * Inside each queue, we process each entry in a chronological
953 * index number. 875 * order. We first check that the queue is not empty.
954 */ 876 */
955 index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1; 877 if (rt2x00queue_empty(queue))
956 if (unlikely(index >= queue->limit))
957 continue; 878 continue;
879 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
958 880
959 entry = &queue->entries[index]; 881 /* Check if we got a match by looking at WCID/ACK/PID
960 entry_priv = entry->priv_data; 882 * fields */
961 rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word); 883 txwi = (__le32 *)(entry->skb->data -
884 rt2x00dev->ops->extra_tx_headroom);
962 885
963 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 886 rt2x00_desc_read(txwi, 1, &word);
964 while (entry != entry_done) { 887 tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
965 /* 888 tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK);
966 * Catch up. 889 tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID);
967 * Just report any entries we missed as failed.
968 */
969 WARNING(rt2x00dev,
970 "TX status report missed for entry %d\n",
971 entry_done->entry_idx);
972 890
973 txdesc.flags = 0; 891 if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid))
974 __set_bit(TXDONE_UNKNOWN, &txdesc.flags); 892 WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n");
975 txdesc.retry = 0;
976
977 rt2x00lib_txdone(entry_done, &txdesc);
978 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
979 }
980 893
981 /* 894 /*
982 * Obtain the status about this packet. 895 * Obtain the status about this packet.
983 */ 896 */
984 txdesc.flags = 0; 897 txdesc.flags = 0;
985 if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) 898 rt2x00_desc_read(txwi, 0, &word);
986 __set_bit(TXDONE_SUCCESS, &txdesc.flags); 899 mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
987 else 900 real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS);
988 __set_bit(TXDONE_FAILURE, &txdesc.flags);
989 901
990 /* 902 /*
991 * Ralink has a retry mechanism using a global fallback 903 * Ralink has a retry mechanism using a global fallback
992 * table. We setup this fallback table to try immediate 904 * table. We setup this fallback table to try the immediate
993 * lower rate for all rates. In the TX_STA_FIFO, 905 * lower rate for all rates. In the TX_STA_FIFO, the MCS field
994 * the MCS field contains the MCS used for the successfull 906 * always contains the MCS used for the last transmission, be
995 * transmission. If the first transmission succeed, 907 * it successful or not.
996 * we have mcs == tx_mcs. On the second transmission,
997 * we have mcs = tx_mcs - 1. So the number of
998 * retry is (tx_mcs - mcs).
999 */ 908 */
1000 mcs = rt2x00_get_field32(word, TXWI_W0_MCS); 909 if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) {
1001 real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); 910 /*
911 * Transmission succeeded. The number of retries is
912 * mcs - real_mcs
913 */
914 __set_bit(TXDONE_SUCCESS, &txdesc.flags);
915 txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0);
916 } else {
917 /*
918 * Transmission failed. The number of retries is
919 * always 7 in this case (for a total number of 8
920 * frames sent).
921 */
922 __set_bit(TXDONE_FAILURE, &txdesc.flags);
923 txdesc.retry = 7;
924 }
925
1002 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 926 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
1003 txdesc.retry = mcs - min(mcs, real_mcs); 927
1004 928
1005 rt2x00lib_txdone(entry, &txdesc); 929 rt2x00lib_txdone(entry, &txdesc);
1006 } 930 }
1007} 931}
1008 932
933static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev)
934{
935 struct ieee80211_conf conf = { .flags = 0 };
936 struct rt2x00lib_conf libconf = { .conf = &conf };
937
938 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
939}
940
1009static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) 941static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
1010{ 942{
1011 struct rt2x00_dev *rt2x00dev = dev_instance; 943 struct rt2x00_dev *rt2x00dev = dev_instance;
@@ -1030,6 +962,9 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
1030 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) 962 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
1031 rt2800pci_txdone(rt2x00dev); 963 rt2800pci_txdone(rt2x00dev);
1032 964
965 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
966 rt2800pci_wakeup(rt2x00dev);
967
1033 return IRQ_HANDLED; 968 return IRQ_HANDLED;
1034} 969}
1035 970
@@ -1128,7 +1063,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
1128 .reset_tuner = rt2800_reset_tuner, 1063 .reset_tuner = rt2800_reset_tuner,
1129 .link_tuner = rt2800_link_tuner, 1064 .link_tuner = rt2800_link_tuner,
1130 .write_tx_desc = rt2800pci_write_tx_desc, 1065 .write_tx_desc = rt2800pci_write_tx_desc,
1131 .write_tx_data = rt2x00pci_write_tx_data, 1066 .write_tx_data = rt2800pci_write_tx_data,
1132 .write_beacon = rt2800pci_write_beacon, 1067 .write_beacon = rt2800pci_write_beacon,
1133 .kick_tx_queue = rt2800pci_kick_tx_queue, 1068 .kick_tx_queue = rt2800pci_kick_tx_queue,
1134 .kill_tx_queue = rt2800pci_kill_tx_queue, 1069 .kill_tx_queue = rt2800pci_kill_tx_queue,
@@ -1184,6 +1119,7 @@ static const struct rt2x00_ops rt2800pci_ops = {
1184/* 1119/*
1185 * RT2800pci module information. 1120 * RT2800pci module information.
1186 */ 1121 */
1122#ifdef CONFIG_RT2800PCI_PCI
1187static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { 1123static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1188 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1124 { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
1189 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1125 { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
@@ -1208,9 +1144,11 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
1208 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1144 { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
1209 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1145 { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
1210 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, 1146 { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
1147 { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
1211#endif 1148#endif
1212 { 0, } 1149 { 0, }
1213}; 1150};
1151#endif /* CONFIG_RT2800PCI_PCI */
1214 1152
1215MODULE_AUTHOR(DRV_PROJECT); 1153MODULE_AUTHOR(DRV_PROJECT);
1216MODULE_VERSION(DRV_VERSION); 1154MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index d27d7d5d850c..0f8b84b7224c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -400,60 +400,16 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
400 struct txentry_desc *txdesc) 400 struct txentry_desc *txdesc)
401{ 401{
402 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 402 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
403 __le32 *txi = skbdesc->desc; 403 __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE);
404 __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
405 u32 word; 404 u32 word;
406 405
407 /* 406 /*
408 * Initialize TX Info descriptor 407 * Initialize TXWI descriptor
409 */ 408 */
410 rt2x00_desc_read(txwi, 0, &word); 409 rt2800_write_txwi(skb, txdesc);
411 rt2x00_set_field32(&word, TXWI_W0_FRAG,
412 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
413 rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
414 rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
415 rt2x00_set_field32(&word, TXWI_W0_TS,
416 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
417 rt2x00_set_field32(&word, TXWI_W0_AMPDU,
418 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
419 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
420 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
421 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
422 rt2x00_set_field32(&word, TXWI_W0_BW,
423 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
424 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
425 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
426 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
427 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
428 rt2x00_desc_write(txwi, 0, word);
429
430 rt2x00_desc_read(txwi, 1, &word);
431 rt2x00_set_field32(&word, TXWI_W1_ACK,
432 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
433 rt2x00_set_field32(&word, TXWI_W1_NSEQ,
434 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
435 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
436 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
437 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
438 txdesc->key_idx : 0xff);
439 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
440 skb->len - txdesc->l2pad);
441 rt2x00_set_field32(&word, TXWI_W1_PACKETID,
442 skbdesc->entry->queue->qid + 1);
443 rt2x00_desc_write(txwi, 1, word);
444 410
445 /* 411 /*
446 * Always write 0 to IV/EIV fields, hardware will insert the IV 412 * Initialize TXINFO descriptor
447 * from the IVEIV register when TXINFO_W0_WIV is set to 0.
448 * When TXINFO_W0_WIV is set to 1 it will use the IV data
449 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
450 * crypto entry in the registers should be used to encrypt the frame.
451 */
452 _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
453 _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
454
455 /*
456 * Initialize TX descriptor
457 */ 413 */
458 rt2x00_desc_read(txi, 0, &word); 414 rt2x00_desc_read(txi, 0, &word);
459 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, 415 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
@@ -466,26 +422,25 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
466 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST, 422 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
467 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 423 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
468 rt2x00_desc_write(txi, 0, word); 424 rt2x00_desc_write(txi, 0, word);
425
426 /*
427 * Register descriptor details in skb frame descriptor.
428 */
429 skbdesc->desc = txi;
430 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
469} 431}
470 432
471/* 433/*
472 * TX data initialization 434 * TX data initialization
473 */ 435 */
474static void rt2800usb_write_beacon(struct queue_entry *entry) 436static void rt2800usb_write_beacon(struct queue_entry *entry,
437 struct txentry_desc *txdesc)
475{ 438{
476 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 439 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
477 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
478 unsigned int beacon_base; 440 unsigned int beacon_base;
479 u32 reg; 441 u32 reg;
480 442
481 /* 443 /*
482 * Add the descriptor in front of the skb.
483 */
484 skb_push(entry->skb, entry->queue->desc_size);
485 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
486 skbdesc->desc = entry->skb->data;
487
488 /*
489 * Disable beaconing while we are reloading the beacon data, 444 * Disable beaconing while we are reloading the beacon data,
490 * otherwise we might be sending out invalid data. 445 * otherwise we might be sending out invalid data.
491 */ 446 */
@@ -494,6 +449,12 @@ static void rt2800usb_write_beacon(struct queue_entry *entry)
494 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 449 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
495 450
496 /* 451 /*
452 * Add the TXWI for the beacon to the skb.
453 */
454 rt2800_write_txwi(entry->skb, txdesc);
455 skb_push(entry->skb, TXWI_DESC_SIZE);
456
457 /*
497 * Write entire beacon with descriptor to register. 458 * Write entire beacon with descriptor to register.
498 */ 459 */
499 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 460 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
@@ -503,6 +464,14 @@ static void rt2800usb_write_beacon(struct queue_entry *entry)
503 REGISTER_TIMEOUT32(entry->skb->len)); 464 REGISTER_TIMEOUT32(entry->skb->len));
504 465
505 /* 466 /*
467 * Enable beaconing again.
468 */
469 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
470 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
471 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
472 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
473
474 /*
506 * Clean up the beacon skb. 475 * Clean up the beacon skb.
507 */ 476 */
508 dev_kfree_skb(entry->skb); 477 dev_kfree_skb(entry->skb);
@@ -524,84 +493,53 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
524 return length; 493 return length;
525} 494}
526 495
527static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
528 const enum data_queue_qid queue)
529{
530 u32 reg;
531
532 if (queue != QID_BEACON) {
533 rt2x00usb_kick_tx_queue(rt2x00dev, queue);
534 return;
535 }
536
537 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
538 if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
539 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
540 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
541 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
542 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
543 }
544}
545
546/* 496/*
547 * RX control handlers 497 * RX control handlers
548 */ 498 */
549static void rt2800usb_fill_rxdone(struct queue_entry *entry, 499static void rt2800usb_fill_rxdone(struct queue_entry *entry,
550 struct rxdone_entry_desc *rxdesc) 500 struct rxdone_entry_desc *rxdesc)
551{ 501{
552 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
553 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 502 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
554 __le32 *rxi = (__le32 *)entry->skb->data; 503 __le32 *rxi = (__le32 *)entry->skb->data;
555 __le32 *rxwi;
556 __le32 *rxd; 504 __le32 *rxd;
557 u32 rxi0; 505 u32 word;
558 u32 rxwi0;
559 u32 rxwi1;
560 u32 rxwi2;
561 u32 rxwi3;
562 u32 rxd0;
563 int rx_pkt_len; 506 int rx_pkt_len;
564 507
565 /* 508 /*
509 * Copy descriptor to the skbdesc->desc buffer, making it safe from
510 * moving of frame data in rt2x00usb.
511 */
512 memcpy(skbdesc->desc, rxi, skbdesc->desc_len);
513
514 /*
566 * RX frame format is : 515 * RX frame format is :
567 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad | 516 * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad |
568 * |<------------ rx_pkt_len -------------->| 517 * |<------------ rx_pkt_len -------------->|
569 */ 518 */
570 rt2x00_desc_read(rxi, 0, &rxi0); 519 rt2x00_desc_read(rxi, 0, &word);
571 rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN); 520 rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
572
573 rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE);
574 521
575 /* 522 /*
576 * FIXME : we need to check for rx_pkt_len validity 523 * Remove the RXINFO structure from the sbk.
577 */ 524 */
578 rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len); 525 skb_pull(entry->skb, RXINFO_DESC_SIZE);
579 526
580 /* 527 /*
581 * Copy descriptor to the skbdesc->desc buffer, making it safe from 528 * FIXME: we need to check for rx_pkt_len validity
582 * moving of frame data in rt2x00usb.
583 */ 529 */
584 memcpy(skbdesc->desc, rxi, skbdesc->desc_len); 530 rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
585 531
586 /* 532 /*
587 * It is now safe to read the descriptor on all architectures. 533 * It is now safe to read the descriptor on all architectures.
588 */ 534 */
589 rt2x00_desc_read(rxwi, 0, &rxwi0); 535 rt2x00_desc_read(rxd, 0, &word);
590 rt2x00_desc_read(rxwi, 1, &rxwi1);
591 rt2x00_desc_read(rxwi, 2, &rxwi2);
592 rt2x00_desc_read(rxwi, 3, &rxwi3);
593 rt2x00_desc_read(rxd, 0, &rxd0);
594 536
595 if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR)) 537 if (rt2x00_get_field32(word, RXD_W0_CRC_ERROR))
596 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 538 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
597 539
598 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 540 rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W0_CIPHER_ERROR);
599 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
600 rxdesc->cipher_status =
601 rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
602 }
603 541
604 if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) { 542 if (rt2x00_get_field32(word, RXD_W0_DECRYPTED)) {
605 /* 543 /*
606 * Hardware has stripped IV/EIV data from 802.11 frame during 544 * Hardware has stripped IV/EIV data from 802.11 frame during
607 * decryption. Unfortunately the descriptor doesn't contain 545 * decryption. Unfortunately the descriptor doesn't contain
@@ -616,45 +554,21 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
616 rxdesc->flags |= RX_FLAG_MMIC_ERROR; 554 rxdesc->flags |= RX_FLAG_MMIC_ERROR;
617 } 555 }
618 556
619 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) 557 if (rt2x00_get_field32(word, RXD_W0_MY_BSS))
620 rxdesc->dev_flags |= RXDONE_MY_BSS; 558 rxdesc->dev_flags |= RXDONE_MY_BSS;
621 559
622 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) 560 if (rt2x00_get_field32(word, RXD_W0_L2PAD))
623 rxdesc->dev_flags |= RXDONE_L2PAD; 561 rxdesc->dev_flags |= RXDONE_L2PAD;
624 562
625 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
626 rxdesc->flags |= RX_FLAG_SHORT_GI;
627
628 if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
629 rxdesc->flags |= RX_FLAG_40MHZ;
630
631 /* 563 /*
632 * Detect RX rate, always use MCS as signal type. 564 * Remove RXD descriptor from end of buffer.
633 */ 565 */
634 rxdesc->dev_flags |= RXDONE_SIGNAL_MCS; 566 skb_trim(entry->skb, rx_pkt_len);
635 rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
636 rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
637 567
638 /* 568 /*
639 * Mask of 0x8 bit to remove the short preamble flag. 569 * Process the RXWI structure.
640 */ 570 */
641 if (rxdesc->rate_mode == RATE_MODE_CCK) 571 rt2800_process_rxwi(entry->skb, rxdesc);
642 rxdesc->signal &= ~0x8;
643
644 rxdesc->rssi =
645 (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
646 rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
647
648 rxdesc->noise =
649 (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
650 rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
651
652 rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
653
654 /*
655 * Remove RXWI descriptor from start of buffer.
656 */
657 skb_pull(entry->skb, skbdesc->desc_len);
658} 572}
659 573
660/* 574/*
@@ -747,7 +661,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
747 .write_tx_data = rt2x00usb_write_tx_data, 661 .write_tx_data = rt2x00usb_write_tx_data,
748 .write_beacon = rt2800usb_write_beacon, 662 .write_beacon = rt2800usb_write_beacon,
749 .get_tx_data_len = rt2800usb_get_tx_data_len, 663 .get_tx_data_len = rt2800usb_get_tx_data_len,
750 .kick_tx_queue = rt2800usb_kick_tx_queue, 664 .kick_tx_queue = rt2x00usb_kick_tx_queue,
751 .kill_tx_queue = rt2x00usb_kill_tx_queue, 665 .kill_tx_queue = rt2x00usb_kill_tx_queue,
752 .fill_rxdone = rt2800usb_fill_rxdone, 666 .fill_rxdone = rt2800usb_fill_rxdone,
753 .config_shared_key = rt2800_config_shared_key, 667 .config_shared_key = rt2800_config_shared_key,
@@ -806,6 +720,10 @@ static struct usb_device_id rt2800usb_device_table[] = {
806 { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, 720 { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
807 { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, 721 { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
808 { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 722 { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
723 /* Allwin */
724 { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
725 { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
726 { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
809 /* Amit */ 727 /* Amit */
810 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, 728 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
811 /* Askey */ 729 /* Askey */
@@ -841,13 +759,18 @@ static struct usb_device_id rt2800usb_device_table[] = {
841 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, 759 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
842 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, 760 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
843 /* EnGenius */ 761 /* EnGenius */
844 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, 762 { USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
845 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, 763 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
846 /* Gigabyte */ 764 /* Gigabyte */
847 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, 765 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
848 /* Hawking */ 766 /* Hawking */
849 { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) }, 767 { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
850 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, 768 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
769 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
770 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
771 { USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
772 { USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
773 { USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
851 /* Linksys */ 774 /* Linksys */
852 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, 775 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
853 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, 776 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -876,6 +799,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
876 { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) }, 799 { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
877 { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) }, 800 { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
878 { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) }, 801 { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
802 { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
803 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
879 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, 804 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
880 /* SMC */ 805 /* SMC */
881 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, 806 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -905,8 +830,17 @@ static struct usb_device_id rt2800usb_device_table[] = {
905 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 830 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
906 /* AirTies */ 831 /* AirTies */
907 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) }, 832 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
833 /* Allwin */
834 { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
835 { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
836 { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
837 /* ASUS */
838 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
908 /* AzureWave */ 839 /* AzureWave */
909 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, 840 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
841 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
842 { USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
843 { USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
910 /* Conceptronic */ 844 /* Conceptronic */
911 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) }, 845 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
912 /* Corega */ 846 /* Corega */
@@ -916,20 +850,46 @@ static struct usb_device_id rt2800usb_device_table[] = {
916 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, 850 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
917 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, 851 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
918 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, 852 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
853 { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
854 /* Draytek */
855 { USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
919 /* Edimax */ 856 /* Edimax */
920 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, 857 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
921 /* Encore */ 858 /* Encore */
922 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, 859 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
860 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
923 /* EnGenius */ 861 /* EnGenius */
924 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, 862 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
925 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, 863 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
926 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, 864 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
865 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
866 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
867 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
927 /* Gigabyte */ 868 /* Gigabyte */
928 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, 869 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
929 /* I-O DATA */ 870 /* I-O DATA */
930 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, 871 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
872 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
873 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
874 /* Logitec */
875 { USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
931 /* MSI */ 876 /* MSI */
932 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, 877 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
878 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
879 { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
880 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
881 { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
882 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
883 { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
884 { USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
885 { USB_DEVICE(0x0db0, 0x822c), USB_DEVICE_DATA(&rt2800usb_ops) },
886 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
887 { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
888 { USB_DEVICE(0x0db0, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
889 { USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
890 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
891 /* Para */
892 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
933 /* Pegatron */ 893 /* Pegatron */
934 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, 894 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
935 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, 895 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -944,14 +904,22 @@ static struct usb_device_id rt2800usb_device_table[] = {
944 { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 904 { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
945 /* Sitecom */ 905 /* Sitecom */
946 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, 906 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
907 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
947 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, 908 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
909 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
910 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
948 /* SMC */ 911 /* SMC */
949 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, 912 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
913 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
914 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
915 { USB_DEVICE(0x083a, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
950 /* Zinwell */ 916 /* Zinwell */
951 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, 917 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
952 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, 918 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
953#endif 919#endif
954#ifdef CONFIG_RT2800USB_RT35XX 920#ifdef CONFIG_RT2800USB_RT35XX
921 /* Allwin */
922 { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
955 /* Askey */ 923 /* Askey */
956 { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) }, 924 { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
957 /* Cisco */ 925 /* Cisco */
@@ -966,37 +934,27 @@ static struct usb_device_id rt2800usb_device_table[] = {
966 { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) }, 934 { USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
967 /* Sitecom */ 935 /* Sitecom */
968 { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, 936 { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
937 { USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
969 /* Zinwell */ 938 /* Zinwell */
970 { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, 939 { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
971#endif 940#endif
972#ifdef CONFIG_RT2800USB_UNKNOWN 941#ifdef CONFIG_RT2800USB_UNKNOWN
973 /* 942 /*
974 * Unclear what kind of devices these are (they aren't supported by the 943 * Unclear what kind of devices these are (they aren't supported by the
975 * vendor driver). 944 * vendor linux driver).
976 */ 945 */
977 /* Allwin */
978 { USB_DEVICE(0x8516, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
979 { USB_DEVICE(0x8516, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
980 { USB_DEVICE(0x8516, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
981 { USB_DEVICE(0x8516, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
982 { USB_DEVICE(0x8516, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
983 { USB_DEVICE(0x8516, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
984 { USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
985 /* Amigo */ 946 /* Amigo */
986 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, 947 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
987 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, 948 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
988 /* Askey */
989 { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
990 /* ASUS */ 949 /* ASUS */
991 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, 950 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
992 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, 951 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
993 { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
994 { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) }, 952 { USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
995 { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) }, 953 { USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
996 /* AzureWave */ 954 /* AzureWave */
997 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, 955 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
998 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, 956 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
999 { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, 957 { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) },
1000 /* Belkin */ 958 /* Belkin */
1001 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, 959 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
1002 /* Buffalo */ 960 /* Buffalo */
@@ -1015,24 +973,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
1015 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, 973 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
1016 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, 974 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
1017 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, 975 { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) },
1018 { USB_DEVICE(0x07d1, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) }, 976 { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) },
1019 /* Encore */ 977 /* Encore */
1020 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, 978 { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
1021 { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
1022 /* EnGenius */
1023 { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
1024 { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
1025 { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
1026 /* Gemtek */ 979 /* Gemtek */
1027 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, 980 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
1028 /* Gigabyte */ 981 /* Gigabyte */
1029 { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) }, 982 { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
1030 /* Hawking */
1031 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
1032 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
1033 /* I-O DATA */
1034 { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) },
1035 { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) },
1036 /* LevelOne */ 983 /* LevelOne */
1037 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, 984 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
1038 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, 985 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -1042,43 +989,23 @@ static struct usb_device_id rt2800usb_device_table[] = {
1042 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, 989 { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) },
1043 /* Motorola */ 990 /* Motorola */
1044 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, 991 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
1045 /* MSI */
1046 { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) },
1047 { USB_DEVICE(0x0db0, 0x3822), USB_DEVICE_DATA(&rt2800usb_ops) },
1048 { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) },
1049 { USB_DEVICE(0x0db0, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
1050 { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
1051 { USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
1052 { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) },
1053 { USB_DEVICE(0x0db0, 0x871a), USB_DEVICE_DATA(&rt2800usb_ops) },
1054 { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
1055 /* Ovislink */ 992 /* Ovislink */
993 { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
1056 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, 994 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
1057 /* Para */
1058 { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
1059 /* Pegatron */ 995 /* Pegatron */
1060 { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, 996 { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
1061 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, 997 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
1062 { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, 998 { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
999 { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) },
1063 /* Planex */ 1000 /* Planex */
1064 { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, 1001 { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
1065 /* Qcom */ 1002 /* Qcom */
1066 { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) }, 1003 { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
1067 /* Sitecom */
1068 { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
1069 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
1070 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
1071 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
1072 { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) },
1073 { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) },
1074 { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) },
1075 { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) },
1076 /* SMC */ 1004 /* SMC */
1077 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, 1005 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
1078 { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) },
1079 { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) },
1080 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, 1006 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
1081 { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, 1007 { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
1008 { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) },
1082 /* Sweex */ 1009 /* Sweex */
1083 { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, 1010 { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
1084 { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, 1011 { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index d1d8ae94b4d4..2bca6a71a7f5 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -79,8 +79,6 @@
79 */ 79 */
80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 80#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 81#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) )
82#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) )
83#define RXD_DESC_SIZE ( 1 * sizeof(__le32) )
84 82
85/* 83/*
86 * TX Info structure 84 * TX Info structure
@@ -113,44 +111,6 @@
113#define RXINFO_W0_USB_DMA_RX_PKT_LEN FIELD32(0x0000ffff) 111#define RXINFO_W0_USB_DMA_RX_PKT_LEN FIELD32(0x0000ffff)
114 112
115/* 113/*
116 * RX WI structure
117 */
118
119/*
120 * Word0
121 */
122#define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff)
123#define RXWI_W0_KEY_INDEX FIELD32(0x00000300)
124#define RXWI_W0_BSSID FIELD32(0x00001c00)
125#define RXWI_W0_UDF FIELD32(0x0000e000)
126#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000)
127#define RXWI_W0_TID FIELD32(0xf0000000)
128
129/*
130 * Word1
131 */
132#define RXWI_W1_FRAG FIELD32(0x0000000f)
133#define RXWI_W1_SEQUENCE FIELD32(0x0000fff0)
134#define RXWI_W1_MCS FIELD32(0x007f0000)
135#define RXWI_W1_BW FIELD32(0x00800000)
136#define RXWI_W1_SHORT_GI FIELD32(0x01000000)
137#define RXWI_W1_STBC FIELD32(0x06000000)
138#define RXWI_W1_PHYMODE FIELD32(0xc0000000)
139
140/*
141 * Word2
142 */
143#define RXWI_W2_RSSI0 FIELD32(0x000000ff)
144#define RXWI_W2_RSSI1 FIELD32(0x0000ff00)
145#define RXWI_W2_RSSI2 FIELD32(0x00ff0000)
146
147/*
148 * Word3
149 */
150#define RXWI_W3_SNR0 FIELD32(0x000000ff)
151#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
152
153/*
154 * RX descriptor format for RX Ring. 114 * RX descriptor format for RX Ring.
155 */ 115 */
156 116
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index d9daa9c406fa..6c1ff4c15c84 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -177,16 +177,15 @@ struct rt2x00_chip {
177#define RT2573 0x2573 177#define RT2573 0x2573
178#define RT2860 0x2860 /* 2.4GHz PCI/CB */ 178#define RT2860 0x2860 /* 2.4GHz PCI/CB */
179#define RT2870 0x2870 179#define RT2870 0x2870
180#define RT2872 0x2872 180#define RT2872 0x2872 /* WSOC */
181#define RT2880 0x2880 /* WSOC */
182#define RT2883 0x2883 /* WSOC */ 181#define RT2883 0x2883 /* WSOC */
183#define RT2890 0x2890 /* 2.4GHz PCIe */
184#define RT3052 0x3052 /* WSOC */
185#define RT3070 0x3070 182#define RT3070 0x3070
186#define RT3071 0x3071 183#define RT3071 0x3071
187#define RT3090 0x3090 /* 2.4GHz PCIe */ 184#define RT3090 0x3090 /* 2.4GHz PCIe */
188#define RT3390 0x3390 185#define RT3390 0x3390
189#define RT3572 0x3572 186#define RT3572 0x3572
187#define RT3593 0x3593 /* PCIe */
188#define RT3883 0x3883 /* WSOC */
190 189
191 u16 rf; 190 u16 rf;
192 u16 rev; 191 u16 rev;
@@ -550,8 +549,10 @@ struct rt2x00lib_ops {
550 void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, 549 void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
551 struct sk_buff *skb, 550 struct sk_buff *skb,
552 struct txentry_desc *txdesc); 551 struct txentry_desc *txdesc);
553 int (*write_tx_data) (struct queue_entry *entry); 552 int (*write_tx_data) (struct queue_entry *entry,
554 void (*write_beacon) (struct queue_entry *entry); 553 struct txentry_desc *txdesc);
554 void (*write_beacon) (struct queue_entry *entry,
555 struct txentry_desc *txdesc);
555 int (*get_tx_data_len) (struct queue_entry *entry); 556 int (*get_tx_data_len) (struct queue_entry *entry);
556 void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, 557 void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
557 const enum data_queue_qid queue); 558 const enum data_queue_qid queue);
@@ -930,12 +931,12 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
930 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); 931 rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev);
931} 932}
932 933
933static inline char rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt) 934static inline bool rt2x00_rt(struct rt2x00_dev *rt2x00dev, const u16 rt)
934{ 935{
935 return (rt2x00dev->chip.rt == rt); 936 return (rt2x00dev->chip.rt == rt);
936} 937}
937 938
938static inline char rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf) 939static inline bool rt2x00_rf(struct rt2x00_dev *rt2x00dev, const u16 rf)
939{ 940{
940 return (rt2x00dev->chip.rf == rf); 941 return (rt2x00dev->chip.rf == rf);
941} 942}
@@ -945,6 +946,24 @@ static inline u16 rt2x00_rev(struct rt2x00_dev *rt2x00dev)
945 return rt2x00dev->chip.rev; 946 return rt2x00dev->chip.rev;
946} 947}
947 948
949static inline bool rt2x00_rt_rev(struct rt2x00_dev *rt2x00dev,
950 const u16 rt, const u16 rev)
951{
952 return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) == rev);
953}
954
955static inline bool rt2x00_rt_rev_lt(struct rt2x00_dev *rt2x00dev,
956 const u16 rt, const u16 rev)
957{
958 return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) < rev);
959}
960
961static inline bool rt2x00_rt_rev_gte(struct rt2x00_dev *rt2x00dev,
962 const u16 rt, const u16 rev)
963{
964 return (rt2x00_rt(rt2x00dev, rt) && rt2x00_rev(rt2x00dev) >= rev);
965}
966
948static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev, 967static inline void rt2x00_set_chip_intf(struct rt2x00_dev *rt2x00dev,
949 enum rt2x00_chip_intf intf) 968 enum rt2x00_chip_intf intf)
950{ 969{
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index d291c7862e10..583dacd8d241 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -128,6 +128,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
128 128
129 /* Pull buffer to correct size */ 129 /* Pull buffer to correct size */
130 skb_pull(skb, txdesc->iv_len); 130 skb_pull(skb, txdesc->iv_len);
131 txdesc->length -= txdesc->iv_len;
131 132
132 /* IV/EIV data has officially been stripped */ 133 /* IV/EIV data has officially been stripped */
133 skbdesc->flags |= SKBDESC_IV_STRIPPED; 134 skbdesc->flags |= SKBDESC_IV_STRIPPED;
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 9569fb4e5bc5..e9fe93fd8042 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -156,10 +156,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
156 enum rt2x00_dump_type type, struct sk_buff *skb) 156 enum rt2x00_dump_type type, struct sk_buff *skb)
157{ 157{
158 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; 158 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
159 struct skb_frame_desc *desc = get_skb_frame_desc(skb); 159 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
160 struct sk_buff *skbcopy; 160 struct sk_buff *skbcopy;
161 struct rt2x00dump_hdr *dump_hdr; 161 struct rt2x00dump_hdr *dump_hdr;
162 struct timeval timestamp; 162 struct timeval timestamp;
163 u32 data_len;
163 164
164 do_gettimeofday(&timestamp); 165 do_gettimeofday(&timestamp);
165 166
@@ -171,7 +172,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
171 return; 172 return;
172 } 173 }
173 174
174 skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len, 175 data_len = skb->len;
176 if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
177 data_len -= skbdesc->desc_len;
178
179 skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
175 GFP_ATOMIC); 180 GFP_ATOMIC);
176 if (!skbcopy) { 181 if (!skbcopy) {
177 DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); 182 DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
@@ -181,18 +186,20 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
181 dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr)); 186 dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
182 dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); 187 dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
183 dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); 188 dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
184 dump_hdr->desc_length = cpu_to_le32(desc->desc_len); 189 dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len);
185 dump_hdr->data_length = cpu_to_le32(skb->len); 190 dump_hdr->data_length = cpu_to_le32(data_len);
186 dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); 191 dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
187 dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); 192 dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
188 dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev); 193 dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
189 dump_hdr->type = cpu_to_le16(type); 194 dump_hdr->type = cpu_to_le16(type);
190 dump_hdr->queue_index = desc->entry->queue->qid; 195 dump_hdr->queue_index = skbdesc->entry->queue->qid;
191 dump_hdr->entry_index = desc->entry->entry_idx; 196 dump_hdr->entry_index = skbdesc->entry->entry_idx;
192 dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); 197 dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
193 dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); 198 dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
194 199
195 memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len); 200 if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
201 memcpy(skb_put(skbcopy, skbdesc->desc_len), skbdesc->desc,
202 skbdesc->desc_len);
196 memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len); 203 memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
197 204
198 skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); 205 skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
@@ -700,8 +707,6 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
700exit: 707exit:
701 rt2x00debug_deregister(rt2x00dev); 708 rt2x00debug_deregister(rt2x00dev);
702 ERROR(rt2x00dev, "Failed to register debug handler.\n"); 709 ERROR(rt2x00dev, "Failed to register debug handler.\n");
703
704 return;
705} 710}
706 711
707void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) 712void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index eda73ba735a6..3ae468c4d760 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -435,7 +435,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
435 rx_status->mactime = rxdesc.timestamp; 435 rx_status->mactime = rxdesc.timestamp;
436 rx_status->rate_idx = rate_idx; 436 rx_status->rate_idx = rate_idx;
437 rx_status->signal = rxdesc.rssi; 437 rx_status->signal = rxdesc.rssi;
438 rx_status->noise = rxdesc.noise;
439 rx_status->flag = rxdesc.flags; 438 rx_status->flag = rxdesc.flags;
440 rx_status->antenna = rt2x00dev->link.ant.active.rx; 439 rx_status->antenna = rt2x00dev->link.ant.active.rx;
441 440
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
index 727019a748e7..ed303b423e41 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dump.h
+++ b/drivers/net/wireless/rt2x00/rt2x00dump.h
@@ -62,11 +62,14 @@
62 * the tx event which has either succeeded or failed. A frame 62 * the tx event which has either succeeded or failed. A frame
63 * with this type should also have been reported with as a 63 * with this type should also have been reported with as a
64 * %DUMP_FRAME_TX frame. 64 * %DUMP_FRAME_TX frame.
65 * @DUMP_FRAME_BEACON: This beacon frame is queued for transmission to the
66 * hardware.
65 */ 67 */
66enum rt2x00_dump_type { 68enum rt2x00_dump_type {
67 DUMP_FRAME_RXDONE = 1, 69 DUMP_FRAME_RXDONE = 1,
68 DUMP_FRAME_TX = 2, 70 DUMP_FRAME_TX = 2,
69 DUMP_FRAME_TXDONE = 3, 71 DUMP_FRAME_TXDONE = 3,
72 DUMP_FRAME_BEACON = 4,
70}; 73};
71 74
72/** 75/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index 34beb00c4347..b818a43c4672 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -79,7 +79,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
79 ERROR(rt2x00dev, 79 ERROR(rt2x00dev,
80 "Current firmware does not support detected chipset.\n"); 80 "Current firmware does not support detected chipset.\n");
81 goto exit; 81 goto exit;
82 }; 82 }
83 83
84 rt2x00dev->fw = fw; 84 rt2x00dev->fw = fw;
85 85
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index 1056c92143a8..5a407602ce3e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -35,6 +35,7 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
35{ 35{
36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
37 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; 37 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
38 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
38 39
39 if (tx_info->control.sta) 40 if (tx_info->control.sta)
40 txdesc->mpdu_density = 41 txdesc->mpdu_density =
@@ -66,4 +67,20 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
66 __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); 67 __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
67 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) 68 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
68 __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); 69 __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
70
71 /*
72 * Determine IFS values
73 * - Use TXOP_BACKOFF for management frames
74 * - Use TXOP_SIFS for fragment bursts
75 * - Use TXOP_HTTXOP for everything else
76 *
77 * Note: rt2800 devices won't use CTS protection (if used)
78 * for frames not transmitted with TXOP_HTTXOP
79 */
80 if (ieee80211_is_mgmt(hdr->frame_control))
81 txdesc->txop = TXOP_BACKOFF;
82 else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
83 txdesc->txop = TXOP_SIFS;
84 else
85 txdesc->txop = TXOP_HTTXOP;
69} 86}
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index cf3f1c0c4382..a016f7ccde29 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -63,11 +63,10 @@ EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
63/* 63/*
64 * TX data handlers. 64 * TX data handlers.
65 */ 65 */
66int rt2x00pci_write_tx_data(struct queue_entry *entry) 66int rt2x00pci_write_tx_data(struct queue_entry *entry,
67 struct txentry_desc *txdesc)
67{ 68{
68 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 69 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
69 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
70 struct skb_frame_desc *skbdesc;
71 70
72 /* 71 /*
73 * This should not happen, we already checked the entry 72 * This should not happen, we already checked the entry
@@ -82,13 +81,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry)
82 return -EINVAL; 81 return -EINVAL;
83 } 82 }
84 83
85 /*
86 * Fill in skb descriptor
87 */
88 skbdesc = get_skb_frame_desc(entry->skb);
89 skbdesc->desc = entry_priv->desc;
90 skbdesc->desc_len = entry->queue->desc_size;
91
92 return 0; 84 return 0;
93} 85}
94EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); 86EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 8149ff68410a..51bcef3839ce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -92,7 +92,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
92 * This function will initialize the DMA and skb descriptor 92 * This function will initialize the DMA and skb descriptor
93 * to prepare the entry for the actual TX operation. 93 * to prepare the entry for the actual TX operation.
94 */ 94 */
95int rt2x00pci_write_tx_data(struct queue_entry *entry); 95int rt2x00pci_write_tx_data(struct queue_entry *entry,
96 struct txentry_desc *txdesc);
96 97
97/** 98/**
98 * struct queue_entry_priv_pci: Per entry PCI specific information 99 * struct queue_entry_priv_pci: Per entry PCI specific information
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a0bd36fc4d2e..20dbdd6fb904 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -334,12 +334,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
334 txdesc->aifs = entry->queue->aifs; 334 txdesc->aifs = entry->queue->aifs;
335 335
336 /* 336 /*
337 * Header and alignment information. 337 * Header and frame information.
338 */ 338 */
339 txdesc->length = entry->skb->len;
339 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 340 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
340 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) &&
341 (entry->skb->len > txdesc->header_length))
342 txdesc->l2pad = L2PAD_SIZE(txdesc->header_length);
343 341
344 /* 342 /*
345 * Check whether this frame is to be acked. 343 * Check whether this frame is to be acked.
@@ -423,6 +421,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
423{ 421{
424 struct data_queue *queue = entry->queue; 422 struct data_queue *queue = entry->queue;
425 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 423 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
424 enum rt2x00_dump_type dump_type;
426 425
427 rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); 426 rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
428 427
@@ -430,21 +429,26 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
430 * All processing on the frame has been completed, this means 429 * All processing on the frame has been completed, this means
431 * it is now ready to be dumped to userspace through debugfs. 430 * it is now ready to be dumped to userspace through debugfs.
432 */ 431 */
433 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); 432 dump_type = (txdesc->queue == QID_BEACON) ?
433 DUMP_FRAME_BEACON : DUMP_FRAME_TX;
434 rt2x00debug_dump_frame(rt2x00dev, dump_type, entry->skb);
435}
436
437static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
438 struct txentry_desc *txdesc)
439{
440 struct data_queue *queue = entry->queue;
441 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
434 442
435 /* 443 /*
436 * Check if we need to kick the queue, there are however a few rules 444 * Check if we need to kick the queue, there are however a few rules
437 * 1) Don't kick beacon queue 445 * 1) Don't kick unless this is the last in frame in a burst.
438 * 2) Don't kick unless this is the last in frame in a burst.
439 * When the burst flag is set, this frame is always followed 446 * When the burst flag is set, this frame is always followed
440 * by another frame which in some way are related to eachother. 447 * by another frame which in some way are related to eachother.
441 * This is true for fragments, RTS or CTS-to-self frames. 448 * This is true for fragments, RTS or CTS-to-self frames.
442 * 3) Rule 2 can be broken when the available entries 449 * 2) Rule 1 can be broken when the available entries
443 * in the queue are less then a certain threshold. 450 * in the queue are less then a certain threshold.
444 */ 451 */
445 if (entry->queue->qid == QID_BEACON)
446 return;
447
448 if (rt2x00queue_threshold(queue) || 452 if (rt2x00queue_threshold(queue) ||
449 !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) 453 !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
450 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); 454 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
@@ -526,7 +530,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
526 * call failed. Since we always return NETDEV_TX_OK to mac80211, 530 * call failed. Since we always return NETDEV_TX_OK to mac80211,
527 * this frame will simply be dropped. 531 * this frame will simply be dropped.
528 */ 532 */
529 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { 533 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry,
534 &txdesc))) {
530 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 535 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
531 entry->skb = NULL; 536 entry->skb = NULL;
532 return -EIO; 537 return -EIO;
@@ -539,6 +544,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
539 544
540 rt2x00queue_index_inc(queue, Q_INDEX); 545 rt2x00queue_index_inc(queue, Q_INDEX);
541 rt2x00queue_write_tx_descriptor(entry, &txdesc); 546 rt2x00queue_write_tx_descriptor(entry, &txdesc);
547 rt2x00queue_kick_tx_queue(entry, &txdesc);
542 548
543 return 0; 549 return 0;
544} 550}
@@ -550,7 +556,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
550 struct rt2x00_intf *intf = vif_to_intf(vif); 556 struct rt2x00_intf *intf = vif_to_intf(vif);
551 struct skb_frame_desc *skbdesc; 557 struct skb_frame_desc *skbdesc;
552 struct txentry_desc txdesc; 558 struct txentry_desc txdesc;
553 __le32 desc[16];
554 559
555 if (unlikely(!intf->beacon)) 560 if (unlikely(!intf->beacon))
556 return -ENOBUFS; 561 return -ENOBUFS;
@@ -583,19 +588,10 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
583 rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); 588 rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
584 589
585 /* 590 /*
586 * For the descriptor we use a local array from where the
587 * driver can move it to the correct location required for
588 * the hardware.
589 */
590 memset(desc, 0, sizeof(desc));
591
592 /*
593 * Fill in skb descriptor 591 * Fill in skb descriptor
594 */ 592 */
595 skbdesc = get_skb_frame_desc(intf->beacon->skb); 593 skbdesc = get_skb_frame_desc(intf->beacon->skb);
596 memset(skbdesc, 0, sizeof(*skbdesc)); 594 memset(skbdesc, 0, sizeof(*skbdesc));
597 skbdesc->desc = desc;
598 skbdesc->desc_len = intf->beacon->queue->desc_size;
599 skbdesc->entry = intf->beacon; 595 skbdesc->entry = intf->beacon;
600 596
601 /* 597 /*
@@ -604,12 +600,9 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
604 rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); 600 rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
605 601
606 /* 602 /*
607 * Send beacon to hardware. 603 * Send beacon to hardware and enable beacon genaration..
608 * Also enable beacon generation, which might have been disabled
609 * by the driver during the config_beacon() callback function.
610 */ 604 */
611 rt2x00dev->ops->lib->write_beacon(intf->beacon); 605 rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc);
612 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
613 606
614 mutex_unlock(&intf->beacon_skb_mutex); 607 mutex_unlock(&intf->beacon_skb_mutex);
615 608
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index c1e482bb37b3..f79170849add 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -94,12 +94,15 @@ enum data_queue_qid {
94 * mac80211 but was stripped for processing by the driver. 94 * mac80211 but was stripped for processing by the driver.
95 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211, 95 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
96 * don't try to pass it back. 96 * don't try to pass it back.
97 * @SKBDESC_DESC_IN_SKB: The descriptor is at the start of the
98 * skb, instead of in the desc field.
97 */ 99 */
98enum skb_frame_desc_flags { 100enum skb_frame_desc_flags {
99 SKBDESC_DMA_MAPPED_RX = 1 << 0, 101 SKBDESC_DMA_MAPPED_RX = 1 << 0,
100 SKBDESC_DMA_MAPPED_TX = 1 << 1, 102 SKBDESC_DMA_MAPPED_TX = 1 << 1,
101 SKBDESC_IV_STRIPPED = 1 << 2, 103 SKBDESC_IV_STRIPPED = 1 << 2,
102 SKBDESC_NOT_MAC80211 = 1 << 3, 104 SKBDESC_NOT_MAC80211 = 1 << 3,
105 SKBDESC_DESC_IN_SKB = 1 << 4,
103}; 106};
104 107
105/** 108/**
@@ -183,7 +186,6 @@ enum rxdone_entry_desc_flags {
183 * @timestamp: RX Timestamp 186 * @timestamp: RX Timestamp
184 * @signal: Signal of the received frame. 187 * @signal: Signal of the received frame.
185 * @rssi: RSSI of the received frame. 188 * @rssi: RSSI of the received frame.
186 * @noise: Measured noise during frame reception.
187 * @size: Data size of the received frame. 189 * @size: Data size of the received frame.
188 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). 190 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
189 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). 191 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
@@ -197,7 +199,6 @@ struct rxdone_entry_desc {
197 u64 timestamp; 199 u64 timestamp;
198 int signal; 200 int signal;
199 int rssi; 201 int rssi;
200 int noise;
201 int size; 202 int size;
202 int flags; 203 int flags;
203 int dev_flags; 204 int dev_flags;
@@ -287,8 +288,8 @@ enum txentry_desc_flags {
287 * 288 *
288 * @flags: Descriptor flags (See &enum queue_entry_flags). 289 * @flags: Descriptor flags (See &enum queue_entry_flags).
289 * @queue: Queue identification (See &enum data_queue_qid). 290 * @queue: Queue identification (See &enum data_queue_qid).
291 * @length: Length of the entire frame.
290 * @header_length: Length of 802.11 header. 292 * @header_length: Length of 802.11 header.
291 * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary.
292 * @length_high: PLCP length high word. 293 * @length_high: PLCP length high word.
293 * @length_low: PLCP length low word. 294 * @length_low: PLCP length low word.
294 * @signal: PLCP signal. 295 * @signal: PLCP signal.
@@ -301,6 +302,7 @@ enum txentry_desc_flags {
301 * @retry_limit: Max number of retries. 302 * @retry_limit: Max number of retries.
302 * @aifs: AIFS value. 303 * @aifs: AIFS value.
303 * @ifs: IFS value. 304 * @ifs: IFS value.
305 * @txop: IFS value for 11n capable chips.
304 * @cw_min: cwmin value. 306 * @cw_min: cwmin value.
305 * @cw_max: cwmax value. 307 * @cw_max: cwmax value.
306 * @cipher: Cipher type used for encryption. 308 * @cipher: Cipher type used for encryption.
@@ -313,8 +315,8 @@ struct txentry_desc {
313 315
314 enum data_queue_qid queue; 316 enum data_queue_qid queue;
315 317
318 u16 length;
316 u16 header_length; 319 u16 header_length;
317 u16 l2pad;
318 320
319 u16 length_high; 321 u16 length_high;
320 u16 length_low; 322 u16 length_low;
@@ -330,6 +332,7 @@ struct txentry_desc {
330 short retry_limit; 332 short retry_limit;
331 short aifs; 333 short aifs;
332 short ifs; 334 short ifs;
335 short txop;
333 short cw_min; 336 short cw_min;
334 short cw_max; 337 short cw_max;
335 338
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 603bfc0adaa3..b9fe94873ee0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -101,6 +101,16 @@ enum ifs {
101}; 101};
102 102
103/* 103/*
104 * IFS backoff values for HT devices
105 */
106enum txop {
107 TXOP_HTTXOP = 0,
108 TXOP_PIFS = 1,
109 TXOP_SIFS = 2,
110 TXOP_BACKOFF = 3,
111};
112
113/*
104 * Cipher types for hardware encryption 114 * Cipher types for hardware encryption
105 */ 115 */
106enum cipher { 116enum cipher {
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index f9a7f8b17411..bd1546ba7ad2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -216,12 +216,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
216 rt2x00lib_txdone(entry, &txdesc); 216 rt2x00lib_txdone(entry, &txdesc);
217} 217}
218 218
219int rt2x00usb_write_tx_data(struct queue_entry *entry) 219int rt2x00usb_write_tx_data(struct queue_entry *entry,
220 struct txentry_desc *txdesc)
220{ 221{
221 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 222 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
222 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 223 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
223 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 224 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
224 struct skb_frame_desc *skbdesc;
225 u32 length; 225 u32 length;
226 226
227 /* 227 /*
@@ -231,13 +231,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
231 memset(entry->skb->data, 0, entry->queue->desc_size); 231 memset(entry->skb->data, 0, entry->queue->desc_size);
232 232
233 /* 233 /*
234 * Fill in skb descriptor
235 */
236 skbdesc = get_skb_frame_desc(entry->skb);
237 skbdesc->desc = entry->skb->data;
238 skbdesc->desc_len = entry->queue->desc_size;
239
240 /*
241 * USB devices cannot blindly pass the skb->len as the 234 * USB devices cannot blindly pass the skb->len as the
242 * length of the data to usb_fill_bulk_urb. Pass the skb 235 * length of the data to usb_fill_bulk_urb. Pass the skb
243 * to the driver to determine what the length should be. 236 * to the driver to determine what the length should be.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 3da6841b5d42..621d0f829251 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -376,7 +376,8 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
376 * This function will initialize the URB and skb descriptor 376 * This function will initialize the URB and skb descriptor
377 * to prepare the entry for the actual TX operation. 377 * to prepare the entry for the actual TX operation.
378 */ 378 */
379int rt2x00usb_write_tx_data(struct queue_entry *entry); 379int rt2x00usb_write_tx_data(struct queue_entry *entry,
380 struct txentry_desc *txdesc);
380 381
381/** 382/**
382 * struct queue_entry_priv_usb: Per entry USB specific information 383 * struct queue_entry_priv_usb: Per entry USB specific information
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 432e75f960b7..2e3076f67535 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1764,7 +1764,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1764 struct txentry_desc *txdesc) 1764 struct txentry_desc *txdesc)
1765{ 1765{
1766 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1766 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1767 __le32 *txd = skbdesc->desc; 1767 struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
1768 __le32 *txd = entry_priv->desc;
1768 u32 word; 1769 u32 word;
1769 1770
1770 /* 1771 /*
@@ -1802,17 +1803,23 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1802 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); 1803 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
1803 rt2x00_desc_write(txd, 5, word); 1804 rt2x00_desc_write(txd, 5, word);
1804 1805
1805 rt2x00_desc_read(txd, 6, &word); 1806 if (txdesc->queue != QID_BEACON) {
1806 rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, 1807 rt2x00_desc_read(txd, 6, &word);
1807 skbdesc->skb_dma); 1808 rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
1808 rt2x00_desc_write(txd, 6, word); 1809 skbdesc->skb_dma);
1810 rt2x00_desc_write(txd, 6, word);
1809 1811
1810 if (skbdesc->desc_len > TXINFO_SIZE) {
1811 rt2x00_desc_read(txd, 11, &word); 1812 rt2x00_desc_read(txd, 11, &word);
1812 rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); 1813 rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0,
1814 txdesc->length);
1813 rt2x00_desc_write(txd, 11, word); 1815 rt2x00_desc_write(txd, 11, word);
1814 } 1816 }
1815 1817
1818 /*
1819 * Writing TXD word 0 must the last to prevent a race condition with
1820 * the device, whereby the device may take hold of the TXD before we
1821 * finished updating it.
1822 */
1816 rt2x00_desc_read(txd, 0, &word); 1823 rt2x00_desc_read(txd, 0, &word);
1817 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); 1824 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
1818 rt2x00_set_field32(&word, TXD_W0_VALID, 1); 1825 rt2x00_set_field32(&word, TXD_W0_VALID, 1);
@@ -1832,20 +1839,28 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1832 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, 1839 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
1833 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); 1840 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
1834 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); 1841 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
1835 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); 1842 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
1836 rt2x00_set_field32(&word, TXD_W0_BURST, 1843 rt2x00_set_field32(&word, TXD_W0_BURST,
1837 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 1844 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1838 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); 1845 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
1839 rt2x00_desc_write(txd, 0, word); 1846 rt2x00_desc_write(txd, 0, word);
1847
1848 /*
1849 * Register descriptor details in skb frame descriptor.
1850 */
1851 skbdesc->desc = txd;
1852 skbdesc->desc_len =
1853 (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
1840} 1854}
1841 1855
1842/* 1856/*
1843 * TX data initialization 1857 * TX data initialization
1844 */ 1858 */
1845static void rt61pci_write_beacon(struct queue_entry *entry) 1859static void rt61pci_write_beacon(struct queue_entry *entry,
1860 struct txentry_desc *txdesc)
1846{ 1861{
1847 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1862 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1848 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 1863 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1849 unsigned int beacon_base; 1864 unsigned int beacon_base;
1850 u32 reg; 1865 u32 reg;
1851 1866
@@ -1861,14 +1876,25 @@ static void rt61pci_write_beacon(struct queue_entry *entry)
1861 * Write entire beacon with descriptor to register. 1876 * Write entire beacon with descriptor to register.
1862 */ 1877 */
1863 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1878 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1864 rt2x00pci_register_multiwrite(rt2x00dev, 1879 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
1865 beacon_base, 1880 entry_priv->desc, TXINFO_SIZE);
1866 skbdesc->desc, skbdesc->desc_len); 1881 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
1867 rt2x00pci_register_multiwrite(rt2x00dev,
1868 beacon_base + skbdesc->desc_len,
1869 entry->skb->data, entry->skb->len); 1882 entry->skb->data, entry->skb->len);
1870 1883
1871 /* 1884 /*
1885 * Enable beaconing again.
1886 *
1887 * For Wi-Fi faily generated beacons between participating
1888 * stations. Set TBTT phase adaptive adjustment step to 8us.
1889 */
1890 rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1891
1892 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1893 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1894 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1895 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1896
1897 /*
1872 * Clean up beacon skb. 1898 * Clean up beacon skb.
1873 */ 1899 */
1874 dev_kfree_skb_any(entry->skb); 1900 dev_kfree_skb_any(entry->skb);
@@ -1880,23 +1906,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1880{ 1906{
1881 u32 reg; 1907 u32 reg;
1882 1908
1883 if (queue == QID_BEACON) {
1884 /*
1885 * For Wi-Fi faily generated beacons between participating
1886 * stations. Set TBTT phase adaptive adjustment step to 8us.
1887 */
1888 rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1889
1890 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
1891 if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
1892 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1893 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1894 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1895 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1896 }
1897 return;
1898 }
1899
1900 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg); 1909 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1901 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); 1910 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE));
1902 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); 1911 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK));
@@ -1968,12 +1977,8 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
1968 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) 1977 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1969 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 1978 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
1970 1979
1971 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 1980 rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
1972 rxdesc->cipher = 1981 rxdesc->cipher_status = rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
1973 rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
1974 rxdesc->cipher_status =
1975 rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
1976 }
1977 1982
1978 if (rxdesc->cipher != CIPHER_NONE) { 1983 if (rxdesc->cipher != CIPHER_NONE) {
1979 _rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv[0]); 1984 _rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv[0]);
@@ -2118,6 +2123,14 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2118 } 2123 }
2119} 2124}
2120 2125
2126static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev)
2127{
2128 struct ieee80211_conf conf = { .flags = 0 };
2129 struct rt2x00lib_conf libconf = { .conf = &conf };
2130
2131 rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
2132}
2133
2121static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) 2134static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2122{ 2135{
2123 struct rt2x00_dev *rt2x00dev = dev_instance; 2136 struct rt2x00_dev *rt2x00dev = dev_instance;
@@ -2165,6 +2178,12 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2165 rt2x00pci_register_write(rt2x00dev, 2178 rt2x00pci_register_write(rt2x00dev,
2166 M2H_CMD_DONE_CSR, 0xffffffff); 2179 M2H_CMD_DONE_CSR, 0xffffffff);
2167 2180
2181 /*
2182 * 4 - MCU Autowakeup interrupt.
2183 */
2184 if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP))
2185 rt61pci_wakeup(rt2x00dev);
2186
2168 return IRQ_HANDLED; 2187 return IRQ_HANDLED;
2169} 2188}
2170 2189
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index bb58d797fb72..e35bd19c3c5a 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -861,15 +861,15 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
861 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, 861 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
862 USB_MODE_SLEEP, REGISTER_TIMEOUT); 862 USB_MODE_SLEEP, REGISTER_TIMEOUT);
863 } else { 863 } else {
864 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
865 USB_MODE_WAKEUP, REGISTER_TIMEOUT);
866
867 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg); 864 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
868 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0); 865 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
869 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); 866 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
870 rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0); 867 rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
871 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0); 868 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
872 rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg); 869 rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
870
871 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
872 USB_MODE_WAKEUP, REGISTER_TIMEOUT);
873 } 873 }
874} 874}
875 875
@@ -1441,12 +1441,38 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1441 struct txentry_desc *txdesc) 1441 struct txentry_desc *txdesc)
1442{ 1442{
1443 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1443 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1444 __le32 *txd = skbdesc->desc; 1444 __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
1445 u32 word; 1445 u32 word;
1446 1446
1447 /* 1447 /*
1448 * Start writing the descriptor words. 1448 * Start writing the descriptor words.
1449 */ 1449 */
1450 rt2x00_desc_read(txd, 0, &word);
1451 rt2x00_set_field32(&word, TXD_W0_BURST,
1452 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1453 rt2x00_set_field32(&word, TXD_W0_VALID, 1);
1454 rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
1455 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
1456 rt2x00_set_field32(&word, TXD_W0_ACK,
1457 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
1458 rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
1459 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
1460 rt2x00_set_field32(&word, TXD_W0_OFDM,
1461 (txdesc->rate_mode == RATE_MODE_OFDM));
1462 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1463 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
1464 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
1465 rt2x00_set_field32(&word, TXD_W0_TKIP_MIC,
1466 test_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags));
1467 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
1468 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
1469 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
1470 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
1471 rt2x00_set_field32(&word, TXD_W0_BURST2,
1472 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1473 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
1474 rt2x00_desc_write(txd, 0, word);
1475
1450 rt2x00_desc_read(txd, 1, &word); 1476 rt2x00_desc_read(txd, 1, &word);
1451 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); 1477 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
1452 rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); 1478 rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
@@ -1475,51 +1501,24 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1475 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); 1501 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
1476 rt2x00_desc_write(txd, 5, word); 1502 rt2x00_desc_write(txd, 5, word);
1477 1503
1478 rt2x00_desc_read(txd, 0, &word); 1504 /*
1479 rt2x00_set_field32(&word, TXD_W0_BURST, 1505 * Register descriptor details in skb frame descriptor.
1480 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 1506 */
1481 rt2x00_set_field32(&word, TXD_W0_VALID, 1); 1507 skbdesc->desc = txd;
1482 rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, 1508 skbdesc->desc_len = TXD_DESC_SIZE;
1483 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
1484 rt2x00_set_field32(&word, TXD_W0_ACK,
1485 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
1486 rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
1487 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
1488 rt2x00_set_field32(&word, TXD_W0_OFDM,
1489 (txdesc->rate_mode == RATE_MODE_OFDM));
1490 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1491 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
1492 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
1493 rt2x00_set_field32(&word, TXD_W0_TKIP_MIC,
1494 test_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags));
1495 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
1496 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
1497 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
1498 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
1499 rt2x00_set_field32(&word, TXD_W0_BURST2,
1500 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1501 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
1502 rt2x00_desc_write(txd, 0, word);
1503} 1509}
1504 1510
1505/* 1511/*
1506 * TX data initialization 1512 * TX data initialization
1507 */ 1513 */
1508static void rt73usb_write_beacon(struct queue_entry *entry) 1514static void rt73usb_write_beacon(struct queue_entry *entry,
1515 struct txentry_desc *txdesc)
1509{ 1516{
1510 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1517 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1511 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1512 unsigned int beacon_base; 1518 unsigned int beacon_base;
1513 u32 reg; 1519 u32 reg;
1514 1520
1515 /* 1521 /*
1516 * Add the descriptor in front of the skb.
1517 */
1518 skb_push(entry->skb, entry->queue->desc_size);
1519 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
1520 skbdesc->desc = entry->skb->data;
1521
1522 /*
1523 * Disable beaconing while we are reloading the beacon data, 1522 * Disable beaconing while we are reloading the beacon data,
1524 * otherwise we might be sending out invalid data. 1523 * otherwise we might be sending out invalid data.
1525 */ 1524 */
@@ -1528,6 +1527,11 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1528 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 1527 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1529 1528
1530 /* 1529 /*
1530 * Take the descriptor in front of the skb into account.
1531 */
1532 skb_push(entry->skb, TXD_DESC_SIZE);
1533
1534 /*
1531 * Write entire beacon with descriptor to register. 1535 * Write entire beacon with descriptor to register.
1532 */ 1536 */
1533 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1537 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
@@ -1537,6 +1541,19 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1537 REGISTER_TIMEOUT32(entry->skb->len)); 1541 REGISTER_TIMEOUT32(entry->skb->len));
1538 1542
1539 /* 1543 /*
1544 * Enable beaconing again.
1545 *
1546 * For Wi-Fi faily generated beacons between participating stations.
1547 * Set TBTT phase adaptive adjustment step to 8us (default 16us)
1548 */
1549 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1550
1551 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1552 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1553 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1554 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1555
1556 /*
1540 * Clean up the beacon skb. 1557 * Clean up the beacon skb.
1541 */ 1558 */
1542 dev_kfree_skb(entry->skb); 1559 dev_kfree_skb(entry->skb);
@@ -1557,31 +1574,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
1557 return length; 1574 return length;
1558} 1575}
1559 1576
1560static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1561 const enum data_queue_qid queue)
1562{
1563 u32 reg;
1564
1565 if (queue != QID_BEACON) {
1566 rt2x00usb_kick_tx_queue(rt2x00dev, queue);
1567 return;
1568 }
1569
1570 /*
1571 * For Wi-Fi faily generated beacons between participating stations.
1572 * Set TBTT phase adaptive adjustment step to 8us (default 16us)
1573 */
1574 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1575
1576 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1577 if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
1578 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1579 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1580 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1581 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1582 }
1583}
1584
1585/* 1577/*
1586 * RX control handlers 1578 * RX control handlers
1587 */ 1579 */
@@ -1645,12 +1637,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
1645 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) 1637 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1646 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 1638 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
1647 1639
1648 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { 1640 rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
1649 rxdesc->cipher = 1641 rxdesc->cipher_status = rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
1650 rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG);
1651 rxdesc->cipher_status =
1652 rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR);
1653 }
1654 1642
1655 if (rxdesc->cipher != CIPHER_NONE) { 1643 if (rxdesc->cipher != CIPHER_NONE) {
1656 _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); 1644 _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]);
@@ -2266,7 +2254,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2266 .write_tx_data = rt2x00usb_write_tx_data, 2254 .write_tx_data = rt2x00usb_write_tx_data,
2267 .write_beacon = rt73usb_write_beacon, 2255 .write_beacon = rt73usb_write_beacon,
2268 .get_tx_data_len = rt73usb_get_tx_data_len, 2256 .get_tx_data_len = rt73usb_get_tx_data_len,
2269 .kick_tx_queue = rt73usb_kick_tx_queue, 2257 .kick_tx_queue = rt2x00usb_kick_tx_queue,
2270 .kill_tx_queue = rt2x00usb_kill_tx_queue, 2258 .kill_tx_queue = rt2x00usb_kill_tx_queue,
2271 .fill_rxdone = rt73usb_fill_rxdone, 2259 .fill_rxdone = rt73usb_fill_rxdone,
2272 .config_shared_key = rt73usb_config_shared_key, 2260 .config_shared_key = rt73usb_config_shared_key,
diff --git a/drivers/net/wireless/rtl818x/Kconfig b/drivers/net/wireless/rtl818x/Kconfig
new file mode 100644
index 000000000000..17d80fe556de
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/Kconfig
@@ -0,0 +1,88 @@
1#
2# RTL818X Wireless LAN device configuration
3#
4config RTL8180
5 tristate "Realtek 8180/8185 PCI support"
6 depends on MAC80211 && PCI && EXPERIMENTAL
7 select EEPROM_93CX6
8 ---help---
9 This is a driver for RTL8180 and RTL8185 based cards.
10 These are PCI based chips found in cards such as:
11
12 (RTL8185 802.11g)
13 A-Link WL54PC
14
15 (RTL8180 802.11b)
16 Belkin F5D6020 v3
17 Belkin F5D6020 v3
18 Dlink DWL-610
19 Dlink DWL-510
20 Netgear MA521
21 Level-One WPC-0101
22 Acer Aspire 1357 LMi
23 VCTnet PC-11B1
24 Ovislink AirLive WL-1120PCM
25 Mentor WL-PCI
26 Linksys WPC11 v4
27 TrendNET TEW-288PI
28 D-Link DWL-520 Rev D
29 Repotec RP-WP7126
30 TP-Link TL-WN250/251
31 Zonet ZEW1000
32 Longshine LCS-8031-R
33 HomeLine HLW-PCC200
34 GigaFast WF721-AEX
35 Planet WL-3553
36 Encore ENLWI-PCI1-NT
37 TrendNET TEW-266PC
38 Gigabyte GN-WLMR101
39 Siemens-fujitsu Amilo D1840W
40 Edimax EW-7126
41 PheeNet WL-11PCIR
42 Tonze PC-2100T
43 Planet WL-8303
44 Dlink DWL-650 v M1
45 Edimax EW-7106
46 Q-Tec 770WC
47 Topcom Skyr@cer 4011b
48 Roper FreeLan 802.11b (edition 2004)
49 Wistron Neweb Corp CB-200B
50 Pentagram HorNET
51 QTec 775WC
52 TwinMOS Booming B Series
53 Micronet SP906BB
54 Sweex LC700010
55 Surecom EP-9428
56 Safecom SWLCR-1100
57
58 Thanks to Realtek for their support!
59
60config RTL8187
61 tristate "Realtek 8187 and 8187B USB support"
62 depends on MAC80211 && USB
63 select EEPROM_93CX6
64 ---help---
65 This is a driver for RTL8187 and RTL8187B based cards.
66 These are USB based chips found in devices such as:
67
68 Netgear WG111v2
69 Level 1 WNC-0301USB
70 Micronet SP907GK V5
71 Encore ENUWI-G2
72 Trendnet TEW-424UB
73 ASUS P5B Deluxe/P5K Premium motherboards
74 Toshiba Satellite Pro series of laptops
75 Asus Wireless Link
76 Linksys WUSB54GC-EU v2
77 (v1 = rt73usb; v3 is rt2070-based,
78 use staging/rt3070 or try rt2800usb)
79
80 Thanks to Realtek for their support!
81
82# If possible, automatically enable LEDs for RTL8187.
83
84config RTL8187_LEDS
85 bool
86 depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
87 default y
88
diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h
index de3844fe06d8..4baf0cf0826f 100644
--- a/drivers/net/wireless/rtl818x/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180.h
@@ -55,6 +55,14 @@ struct rtl8180_tx_ring {
55 struct sk_buff_head queue; 55 struct sk_buff_head queue;
56}; 56};
57 57
58struct rtl8180_vif {
59 struct ieee80211_hw *dev;
60
61 /* beaconing */
62 struct delayed_work beacon_work;
63 bool enable_beacon;
64};
65
58struct rtl8180_priv { 66struct rtl8180_priv {
59 /* common between rtl818x drivers */ 67 /* common between rtl818x drivers */
60 struct rtl818x_csr __iomem *map; 68 struct rtl818x_csr __iomem *map;
@@ -78,6 +86,9 @@ struct rtl8180_priv {
78 u32 anaparam; 86 u32 anaparam;
79 u16 rfparam; 87 u16 rfparam;
80 u8 csthreshold; 88 u8 csthreshold;
89
90 /* sequence # */
91 u16 seqno;
81}; 92};
82 93
83void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 94void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 2131a442831a..515817de2905 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -188,6 +188,7 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
188 info->flags |= IEEE80211_TX_STAT_ACK; 188 info->flags |= IEEE80211_TX_STAT_ACK;
189 189
190 info->status.rates[0].count = (flags & 0xFF) + 1; 190 info->status.rates[0].count = (flags & 0xFF) + 1;
191 info->status.rates[1].idx = -1;
191 192
192 ieee80211_tx_status_irqsafe(dev, skb); 193 ieee80211_tx_status_irqsafe(dev, skb);
193 if (ring->entries - skb_queue_len(&ring->queue) == 2) 194 if (ring->entries - skb_queue_len(&ring->queue) == 2)
@@ -233,6 +234,7 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
233static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 234static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
234{ 235{
235 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 236 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
237 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
236 struct rtl8180_priv *priv = dev->priv; 238 struct rtl8180_priv *priv = dev->priv;
237 struct rtl8180_tx_ring *ring; 239 struct rtl8180_tx_ring *ring;
238 struct rtl8180_tx_desc *entry; 240 struct rtl8180_tx_desc *entry;
@@ -284,6 +286,14 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
284 } 286 }
285 287
286 spin_lock_irqsave(&priv->lock, flags); 288 spin_lock_irqsave(&priv->lock, flags);
289
290 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
291 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
292 priv->seqno += 0x10;
293 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
294 hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
295 }
296
287 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; 297 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
288 entry = &ring->desc[idx]; 298 entry = &ring->desc[idx];
289 299
@@ -297,7 +307,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
297 entry->flags = cpu_to_le32(tx_flags); 307 entry->flags = cpu_to_le32(tx_flags);
298 __skb_queue_tail(&ring->queue, skb); 308 __skb_queue_tail(&ring->queue, skb);
299 if (ring->entries - skb_queue_len(&ring->queue) < 2) 309 if (ring->entries - skb_queue_len(&ring->queue) < 2)
300 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); 310 ieee80211_stop_queue(dev, prio);
311
301 spin_unlock_irqrestore(&priv->lock, flags); 312 spin_unlock_irqrestore(&priv->lock, flags);
302 313
303 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); 314 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -652,10 +663,59 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
652 rtl8180_free_tx_ring(dev, i); 663 rtl8180_free_tx_ring(dev, i);
653} 664}
654 665
666static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
667{
668 struct rtl8180_priv *priv = dev->priv;
669
670 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
671 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
672}
673
674void rtl8180_beacon_work(struct work_struct *work)
675{
676 struct rtl8180_vif *vif_priv =
677 container_of(work, struct rtl8180_vif, beacon_work.work);
678 struct ieee80211_vif *vif =
679 container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
680 struct ieee80211_hw *dev = vif_priv->dev;
681 struct ieee80211_mgmt *mgmt;
682 struct sk_buff *skb;
683 int err = 0;
684
685 /* don't overflow the tx ring */
686 if (ieee80211_queue_stopped(dev, 0))
687 goto resched;
688
689 /* grab a fresh beacon */
690 skb = ieee80211_beacon_get(dev, vif);
691
692 /*
693 * update beacon timestamp w/ TSF value
694 * TODO: make hardware update beacon timestamp
695 */
696 mgmt = (struct ieee80211_mgmt *)skb->data;
697 mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev));
698
699 /* TODO: use actual beacon queue */
700 skb_set_queue_mapping(skb, 0);
701
702 err = rtl8180_tx(dev, skb);
703 WARN_ON(err);
704
705resched:
706 /*
707 * schedule next beacon
708 * TODO: use hardware support for beacon timing
709 */
710 schedule_delayed_work(&vif_priv->beacon_work,
711 usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
712}
713
655static int rtl8180_add_interface(struct ieee80211_hw *dev, 714static int rtl8180_add_interface(struct ieee80211_hw *dev,
656 struct ieee80211_vif *vif) 715 struct ieee80211_vif *vif)
657{ 716{
658 struct rtl8180_priv *priv = dev->priv; 717 struct rtl8180_priv *priv = dev->priv;
718 struct rtl8180_vif *vif_priv;
659 719
660 /* 720 /*
661 * We only support one active interface at a time. 721 * We only support one active interface at a time.
@@ -665,6 +725,7 @@ static int rtl8180_add_interface(struct ieee80211_hw *dev,
665 725
666 switch (vif->type) { 726 switch (vif->type) {
667 case NL80211_IFTYPE_STATION: 727 case NL80211_IFTYPE_STATION:
728 case NL80211_IFTYPE_ADHOC:
668 break; 729 break;
669 default: 730 default:
670 return -EOPNOTSUPP; 731 return -EOPNOTSUPP;
@@ -672,6 +733,12 @@ static int rtl8180_add_interface(struct ieee80211_hw *dev,
672 733
673 priv->vif = vif; 734 priv->vif = vif;
674 735
736 /* Initialize driver private area */
737 vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
738 vif_priv->dev = dev;
739 INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work);
740 vif_priv->enable_beacon = false;
741
675 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 742 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
676 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], 743 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
677 le32_to_cpu(*(__le32 *)vif->addr)); 744 le32_to_cpu(*(__le32 *)vif->addr));
@@ -705,8 +772,11 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
705 u32 changed) 772 u32 changed)
706{ 773{
707 struct rtl8180_priv *priv = dev->priv; 774 struct rtl8180_priv *priv = dev->priv;
775 struct rtl8180_vif *vif_priv;
708 int i; 776 int i;
709 777
778 vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
779
710 if (changed & BSS_CHANGED_BSSID) { 780 if (changed & BSS_CHANGED_BSSID) {
711 for (i = 0; i < ETH_ALEN; i++) 781 for (i = 0; i < ETH_ALEN; i++)
712 rtl818x_iowrite8(priv, &priv->map->BSSID[i], 782 rtl818x_iowrite8(priv, &priv->map->BSSID[i],
@@ -721,13 +791,22 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
721 } 791 }
722 792
723 if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) 793 if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
724 priv->rf->conf_erp(dev, info); 794 priv->rf->conf_erp(dev, info);
795
796 if (changed & BSS_CHANGED_BEACON_ENABLED)
797 vif_priv->enable_beacon = info->enable_beacon;
798
799 if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
800 cancel_delayed_work_sync(&vif_priv->beacon_work);
801 if (vif_priv->enable_beacon)
802 schedule_work(&vif_priv->beacon_work.work);
803 }
725} 804}
726 805
727static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, int mc_count, 806static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev,
728 struct dev_addr_list *mc_list) 807 struct netdev_hw_addr_list *mc_list)
729{ 808{
730 return mc_count; 809 return netdev_hw_addr_list_count(mc_list);
731} 810}
732 811
733static void rtl8180_configure_filter(struct ieee80211_hw *dev, 812static void rtl8180_configure_filter(struct ieee80211_hw *dev,
@@ -762,14 +841,6 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
762 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 841 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
763} 842}
764 843
765static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
766{
767 struct rtl8180_priv *priv = dev->priv;
768
769 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
770 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
771}
772
773static const struct ieee80211_ops rtl8180_ops = { 844static const struct ieee80211_ops rtl8180_ops = {
774 .tx = rtl8180_tx, 845 .tx = rtl8180_tx,
775 .start = rtl8180_start, 846 .start = rtl8180_start,
@@ -827,6 +898,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
827 const char *chip_name, *rf_name = NULL; 898 const char *chip_name, *rf_name = NULL;
828 u32 reg; 899 u32 reg;
829 u16 eeprom_val; 900 u16 eeprom_val;
901 u8 mac_addr[ETH_ALEN];
830 902
831 err = pci_enable_device(pdev); 903 err = pci_enable_device(pdev);
832 if (err) { 904 if (err) {
@@ -855,8 +927,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
855 goto err_free_reg; 927 goto err_free_reg;
856 } 928 }
857 929
858 if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) || 930 if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
859 (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) { 931 (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
860 printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n", 932 printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
861 pci_name(pdev)); 933 pci_name(pdev));
862 goto err_free_reg; 934 goto err_free_reg;
@@ -905,7 +977,9 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
905 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 977 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
906 IEEE80211_HW_RX_INCLUDES_FCS | 978 IEEE80211_HW_RX_INCLUDES_FCS |
907 IEEE80211_HW_SIGNAL_UNSPEC; 979 IEEE80211_HW_SIGNAL_UNSPEC;
908 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 980 dev->vif_data_size = sizeof(struct rtl8180_vif);
981 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
982 BIT(NL80211_IFTYPE_ADHOC);
909 dev->queues = 1; 983 dev->queues = 1;
910 dev->max_signal = 65; 984 dev->max_signal = 65;
911 985
@@ -987,12 +1061,13 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
987 eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); 1061 eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
988 } 1062 }
989 1063
990 eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3); 1064 eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3);
991 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { 1065 if (!is_valid_ether_addr(mac_addr)) {
992 printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" 1066 printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
993 " randomly generated MAC addr\n", pci_name(pdev)); 1067 " randomly generated MAC addr\n", pci_name(pdev));
994 random_ether_addr(dev->wiphy->perm_addr); 1068 random_ether_addr(mac_addr);
995 } 1069 }
1070 SET_IEEE80211_PERM_ADDR(dev, mac_addr);
996 1071
997 /* CCK TX power */ 1072 /* CCK TX power */
998 for (i = 0; i < 14; i += 2) { 1073 for (i = 0; i < 14; i += 2) {
@@ -1024,7 +1099,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
1024 } 1099 }
1025 1100
1026 printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", 1101 printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
1027 wiphy_name(dev->wiphy), dev->wiphy->perm_addr, 1102 wiphy_name(dev->wiphy), mac_addr,
1028 chip_name, priv->rf->name); 1103 chip_name, priv->rf->name);
1029 1104
1030 return 0; 1105 return 0;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 1d30792973f5..891b8490e349 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1194,9 +1194,9 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
1194} 1194}
1195 1195
1196static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, 1196static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
1197 int mc_count, struct dev_addr_list *mc_list) 1197 struct netdev_hw_addr_list *mc_list)
1198{ 1198{
1199 return mc_count; 1199 return netdev_hw_addr_list_count(mc_list);
1200} 1200}
1201 1201
1202static void rtl8187_configure_filter(struct ieee80211_hw *dev, 1202static void rtl8187_configure_filter(struct ieee80211_hw *dev,
@@ -1333,6 +1333,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1333 u16 txpwr, reg; 1333 u16 txpwr, reg;
1334 u16 product_id = le16_to_cpu(udev->descriptor.idProduct); 1334 u16 product_id = le16_to_cpu(udev->descriptor.idProduct);
1335 int err, i; 1335 int err, i;
1336 u8 mac_addr[ETH_ALEN];
1336 1337
1337 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); 1338 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
1338 if (!dev) { 1339 if (!dev) {
@@ -1390,12 +1391,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1390 udelay(10); 1391 udelay(10);
1391 1392
1392 eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, 1393 eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR,
1393 (__le16 __force *)dev->wiphy->perm_addr, 3); 1394 (__le16 __force *)mac_addr, 3);
1394 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { 1395 if (!is_valid_ether_addr(mac_addr)) {
1395 printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " 1396 printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly "
1396 "generated MAC address\n"); 1397 "generated MAC address\n");
1397 random_ether_addr(dev->wiphy->perm_addr); 1398 random_ether_addr(mac_addr);
1398 } 1399 }
1400 SET_IEEE80211_PERM_ADDR(dev, mac_addr);
1399 1401
1400 channel = priv->channels; 1402 channel = priv->channels;
1401 for (i = 0; i < 3; i++) { 1403 for (i = 0; i < 3; i++) {
@@ -1526,7 +1528,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1526 skb_queue_head_init(&priv->b_tx_status.queue); 1528 skb_queue_head_init(&priv->b_tx_status.queue);
1527 1529
1528 printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", 1530 printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
1529 wiphy_name(dev->wiphy), dev->wiphy->perm_addr, 1531 wiphy_name(dev->wiphy), mac_addr,
1530 chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); 1532 chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
1531 1533
1532#ifdef CONFIG_RTL8187_LEDS 1534#ifdef CONFIG_RTL8187_LEDS
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 785e0244e305..337fc7bec5a5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -51,3 +51,27 @@ config WL1271
51 51
52 If you choose to build a module, it'll be called wl1271. Say N if 52 If you choose to build a module, it'll be called wl1271. Say N if
53 unsure. 53 unsure.
54
55config WL1271_SPI
56 tristate "TI wl1271 SPI support"
57 depends on WL1271 && SPI_MASTER
58 ---help---
59 This module adds support for the SPI interface of adapters using
60 TI wl1271 chipset. Select this if your platform is using
61 the SPI bus.
62
63 If you choose to build a module, it'll be called wl1251_spi.
64 Say N if unsure.
65
66config WL1271_SDIO
67 tristate "TI wl1271 SDIO support"
68 depends on WL1271 && MMC && ARM
69 ---help---
70 This module adds support for the SDIO interface of adapters using
71 TI wl1271 chipset. Select this if your platform is using
72 the SDIO bus.
73
74 If you choose to build a module, it'll be called
75 wl1271_sdio. Say N if unsure.
76
77
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index f47ec94c16dc..27ddd2be0a91 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -7,10 +7,12 @@ obj-$(CONFIG_WL1251) += wl1251.o
7obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o 7obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o
8obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o 8obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
9 9
10wl1271-objs = wl1271_main.o wl1271_spi.o wl1271_cmd.o \ 10wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
11 wl1271_event.o wl1271_tx.o wl1271_rx.o \ 11 wl1271_event.o wl1271_tx.o wl1271_rx.o \
12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \ 12 wl1271_ps.o wl1271_acx.o wl1271_boot.o \
13 wl1271_init.o wl1271_debugfs.o wl1271_io.o 13 wl1271_init.o wl1271_debugfs.o
14 14
15wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o 15wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
16obj-$(CONFIG_WL1271) += wl1271.o 16obj-$(CONFIG_WL1271) += wl1271.o
17obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
18obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 37c61c19cae5..4f5f02a26e62 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -256,6 +256,8 @@ struct wl1251_debugfs {
256struct wl1251_if_operations { 256struct wl1251_if_operations {
257 void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); 257 void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
258 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); 258 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
259 void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
260 void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
259 void (*reset)(struct wl1251 *wl); 261 void (*reset)(struct wl1251 *wl);
260 void (*enable_irq)(struct wl1251 *wl); 262 void (*enable_irq)(struct wl1251 *wl);
261 void (*disable_irq)(struct wl1251 *wl); 263 void (*disable_irq)(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index d5ac79aeaa73..2545123931e8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -497,7 +497,8 @@ int wl1251_boot(struct wl1251 *wl)
497 /* 2. start processing NVS file */ 497 /* 2. start processing NVS file */
498 if (wl->use_eeprom) { 498 if (wl->use_eeprom) {
499 wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); 499 wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
500 msleep(4000); 500 /* Wait for EEPROM NVS burst read to complete */
501 msleep(40);
501 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); 502 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
502 } else { 503 } else {
503 ret = wl1251_boot_upload_nvs(wl); 504 ret = wl1251_boot_upload_nvs(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
index b89d2ac62efb..c545e9d5f512 100644
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -48,6 +48,26 @@ static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
48 wl->if_ops->write(wl, addr, &val, sizeof(u32)); 48 wl->if_ops->write(wl, addr, &val, sizeof(u32));
49} 49}
50 50
51static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
52{
53 u32 response;
54
55 if (wl->if_ops->read_elp)
56 wl->if_ops->read_elp(wl, addr, &response);
57 else
58 wl->if_ops->read(wl, addr, &response, sizeof(u32));
59
60 return response;
61}
62
63static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
64{
65 if (wl->if_ops->write_elp)
66 wl->if_ops->write_elp(wl, addr, val);
67 else
68 wl->if_ops->write(wl, addr, &val, sizeof(u32));
69}
70
51/* Memory target IO, address is translated to partition 0 */ 71/* Memory target IO, address is translated to partition 0 */
52void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); 72void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
53void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); 73void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 1c8226eee409..00b24282fc73 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -147,8 +147,8 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
147 u32 elp_reg; 147 u32 elp_reg;
148 148
149 elp_reg = ELPCTRL_WAKE_UP; 149 elp_reg = ELPCTRL_WAKE_UP;
150 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); 150 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
151 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 151 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
152 152
153 if (!(elp_reg & ELPCTRL_WLAN_READY)) 153 if (!(elp_reg & ELPCTRL_WLAN_READY))
154 wl1251_warning("WLAN not ready"); 154 wl1251_warning("WLAN not ready");
@@ -202,8 +202,8 @@ static int wl1251_chip_wakeup(struct wl1251 *wl)
202 goto out; 202 goto out;
203 } 203 }
204 204
205 /* No NVS from netlink, try to get it from the filesystem */ 205 if (wl->nvs == NULL && !wl->use_eeprom) {
206 if (wl->nvs == NULL) { 206 /* No NVS from netlink, try to get it from the filesystem */
207 ret = wl1251_fetch_nvs(wl); 207 ret = wl1251_fetch_nvs(wl);
208 if (ret < 0) 208 if (ret < 0)
209 goto out; 209 goto out;
@@ -857,6 +857,7 @@ out:
857} 857}
858 858
859static int wl1251_op_hw_scan(struct ieee80211_hw *hw, 859static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
860 struct ieee80211_vif *vif,
860 struct cfg80211_scan_request *req) 861 struct cfg80211_scan_request *req)
861{ 862{
862 struct wl1251 *wl = hw->priv; 863 struct wl1251 *wl = hw->priv;
@@ -1196,6 +1197,66 @@ static const struct ieee80211_ops wl1251_ops = {
1196 .conf_tx = wl1251_op_conf_tx, 1197 .conf_tx = wl1251_op_conf_tx,
1197}; 1198};
1198 1199
1200static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
1201{
1202 unsigned long timeout;
1203
1204 wl1251_reg_write32(wl, EE_ADDR, offset);
1205 wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
1206
1207 /* EE_CTL_READ clears when data is ready */
1208 timeout = jiffies + msecs_to_jiffies(100);
1209 while (1) {
1210 if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
1211 break;
1212
1213 if (time_after(jiffies, timeout))
1214 return -ETIMEDOUT;
1215
1216 msleep(1);
1217 }
1218
1219 *data = wl1251_reg_read32(wl, EE_DATA);
1220 return 0;
1221}
1222
1223static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
1224 u8 *data, size_t len)
1225{
1226 size_t i;
1227 int ret;
1228
1229 wl1251_reg_write32(wl, EE_START, 0);
1230
1231 for (i = 0; i < len; i++) {
1232 ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
1233 if (ret < 0)
1234 return ret;
1235 }
1236
1237 return 0;
1238}
1239
1240static int wl1251_read_eeprom_mac(struct wl1251 *wl)
1241{
1242 u8 mac[ETH_ALEN];
1243 int i, ret;
1244
1245 wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
1246
1247 ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
1248 if (ret < 0) {
1249 wl1251_warning("failed to read MAC address from EEPROM");
1250 return ret;
1251 }
1252
1253 /* MAC is stored in reverse order */
1254 for (i = 0; i < ETH_ALEN; i++)
1255 wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
1256
1257 return 0;
1258}
1259
1199static int wl1251_register_hw(struct wl1251 *wl) 1260static int wl1251_register_hw(struct wl1251 *wl)
1200{ 1261{
1201 int ret; 1262 int ret;
@@ -1231,7 +1292,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1231 wl->hw->channel_change_time = 10000; 1292 wl->hw->channel_change_time = 10000;
1232 1293
1233 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1294 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1234 IEEE80211_HW_NOISE_DBM |
1235 IEEE80211_HW_SUPPORTS_PS | 1295 IEEE80211_HW_SUPPORTS_PS |
1236 IEEE80211_HW_BEACON_FILTER | 1296 IEEE80211_HW_BEACON_FILTER |
1237 IEEE80211_HW_SUPPORTS_UAPSD; 1297 IEEE80211_HW_SUPPORTS_UAPSD;
@@ -1242,6 +1302,9 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1242 1302
1243 wl->hw->queues = 4; 1303 wl->hw->queues = 4;
1244 1304
1305 if (wl->use_eeprom)
1306 wl1251_read_eeprom_mac(wl);
1307
1245 ret = wl1251_register_hw(wl); 1308 ret = wl1251_register_hw(wl);
1246 if (ret) 1309 if (ret)
1247 goto out; 1310 goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 851dfb65e474..b55cb2bd459a 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -45,7 +45,7 @@ void wl1251_elp_work(struct work_struct *work)
45 goto out; 45 goto out;
46 46
47 wl1251_debug(DEBUG_PSM, "chip to elp"); 47 wl1251_debug(DEBUG_PSM, "chip to elp");
48 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 48 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
49 wl->elp = true; 49 wl->elp = true;
50 50
51out: 51out:
@@ -79,9 +79,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
79 start = jiffies; 79 start = jiffies;
80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); 80 timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
81 81
82 wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 82 wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
83 83
84 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 84 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
85 85
86 /* 86 /*
87 * FIXME: we should wait for irq from chip but, as a temporary 87 * FIXME: we should wait for irq from chip but, as a temporary
@@ -93,7 +93,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
93 return -ETIMEDOUT; 93 return -ETIMEDOUT;
94 } 94 }
95 msleep(1); 95 msleep(1);
96 elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); 96 elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
97 } 97 }
98 98
99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", 99 wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
index 0ca3b4326056..d16edd9bf06c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1251_reg.h
@@ -46,7 +46,14 @@
46#define SOR_CFG (REGISTERS_BASE + 0x0800) 46#define SOR_CFG (REGISTERS_BASE + 0x0800)
47#define ECPU_CTRL (REGISTERS_BASE + 0x0804) 47#define ECPU_CTRL (REGISTERS_BASE + 0x0804)
48#define HI_CFG (REGISTERS_BASE + 0x0808) 48#define HI_CFG (REGISTERS_BASE + 0x0808)
49
50/* EEPROM registers */
49#define EE_START (REGISTERS_BASE + 0x080C) 51#define EE_START (REGISTERS_BASE + 0x080C)
52#define EE_CTL (REGISTERS_BASE + 0x2000)
53#define EE_DATA (REGISTERS_BASE + 0x2004)
54#define EE_ADDR (REGISTERS_BASE + 0x2008)
55
56#define EE_CTL_READ 2
50 57
51#define CHIP_ID_B (REGISTERS_BASE + 0x5674) 58#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
52 59
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index 6f229e0990f4..851515836a7f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -74,12 +74,6 @@ static void wl1251_rx_status(struct wl1251 *wl,
74 74
75 status->signal = desc->rssi; 75 status->signal = desc->rssi;
76 76
77 /*
78 * FIXME: guessing that snr needs to be divided by two, otherwise
79 * the values don't make any sense
80 */
81 status->noise = desc->rssi - desc->snr / 2;
82
83 status->freq = ieee80211_channel_to_frequency(desc->channel); 77 status->freq = ieee80211_channel_to_frequency(desc->channel);
84 78
85 status->flag |= RX_FLAG_TSFT; 79 status->flag |= RX_FLAG_TSFT;
@@ -189,6 +183,4 @@ void wl1251_rx(struct wl1251 *wl)
189 183
190 /* Finally, we need to ACK the RX */ 184 /* Finally, we need to ACK the RX */
191 wl1251_rx_ack(wl); 185 wl1251_rx_ack(wl);
192
193 return;
194} 186}
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index 9423f22bdced..d234285c2c81 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -20,20 +20,14 @@
20 * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) 20 * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
21 */ 21 */
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/crc7.h>
24#include <linux/mod_devicetable.h> 23#include <linux/mod_devicetable.h>
25#include <linux/irq.h>
26#include <linux/mmc/sdio_func.h> 24#include <linux/mmc/sdio_func.h>
27#include <linux/mmc/sdio_ids.h> 25#include <linux/mmc/sdio_ids.h>
28#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/spi/wl12xx.h>
28#include <linux/irq.h>
29 29
30#include "wl1251.h" 30#include "wl1251.h"
31#include "wl12xx_80211.h"
32#include "wl1251_reg.h"
33#include "wl1251_ps.h"
34#include "wl1251_io.h"
35#include "wl1251_tx.h"
36#include "wl1251_debugfs.h"
37 31
38#ifndef SDIO_VENDOR_ID_TI 32#ifndef SDIO_VENDOR_ID_TI
39#define SDIO_VENDOR_ID_TI 0x104c 33#define SDIO_VENDOR_ID_TI 0x104c
@@ -43,6 +37,8 @@
43#define SDIO_DEVICE_ID_TI_WL1251 0x9066 37#define SDIO_DEVICE_ID_TI_WL1251 0x9066
44#endif 38#endif
45 39
40static struct wl12xx_platform_data *wl12xx_board_data;
41
46static struct sdio_func *wl_to_func(struct wl1251 *wl) 42static struct sdio_func *wl_to_func(struct wl1251 *wl)
47{ 43{
48 return wl->if_priv; 44 return wl->if_priv;
@@ -65,7 +61,8 @@ static const struct sdio_device_id wl1251_devices[] = {
65MODULE_DEVICE_TABLE(sdio, wl1251_devices); 61MODULE_DEVICE_TABLE(sdio, wl1251_devices);
66 62
67 63
68void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len) 64static void wl1251_sdio_read(struct wl1251 *wl, int addr,
65 void *buf, size_t len)
69{ 66{
70 int ret; 67 int ret;
71 struct sdio_func *func = wl_to_func(wl); 68 struct sdio_func *func = wl_to_func(wl);
@@ -77,7 +74,8 @@ void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
77 sdio_release_host(func); 74 sdio_release_host(func);
78} 75}
79 76
80void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len) 77static void wl1251_sdio_write(struct wl1251 *wl, int addr,
78 void *buf, size_t len)
81{ 79{
82 int ret; 80 int ret;
83 struct sdio_func *func = wl_to_func(wl); 81 struct sdio_func *func = wl_to_func(wl);
@@ -89,7 +87,33 @@ void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
89 sdio_release_host(func); 87 sdio_release_host(func);
90} 88}
91 89
92void wl1251_sdio_reset(struct wl1251 *wl) 90static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
91{
92 int ret = 0;
93 struct sdio_func *func = wl_to_func(wl);
94
95 sdio_claim_host(func);
96 *val = sdio_readb(func, addr, &ret);
97 sdio_release_host(func);
98
99 if (ret)
100 wl1251_error("sdio_readb failed (%d)", ret);
101}
102
103static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
104{
105 int ret = 0;
106 struct sdio_func *func = wl_to_func(wl);
107
108 sdio_claim_host(func);
109 sdio_writeb(func, val, addr, &ret);
110 sdio_release_host(func);
111
112 if (ret)
113 wl1251_error("sdio_writeb failed (%d)", ret);
114}
115
116static void wl1251_sdio_reset(struct wl1251 *wl)
93{ 117{
94} 118}
95 119
@@ -111,19 +135,64 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl)
111 sdio_release_host(func); 135 sdio_release_host(func);
112} 136}
113 137
114void wl1251_sdio_set_power(bool enable) 138/* Interrupts when using dedicated WLAN_IRQ pin */
139static irqreturn_t wl1251_line_irq(int irq, void *cookie)
140{
141 struct wl1251 *wl = cookie;
142
143 ieee80211_queue_work(wl->hw, &wl->irq_work);
144
145 return IRQ_HANDLED;
146}
147
148static void wl1251_enable_line_irq(struct wl1251 *wl)
115{ 149{
150 return enable_irq(wl->irq);
116} 151}
117 152
118struct wl1251_if_operations wl1251_sdio_ops = { 153static void wl1251_disable_line_irq(struct wl1251 *wl)
154{
155 return disable_irq(wl->irq);
156}
157
158static void wl1251_sdio_set_power(bool enable)
159{
160}
161
162static struct wl1251_if_operations wl1251_sdio_ops = {
119 .read = wl1251_sdio_read, 163 .read = wl1251_sdio_read,
120 .write = wl1251_sdio_write, 164 .write = wl1251_sdio_write,
165 .write_elp = wl1251_sdio_write_elp,
166 .read_elp = wl1251_sdio_read_elp,
121 .reset = wl1251_sdio_reset, 167 .reset = wl1251_sdio_reset,
122 .enable_irq = wl1251_sdio_enable_irq,
123 .disable_irq = wl1251_sdio_disable_irq,
124}; 168};
125 169
126int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) 170static int wl1251_platform_probe(struct platform_device *pdev)
171{
172 if (pdev->id != -1) {
173 wl1251_error("can only handle single device");
174 return -ENODEV;
175 }
176
177 wl12xx_board_data = pdev->dev.platform_data;
178 return 0;
179}
180
181/*
182 * Dummy platform_driver for passing platform_data to this driver,
183 * until we have a way to pass this through SDIO subsystem or
184 * some other way.
185 */
186static struct platform_driver wl1251_platform_driver = {
187 .driver = {
188 .name = "wl1251_data",
189 .owner = THIS_MODULE,
190 },
191 .probe = wl1251_platform_probe,
192};
193
194static int wl1251_sdio_probe(struct sdio_func *func,
195 const struct sdio_device_id *id)
127{ 196{
128 int ret; 197 int ret;
129 struct wl1251 *wl; 198 struct wl1251 *wl;
@@ -141,20 +210,50 @@ int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
141 goto release; 210 goto release;
142 211
143 sdio_set_block_size(func, 512); 212 sdio_set_block_size(func, 512);
213 sdio_release_host(func);
144 214
145 SET_IEEE80211_DEV(hw, &func->dev); 215 SET_IEEE80211_DEV(hw, &func->dev);
146 wl->if_priv = func; 216 wl->if_priv = func;
147 wl->if_ops = &wl1251_sdio_ops; 217 wl->if_ops = &wl1251_sdio_ops;
148 wl->set_power = wl1251_sdio_set_power; 218 wl->set_power = wl1251_sdio_set_power;
149 219
150 sdio_release_host(func); 220 if (wl12xx_board_data != NULL) {
221 wl->set_power = wl12xx_board_data->set_power;
222 wl->irq = wl12xx_board_data->irq;
223 wl->use_eeprom = wl12xx_board_data->use_eeprom;
224 }
225
226 if (wl->irq) {
227 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
228 if (ret < 0) {
229 wl1251_error("request_irq() failed: %d", ret);
230 goto disable;
231 }
232
233 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
234 disable_irq(wl->irq);
235
236 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
237 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
238
239 wl1251_info("using dedicated interrupt line");
240 } else {
241 wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
242 wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
243
244 wl1251_info("using SDIO interrupt");
245 }
246
151 ret = wl1251_init_ieee80211(wl); 247 ret = wl1251_init_ieee80211(wl);
152 if (ret) 248 if (ret)
153 goto disable; 249 goto out_free_irq;
154 250
155 sdio_set_drvdata(func, wl); 251 sdio_set_drvdata(func, wl);
156 return ret; 252 return ret;
157 253
254out_free_irq:
255 if (wl->irq)
256 free_irq(wl->irq, wl);
158disable: 257disable:
159 sdio_claim_host(func); 258 sdio_claim_host(func);
160 sdio_disable_func(func); 259 sdio_disable_func(func);
@@ -167,6 +266,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
167{ 266{
168 struct wl1251 *wl = sdio_get_drvdata(func); 267 struct wl1251 *wl = sdio_get_drvdata(func);
169 268
269 if (wl->irq)
270 free_irq(wl->irq, wl);
170 wl1251_free_hw(wl); 271 wl1251_free_hw(wl);
171 272
172 sdio_claim_host(func); 273 sdio_claim_host(func);
@@ -186,6 +287,12 @@ static int __init wl1251_sdio_init(void)
186{ 287{
187 int err; 288 int err;
188 289
290 err = platform_driver_register(&wl1251_platform_driver);
291 if (err) {
292 wl1251_error("failed to register platform driver: %d", err);
293 return err;
294 }
295
189 err = sdio_register_driver(&wl1251_sdio_driver); 296 err = sdio_register_driver(&wl1251_sdio_driver);
190 if (err) 297 if (err)
191 wl1251_error("failed to register sdio driver: %d", err); 298 wl1251_error("failed to register sdio driver: %d", err);
@@ -195,6 +302,7 @@ static int __init wl1251_sdio_init(void)
195static void __exit wl1251_sdio_exit(void) 302static void __exit wl1251_sdio_exit(void)
196{ 303{
197 sdio_unregister_driver(&wl1251_sdio_driver); 304 sdio_unregister_driver(&wl1251_sdio_driver);
305 platform_driver_unregister(&wl1251_platform_driver);
198 wl1251_notice("unloaded"); 306 wl1251_notice("unloaded");
199} 307}
200 308
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
index 3bfb59bd4635..e81474203a23 100644
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -310,7 +310,7 @@ static int __devexit wl1251_spi_remove(struct spi_device *spi)
310 310
311static struct spi_driver wl1251_spi_driver = { 311static struct spi_driver wl1251_spi_driver = {
312 .driver = { 312 .driver = {
313 .name = "wl1251", 313 .name = DRIVER_NAME,
314 .bus = &spi_bus_type, 314 .bus = &spi_bus_type,
315 .owner = THIS_MODULE, 315 .owner = THIS_MODULE,
316 }, 316 },
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 97ea5096bc8c..6f1b6b5640c0 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -53,6 +53,9 @@ enum {
53 DEBUG_MAC80211 = BIT(11), 53 DEBUG_MAC80211 = BIT(11),
54 DEBUG_CMD = BIT(12), 54 DEBUG_CMD = BIT(12),
55 DEBUG_ACX = BIT(13), 55 DEBUG_ACX = BIT(13),
56 DEBUG_SDIO = BIT(14),
57 DEBUG_FILTERS = BIT(15),
58 DEBUG_ADHOC = BIT(16),
56 DEBUG_ALL = ~0, 59 DEBUG_ALL = ~0,
57}; 60};
58 61
@@ -110,6 +113,9 @@ enum {
110#define WL1271_FW_NAME "wl1271-fw.bin" 113#define WL1271_FW_NAME "wl1271-fw.bin"
111#define WL1271_NVS_NAME "wl1271-nvs.bin" 114#define WL1271_NVS_NAME "wl1271-nvs.bin"
112 115
116#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
117#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
118
113/* NVS data structure */ 119/* NVS data structure */
114#define WL1271_NVS_SECTION_SIZE 468 120#define WL1271_NVS_SECTION_SIZE 468
115 121
@@ -142,14 +148,7 @@ struct wl1271_nvs_file {
142 */ 148 */
143#undef WL1271_80211A_ENABLED 149#undef WL1271_80211A_ENABLED
144 150
145/* 151#define WL1271_BUSY_WORD_CNT 1
146 * FIXME: for the wl1271, a busy word count of 1 here will result in a more
147 * optimal SPI interface. There is some SPI bug however, causing RXS time outs
148 * with this mode occasionally on boot, so lets have three for now. A value of
149 * three should make sure, that the chipset will always be ready, though this
150 * will impact throughput and latencies slightly.
151 */
152#define WL1271_BUSY_WORD_CNT 3
153#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) 152#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
154 153
155#define WL1271_ELP_HW_STATE_ASLEEP 0 154#define WL1271_ELP_HW_STATE_ASLEEP 0
@@ -334,11 +333,27 @@ struct wl1271_scan {
334 u8 probe_requests; 333 u8 probe_requests;
335}; 334};
336 335
336struct wl1271_if_operations {
337 void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len,
338 bool fixed);
339 void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len,
340 bool fixed);
341 void (*reset)(struct wl1271 *wl);
342 void (*init)(struct wl1271 *wl);
343 void (*power)(struct wl1271 *wl, bool enable);
344 struct device* (*dev)(struct wl1271 *wl);
345 void (*enable_irq)(struct wl1271 *wl);
346 void (*disable_irq)(struct wl1271 *wl);
347};
348
337struct wl1271 { 349struct wl1271 {
350 struct platform_device *plat_dev;
338 struct ieee80211_hw *hw; 351 struct ieee80211_hw *hw;
339 bool mac80211_registered; 352 bool mac80211_registered;
340 353
341 struct spi_device *spi; 354 void *if_priv;
355
356 struct wl1271_if_operations *if_ops;
342 357
343 void (*set_power)(bool enable); 358 void (*set_power)(bool enable);
344 int irq; 359 int irq;
@@ -357,6 +372,9 @@ struct wl1271 {
357#define WL1271_FLAG_IN_ELP (6) 372#define WL1271_FLAG_IN_ELP (6)
358#define WL1271_FLAG_PSM (7) 373#define WL1271_FLAG_PSM (7)
359#define WL1271_FLAG_PSM_REQUESTED (8) 374#define WL1271_FLAG_PSM_REQUESTED (8)
375#define WL1271_FLAG_IRQ_PENDING (9)
376#define WL1271_FLAG_IRQ_RUNNING (10)
377#define WL1271_FLAG_IDLE (11)
360 unsigned long flags; 378 unsigned long flags;
361 379
362 struct wl1271_partition_set part; 380 struct wl1271_partition_set part;
@@ -370,9 +388,12 @@ struct wl1271 {
370 size_t fw_len; 388 size_t fw_len;
371 struct wl1271_nvs_file *nvs; 389 struct wl1271_nvs_file *nvs;
372 390
391 s8 hw_pg_ver;
392
373 u8 bssid[ETH_ALEN]; 393 u8 bssid[ETH_ALEN];
374 u8 mac_addr[ETH_ALEN]; 394 u8 mac_addr[ETH_ALEN];
375 u8 bss_type; 395 u8 bss_type;
396 u8 set_bss_type;
376 u8 ssid[IW_ESSID_MAX_SIZE + 1]; 397 u8 ssid[IW_ESSID_MAX_SIZE + 1];
377 u8 ssid_len; 398 u8 ssid_len;
378 int channel; 399 int channel;
@@ -382,13 +403,13 @@ struct wl1271 {
382 /* Accounting for allocated / available TX blocks on HW */ 403 /* Accounting for allocated / available TX blocks on HW */
383 u32 tx_blocks_freed[NUM_TX_QUEUES]; 404 u32 tx_blocks_freed[NUM_TX_QUEUES];
384 u32 tx_blocks_available; 405 u32 tx_blocks_available;
385 u8 tx_results_count; 406 u32 tx_results_count;
386 407
387 /* Transmitted TX packets counter for chipset interface */ 408 /* Transmitted TX packets counter for chipset interface */
388 int tx_packets_count; 409 u32 tx_packets_count;
389 410
390 /* Time-offset between host and chipset clocks */ 411 /* Time-offset between host and chipset clocks */
391 int time_offset; 412 s64 time_offset;
392 413
393 /* Session counter for the chipset */ 414 /* Session counter for the chipset */
394 int session_counter; 415 int session_counter;
@@ -403,8 +424,7 @@ struct wl1271 {
403 424
404 /* Security sequence number counters */ 425 /* Security sequence number counters */
405 u8 tx_security_last_seq; 426 u8 tx_security_last_seq;
406 u16 tx_security_seq_16; 427 s64 tx_security_seq;
407 u32 tx_security_seq_32;
408 428
409 /* FW Rx counter */ 429 /* FW Rx counter */
410 u32 rx_counter; 430 u32 rx_counter;
@@ -430,14 +450,19 @@ struct wl1271 {
430 /* currently configured rate set */ 450 /* currently configured rate set */
431 u32 sta_rate_set; 451 u32 sta_rate_set;
432 u32 basic_rate_set; 452 u32 basic_rate_set;
453 u32 basic_rate;
433 u32 rate_set; 454 u32 rate_set;
434 455
435 /* The current band */ 456 /* The current band */
436 enum ieee80211_band band; 457 enum ieee80211_band band;
437 458
459 /* Beaconing interval (needed for ad-hoc) */
460 u32 beacon_int;
461
438 /* Default key (for WEP) */ 462 /* Default key (for WEP) */
439 u32 default_key; 463 u32 default_key;
440 464
465 unsigned int filters;
441 unsigned int rx_config; 466 unsigned int rx_config;
442 unsigned int rx_filter; 467 unsigned int rx_filter;
443 468
@@ -450,10 +475,13 @@ struct wl1271 {
450 /* in dBm */ 475 /* in dBm */
451 int power_level; 476 int power_level;
452 477
478 int rssi_thold;
479 int last_rssi_event;
480
453 struct wl1271_stats stats; 481 struct wl1271_stats stats;
454 struct wl1271_debugfs debugfs; 482 struct wl1271_debugfs debugfs;
455 483
456 u32 buffer_32; 484 __le32 buffer_32;
457 u32 buffer_cmd; 485 u32 buffer_cmd;
458 u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; 486 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
459 487
@@ -465,6 +493,8 @@ struct wl1271 {
465 /* Current chipset configuration */ 493 /* Current chipset configuration */
466 struct conf_drv_settings conf; 494 struct conf_drv_settings conf;
467 495
496 bool sg_enabled;
497
468 struct list_head list; 498 struct list_head list;
469}; 499};
470 500
@@ -477,7 +507,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
477 507
478#define WL1271_DEFAULT_POWER_LEVEL 0 508#define WL1271_DEFAULT_POWER_LEVEL 0
479 509
480#define WL1271_TX_QUEUE_MAX_LENGTH 20 510#define WL1271_TX_QUEUE_LOW_WATERMARK 10
511#define WL1271_TX_QUEUE_HIGH_WATERMARK 25
481 512
482/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power 513/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
483 on in case is has been shut down shortly before */ 514 on in case is has been shut down shortly before */
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 308782421fce..e19e2f8f1e52 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -32,7 +32,6 @@
32#include "wl1271.h" 32#include "wl1271.h"
33#include "wl12xx_80211.h" 33#include "wl12xx_80211.h"
34#include "wl1271_reg.h" 34#include "wl1271_reg.h"
35#include "wl1271_spi.h"
36#include "wl1271_ps.h" 35#include "wl1271_ps.h"
37 36
38int wl1271_acx_wake_up_conditions(struct wl1271 *wl) 37int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
@@ -137,12 +136,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
137 goto out; 136 goto out;
138 } 137 }
139 138
140 /* 139 acx->current_tx_power = power * 10;
141 * FIXME: This is a workaround needed while we don't the correct
142 * calibration, to avoid distortions
143 */
144 /* acx->current_tx_power = power * 10; */
145 acx->current_tx_power = 120;
146 140
147 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); 141 ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
148 if (ret < 0) { 142 if (ret < 0) {
@@ -511,12 +505,17 @@ out:
511 return ret; 505 return ret;
512} 506}
513 507
514int wl1271_acx_conn_monit_params(struct wl1271 *wl) 508#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff
509
510int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
515{ 511{
516 struct acx_conn_monit_params *acx; 512 struct acx_conn_monit_params *acx;
513 u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE;
514 u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE;
517 int ret; 515 int ret;
518 516
519 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters"); 517 wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s",
518 enable ? "enabled" : "disabled");
520 519
521 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 520 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
522 if (!acx) { 521 if (!acx) {
@@ -524,8 +523,13 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl)
524 goto out; 523 goto out;
525 } 524 }
526 525
527 acx->synch_fail_thold = cpu_to_le32(wl->conf.conn.synch_fail_thold); 526 if (enable) {
528 acx->bss_lose_timeout = cpu_to_le32(wl->conf.conn.bss_lose_timeout); 527 threshold = wl->conf.conn.synch_fail_thold;
528 timeout = wl->conf.conn.bss_lose_timeout;
529 }
530
531 acx->synch_fail_thold = cpu_to_le32(threshold);
532 acx->bss_lose_timeout = cpu_to_le32(timeout);
529 533
530 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, 534 ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
531 acx, sizeof(*acx)); 535 acx, sizeof(*acx));
@@ -541,7 +545,7 @@ out:
541} 545}
542 546
543 547
544int wl1271_acx_sg_enable(struct wl1271 *wl) 548int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
545{ 549{
546 struct acx_bt_wlan_coex *pta; 550 struct acx_bt_wlan_coex *pta;
547 int ret; 551 int ret;
@@ -554,7 +558,10 @@ int wl1271_acx_sg_enable(struct wl1271 *wl)
554 goto out; 558 goto out;
555 } 559 }
556 560
557 pta->enable = SG_ENABLE; 561 if (enable)
562 pta->enable = wl->conf.sg.state;
563 else
564 pta->enable = CONF_SG_DISABLE;
558 565
559 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); 566 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
560 if (ret < 0) { 567 if (ret < 0) {
@@ -571,7 +578,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
571{ 578{
572 struct acx_bt_wlan_coex_param *param; 579 struct acx_bt_wlan_coex_param *param;
573 struct conf_sg_settings *c = &wl->conf.sg; 580 struct conf_sg_settings *c = &wl->conf.sg;
574 int ret; 581 int i, ret;
575 582
576 wl1271_debug(DEBUG_ACX, "acx sg cfg"); 583 wl1271_debug(DEBUG_ACX, "acx sg cfg");
577 584
@@ -582,19 +589,9 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
582 } 589 }
583 590
584 /* BT-WLAN coext parameters */ 591 /* BT-WLAN coext parameters */
585 param->per_threshold = cpu_to_le32(c->per_threshold); 592 for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
586 param->max_scan_compensation_time = 593 param->params[i] = cpu_to_le32(c->params[i]);
587 cpu_to_le32(c->max_scan_compensation_time); 594 param->param_idx = CONF_SG_PARAMS_ALL;
588 param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval);
589 param->load_ratio = c->load_ratio;
590 param->auto_ps_mode = c->auto_ps_mode;
591 param->probe_req_compensation = c->probe_req_compensation;
592 param->scan_window_compensation = c->scan_window_compensation;
593 param->antenna_config = c->antenna_config;
594 param->beacon_miss_threshold = c->beacon_miss_threshold;
595 param->rate_adaptation_threshold =
596 cpu_to_le32(c->rate_adaptation_threshold);
597 param->rate_adaptation_snr = c->rate_adaptation_snr;
598 595
599 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 596 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
600 if (ret < 0) { 597 if (ret < 0) {
@@ -806,7 +803,7 @@ int wl1271_acx_rate_policies(struct wl1271 *wl)
806 803
807 /* configure one basic rate class */ 804 /* configure one basic rate class */
808 idx = ACX_TX_BASIC_RATE; 805 idx = ACX_TX_BASIC_RATE;
809 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set); 806 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate);
810 acx->rate_class[idx].short_retry_limit = c->short_retry_limit; 807 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
811 acx->rate_class[idx].long_retry_limit = c->long_retry_limit; 808 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
812 acx->rate_class[idx].aflags = c->aflags; 809 acx->rate_class[idx].aflags = c->aflags;
@@ -1143,3 +1140,129 @@ out:
1143 kfree(acx); 1140 kfree(acx);
1144 return ret; 1141 return ret;
1145} 1142}
1143
1144int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
1145{
1146 struct wl1271_acx_keep_alive_mode *acx = NULL;
1147 int ret = 0;
1148
1149 wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable);
1150
1151 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1152 if (!acx) {
1153 ret = -ENOMEM;
1154 goto out;
1155 }
1156
1157 acx->enabled = enable;
1158
1159 ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx));
1160 if (ret < 0) {
1161 wl1271_warning("acx keep alive mode failed: %d", ret);
1162 goto out;
1163 }
1164
1165out:
1166 kfree(acx);
1167 return ret;
1168}
1169
1170int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
1171{
1172 struct wl1271_acx_keep_alive_config *acx = NULL;
1173 int ret = 0;
1174
1175 wl1271_debug(DEBUG_ACX, "acx keep alive config");
1176
1177 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1178 if (!acx) {
1179 ret = -ENOMEM;
1180 goto out;
1181 }
1182
1183 acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval);
1184 acx->index = index;
1185 acx->tpl_validation = tpl_valid;
1186 acx->trigger = ACX_KEEP_ALIVE_NO_TX;
1187
1188 ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG,
1189 acx, sizeof(*acx));
1190 if (ret < 0) {
1191 wl1271_warning("acx keep alive config failed: %d", ret);
1192 goto out;
1193 }
1194
1195out:
1196 kfree(acx);
1197 return ret;
1198}
1199
1200int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1201 s16 thold, u8 hyst)
1202{
1203 struct wl1271_acx_rssi_snr_trigger *acx = NULL;
1204 int ret = 0;
1205
1206 wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");
1207
1208 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1209 if (!acx) {
1210 ret = -ENOMEM;
1211 goto out;
1212 }
1213
1214 wl->last_rssi_event = -1;
1215
1216 acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
1217 acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
1218 acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
1219 if (enable)
1220 acx->enable = WL1271_ACX_TRIG_ENABLE;
1221 else
1222 acx->enable = WL1271_ACX_TRIG_DISABLE;
1223
1224 acx->index = WL1271_ACX_TRIG_IDX_RSSI;
1225 acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
1226 acx->threshold = cpu_to_le16(thold);
1227 acx->hysteresis = hyst;
1228
1229 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
1230 if (ret < 0) {
1231 wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
1232 goto out;
1233 }
1234
1235out:
1236 kfree(acx);
1237 return ret;
1238}
1239
1240int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
1241{
1242 struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
1243 struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
1244 int ret = 0;
1245
1246 wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");
1247
1248 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1249 if (!acx) {
1250 ret = -ENOMEM;
1251 goto out;
1252 }
1253
1254 acx->rssi_beacon = c->avg_weight_rssi_beacon;
1255 acx->rssi_data = c->avg_weight_rssi_data;
1256 acx->snr_beacon = c->avg_weight_snr_beacon;
1257 acx->snr_data = c->avg_weight_snr_data;
1258
1259 ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
1260 if (ret < 0) {
1261 wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
1262 goto out;
1263 }
1264
1265out:
1266 kfree(acx);
1267 return ret;
1268}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index aeccc98581eb..420e7e2fc021 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -392,81 +392,27 @@ struct acx_conn_monit_params {
392 __le32 bss_lose_timeout; /* number of TU's from synch fail */ 392 __le32 bss_lose_timeout; /* number of TU's from synch fail */
393} __attribute__ ((packed)); 393} __attribute__ ((packed));
394 394
395enum {
396 SG_ENABLE = 0,
397 SG_DISABLE,
398 SG_SENSE_NO_ACTIVITY,
399 SG_SENSE_ACTIVE
400};
401
402struct acx_bt_wlan_coex { 395struct acx_bt_wlan_coex {
403 struct acx_header header; 396 struct acx_header header;
404 397
405 /*
406 * 0 -> PTA enabled
407 * 1 -> PTA disabled
408 * 2 -> sense no active mode, i.e.
409 * an interrupt is sent upon
410 * BT activity.
411 * 3 -> PTA is switched on in response
412 * to the interrupt sending.
413 */
414 u8 enable; 398 u8 enable;
415 u8 pad[3]; 399 u8 pad[3];
416} __attribute__ ((packed)); 400} __attribute__ ((packed));
417 401
418struct acx_dco_itrim_params { 402struct acx_bt_wlan_coex_param {
419 struct acx_header header; 403 struct acx_header header;
420 404
421 u8 enable; 405 __le32 params[CONF_SG_PARAMS_MAX];
406 u8 param_idx;
422 u8 padding[3]; 407 u8 padding[3];
423 __le32 timeout;
424} __attribute__ ((packed)); 408} __attribute__ ((packed));
425 409
426#define PTA_ANTENNA_TYPE_DEF (0) 410struct acx_dco_itrim_params {
427#define PTA_BT_HP_MAXTIME_DEF (2000)
428#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
429#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
430#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
431#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
432#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
433#define PTA_SIGNALING_TYPE_DEF (1)
434#define PTA_AFH_LEVERAGE_ON_DEF (0)
435#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
436#define PTA_MAX_NUM_CTS_DEF (3)
437#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
438#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
439#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
440#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
441#define PTA_CYCLE_TIME_FAST_DEF (8700)
442#define PTA_RX_FOR_AVALANCHE_DEF (5)
443#define PTA_ELP_HP_DEF (0)
444#define PTA_ANTI_STARVE_PERIOD_DEF (500)
445#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
446#define PTA_ALLOW_PA_SD_DEF (1)
447#define PTA_TIME_BEFORE_BEACON_DEF (6300)
448#define PTA_HPDM_MAX_TIME_DEF (1600)
449#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
450#define PTA_AUTO_MODE_NO_CTS_DEF (0)
451#define PTA_BT_HP_RESPECTED_DEF (3)
452#define PTA_WLAN_RX_MIN_RATE_DEF (24)
453#define PTA_ACK_MODE_DEF (1)
454
455struct acx_bt_wlan_coex_param {
456 struct acx_header header; 411 struct acx_header header;
457 412
458 __le32 per_threshold; 413 u8 enable;
459 __le32 max_scan_compensation_time;
460 __le16 nfs_sample_interval;
461 u8 load_ratio;
462 u8 auto_ps_mode;
463 u8 probe_req_compensation;
464 u8 scan_window_compensation;
465 u8 antenna_config;
466 u8 beacon_miss_threshold;
467 __le32 rate_adaptation_threshold;
468 s8 rate_adaptation_snr;
469 u8 padding[3]; 414 u8 padding[3];
415 __le32 timeout;
470} __attribute__ ((packed)); 416} __attribute__ ((packed));
471 417
472struct acx_energy_detection { 418struct acx_energy_detection {
@@ -969,6 +915,84 @@ struct wl1271_acx_pm_config {
969 u8 padding[3]; 915 u8 padding[3];
970} __attribute__ ((packed)); 916} __attribute__ ((packed));
971 917
918struct wl1271_acx_keep_alive_mode {
919 struct acx_header header;
920
921 u8 enabled;
922 u8 padding[3];
923} __attribute__ ((packed));
924
925enum {
926 ACX_KEEP_ALIVE_NO_TX = 0,
927 ACX_KEEP_ALIVE_PERIOD_ONLY
928};
929
930enum {
931 ACX_KEEP_ALIVE_TPL_INVALID = 0,
932 ACX_KEEP_ALIVE_TPL_VALID
933};
934
935struct wl1271_acx_keep_alive_config {
936 struct acx_header header;
937
938 __le32 period;
939 u8 index;
940 u8 tpl_validation;
941 u8 trigger;
942 u8 padding;
943} __attribute__ ((packed));
944
945enum {
946 WL1271_ACX_TRIG_TYPE_LEVEL = 0,
947 WL1271_ACX_TRIG_TYPE_EDGE,
948};
949
950enum {
951 WL1271_ACX_TRIG_DIR_LOW = 0,
952 WL1271_ACX_TRIG_DIR_HIGH,
953 WL1271_ACX_TRIG_DIR_BIDIR,
954};
955
956enum {
957 WL1271_ACX_TRIG_ENABLE = 1,
958 WL1271_ACX_TRIG_DISABLE,
959};
960
961enum {
962 WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0,
963 WL1271_ACX_TRIG_METRIC_RSSI_DATA,
964 WL1271_ACX_TRIG_METRIC_SNR_BEACON,
965 WL1271_ACX_TRIG_METRIC_SNR_DATA,
966};
967
968enum {
969 WL1271_ACX_TRIG_IDX_RSSI = 0,
970 WL1271_ACX_TRIG_COUNT = 8,
971};
972
973struct wl1271_acx_rssi_snr_trigger {
974 struct acx_header header;
975
976 __le16 threshold;
977 __le16 pacing; /* 0 - 60000 ms */
978 u8 metric;
979 u8 type;
980 u8 dir;
981 u8 hysteresis;
982 u8 index;
983 u8 enable;
984 u8 padding[2];
985};
986
987struct wl1271_acx_rssi_snr_avg_weights {
988 struct acx_header header;
989
990 u8 rssi_beacon;
991 u8 rssi_data;
992 u8 snr_beacon;
993 u8 snr_data;
994};
995
972enum { 996enum {
973 ACX_WAKE_UP_CONDITIONS = 0x0002, 997 ACX_WAKE_UP_CONDITIONS = 0x0002,
974 ACX_MEM_CFG = 0x0003, 998 ACX_MEM_CFG = 0x0003,
@@ -1017,8 +1041,8 @@ enum {
1017 ACX_FRAG_CFG = 0x004F, 1041 ACX_FRAG_CFG = 0x004F,
1018 ACX_BET_ENABLE = 0x0050, 1042 ACX_BET_ENABLE = 0x0050,
1019 ACX_RSSI_SNR_TRIGGER = 0x0051, 1043 ACX_RSSI_SNR_TRIGGER = 0x0051,
1020 ACX_RSSI_SNR_WEIGHTS = 0x0051, 1044 ACX_RSSI_SNR_WEIGHTS = 0x0052,
1021 ACX_KEEP_ALIVE_MODE = 0x0052, 1045 ACX_KEEP_ALIVE_MODE = 0x0053,
1022 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, 1046 ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
1023 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, 1047 ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
1024 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, 1048 ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
@@ -1058,8 +1082,8 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
1058int wl1271_acx_dco_itrim_params(struct wl1271 *wl); 1082int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1059int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1083int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1060int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1084int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1061int wl1271_acx_conn_monit_params(struct wl1271 *wl); 1085int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable);
1062int wl1271_acx_sg_enable(struct wl1271 *wl); 1086int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
1063int wl1271_acx_sg_cfg(struct wl1271 *wl); 1087int wl1271_acx_sg_cfg(struct wl1271 *wl);
1064int wl1271_acx_cca_threshold(struct wl1271 *wl); 1088int wl1271_acx_cca_threshold(struct wl1271 *wl);
1065int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); 1089int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
@@ -1085,5 +1109,10 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1085int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, 1109int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
1086 u8 version); 1110 u8 version);
1087int wl1271_acx_pm_config(struct wl1271 *wl); 1111int wl1271_acx_pm_config(struct wl1271 *wl);
1112int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
1113int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
1114int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1115 s16 thold, u8 hyst);
1116int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
1088 1117
1089#endif /* __WL1271_ACX_H__ */ 1118#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 024356263065..1a36d8a2196e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2008-2009 Nokia Corporation 4 * Copyright (C) 2008-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -27,7 +27,6 @@
27#include "wl1271_acx.h" 27#include "wl1271_acx.h"
28#include "wl1271_reg.h" 28#include "wl1271_reg.h"
29#include "wl1271_boot.h" 29#include "wl1271_boot.h"
30#include "wl1271_spi.h"
31#include "wl1271_io.h" 30#include "wl1271_io.h"
32#include "wl1271_event.h" 31#include "wl1271_event.h"
33 32
@@ -230,6 +229,14 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
230 nvs_len = sizeof(wl->nvs->nvs); 229 nvs_len = sizeof(wl->nvs->nvs);
231 nvs_ptr = (u8 *)wl->nvs->nvs; 230 nvs_ptr = (u8 *)wl->nvs->nvs;
232 231
232 /* update current MAC address to NVS */
233 nvs_ptr[11] = wl->mac_addr[0];
234 nvs_ptr[10] = wl->mac_addr[1];
235 nvs_ptr[6] = wl->mac_addr[2];
236 nvs_ptr[5] = wl->mac_addr[3];
237 nvs_ptr[4] = wl->mac_addr[4];
238 nvs_ptr[3] = wl->mac_addr[5];
239
233 /* 240 /*
234 * Layout before the actual NVS tables: 241 * Layout before the actual NVS tables:
235 * 1 byte : burst length. 242 * 1 byte : burst length.
@@ -300,7 +307,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
300 307
301static void wl1271_boot_enable_interrupts(struct wl1271 *wl) 308static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
302{ 309{
303 enable_irq(wl->irq); 310 wl1271_enable_interrupts(wl);
304 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, 311 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
305 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 312 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
306 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); 313 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
@@ -344,7 +351,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl)
344static int wl1271_boot_run_firmware(struct wl1271 *wl) 351static int wl1271_boot_run_firmware(struct wl1271 *wl)
345{ 352{
346 int loop, ret; 353 int loop, ret;
347 u32 chip_id, interrupt; 354 u32 chip_id, intr;
348 355
349 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); 356 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
350 357
@@ -361,15 +368,15 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
361 loop = 0; 368 loop = 0;
362 while (loop++ < INIT_LOOP) { 369 while (loop++ < INIT_LOOP) {
363 udelay(INIT_LOOP_DELAY); 370 udelay(INIT_LOOP_DELAY);
364 interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 371 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
365 372
366 if (interrupt == 0xffffffff) { 373 if (intr == 0xffffffff) {
367 wl1271_error("error reading hardware complete " 374 wl1271_error("error reading hardware complete "
368 "init indication"); 375 "init indication");
369 return -EIO; 376 return -EIO;
370 } 377 }
371 /* check that ACX_INTR_INIT_COMPLETE is enabled */ 378 /* check that ACX_INTR_INIT_COMPLETE is enabled */
372 else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) { 379 else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
373 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, 380 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
374 WL1271_ACX_INTR_INIT_COMPLETE); 381 WL1271_ACX_INTR_INIT_COMPLETE);
375 break; 382 break;
@@ -404,7 +411,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
404 /* unmask required mbox events */ 411 /* unmask required mbox events */
405 wl->event_mask = BSS_LOSE_EVENT_ID | 412 wl->event_mask = BSS_LOSE_EVENT_ID |
406 SCAN_COMPLETE_EVENT_ID | 413 SCAN_COMPLETE_EVENT_ID |
407 PS_REPORT_EVENT_ID; 414 PS_REPORT_EVENT_ID |
415 JOIN_EVENT_COMPLETE_ID |
416 DISCONNECT_EVENT_COMPLETE_ID |
417 RSSI_SNR_TRIGGER_0_EVENT_ID;
408 418
409 ret = wl1271_event_unmask(wl); 419 ret = wl1271_event_unmask(wl);
410 if (ret < 0) { 420 if (ret < 0) {
@@ -431,11 +441,23 @@ static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
431 return 0; 441 return 0;
432} 442}
433 443
444static void wl1271_boot_hw_version(struct wl1271 *wl)
445{
446 u32 fuse;
447
448 fuse = wl1271_top_reg_read(wl, REG_FUSE_DATA_2_1);
449 fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET;
450
451 wl->hw_pg_ver = (s8)fuse;
452}
453
434int wl1271_boot(struct wl1271 *wl) 454int wl1271_boot(struct wl1271 *wl)
435{ 455{
436 int ret = 0; 456 int ret = 0;
437 u32 tmp, clk, pause; 457 u32 tmp, clk, pause;
438 458
459 wl1271_boot_hw_version(wl);
460
439 if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4) 461 if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
440 /* ref clk: 19.2/38.4/38.4-XTAL */ 462 /* ref clk: 19.2/38.4/38.4-XTAL */
441 clk = 0x3; 463 clk = 0x3;
@@ -445,11 +467,15 @@ int wl1271_boot(struct wl1271 *wl)
445 467
446 if (REF_CLOCK != 0) { 468 if (REF_CLOCK != 0) {
447 u16 val; 469 u16 val;
448 /* Set clock type */ 470 /* Set clock type (open drain) */
449 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); 471 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
450 val &= FREF_CLK_TYPE_BITS; 472 val &= FREF_CLK_TYPE_BITS;
451 val |= CLK_REQ_PRCM;
452 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); 473 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
474
475 /* Set clock pull mode (no pull) */
476 val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
477 val |= NO_PULL;
478 wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
453 } else { 479 } else {
454 u16 val; 480 u16 val;
455 /* Set clock polarity */ 481 /* Set clock polarity */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index 412443ee655a..f829699d597e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -53,10 +53,16 @@ struct wl1271_static_data {
53#define OCP_REG_POLARITY 0x0064 53#define OCP_REG_POLARITY 0x0064
54#define OCP_REG_CLK_TYPE 0x0448 54#define OCP_REG_CLK_TYPE 0x0448
55#define OCP_REG_CLK_POLARITY 0x0cb2 55#define OCP_REG_CLK_POLARITY 0x0cb2
56#define OCP_REG_CLK_PULL 0x0cb4
56 57
57#define CMD_MBOX_ADDRESS 0x407B4 58#define REG_FUSE_DATA_2_1 0x050a
59#define PG_VER_MASK 0x3c
60#define PG_VER_OFFSET 2
58 61
59#define POLARITY_LOW BIT(1) 62#define CMD_MBOX_ADDRESS 0x407B4
63
64#define POLARITY_LOW BIT(1)
65#define NO_PULL (BIT(14) | BIT(15))
60 66
61#define FREF_CLK_TYPE_BITS 0xfffffe7f 67#define FREF_CLK_TYPE_BITS 0xfffffe7f
62#define CLK_REQ_PRCM 0x100 68#define CLK_REQ_PRCM 0x100
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index e7832f3318eb..19393e236e2c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file is part of wl1271 2 * This file is part of wl1271
3 * 3 *
4 * Copyright (C) 2009 Nokia Corporation 4 * Copyright (C) 2009-2010 Nokia Corporation
5 * 5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 * 7 *
@@ -26,15 +26,18 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/ieee80211.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30 31
31#include "wl1271.h" 32#include "wl1271.h"
32#include "wl1271_reg.h" 33#include "wl1271_reg.h"
33#include "wl1271_spi.h"
34#include "wl1271_io.h" 34#include "wl1271_io.h"
35#include "wl1271_acx.h" 35#include "wl1271_acx.h"
36#include "wl12xx_80211.h" 36#include "wl12xx_80211.h"
37#include "wl1271_cmd.h" 37#include "wl1271_cmd.h"
38#include "wl1271_event.h"
39
40#define WL1271_CMD_FAST_POLL_COUNT 50
38 41
39/* 42/*
40 * send command to firmware 43 * send command to firmware
@@ -52,6 +55,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
52 u32 intr; 55 u32 intr;
53 int ret = 0; 56 int ret = 0;
54 u16 status; 57 u16 status;
58 u16 poll_count = 0;
55 59
56 cmd = buf; 60 cmd = buf;
57 cmd->id = cpu_to_le16(id); 61 cmd->id = cpu_to_le16(id);
@@ -73,7 +77,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
73 goto out; 77 goto out;
74 } 78 }
75 79
76 msleep(1); 80 poll_count++;
81 if (poll_count < WL1271_CMD_FAST_POLL_COUNT)
82 udelay(10);
83 else
84 msleep(1);
77 85
78 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 86 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
79 } 87 }
@@ -249,7 +257,36 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
249 return ret; 257 return ret;
250} 258}
251 259
252int wl1271_cmd_join(struct wl1271 *wl) 260/*
261 * Poll the mailbox event field until any of the bits in the mask is set or a
262 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
263 */
264static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
265{
266 u32 events_vector, event;
267 unsigned long timeout;
268
269 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
270
271 do {
272 if (time_after(jiffies, timeout))
273 return -ETIMEDOUT;
274
275 msleep(1);
276
277 /* read from both event fields */
278 wl1271_read(wl, wl->mbox_ptr[0], &events_vector,
279 sizeof(events_vector), false);
280 event = events_vector & mask;
281 wl1271_read(wl, wl->mbox_ptr[1], &events_vector,
282 sizeof(events_vector), false);
283 event |= events_vector & mask;
284 } while (!event);
285
286 return 0;
287}
288
289int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
253{ 290{
254 static bool do_cal = true; 291 static bool do_cal = true;
255 struct wl1271_cmd_join *join; 292 struct wl1271_cmd_join *join;
@@ -280,30 +317,13 @@ int wl1271_cmd_join(struct wl1271 *wl)
280 317
281 join->rx_config_options = cpu_to_le32(wl->rx_config); 318 join->rx_config_options = cpu_to_le32(wl->rx_config);
282 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 319 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
283 join->bss_type = wl->bss_type; 320 join->bss_type = bss_type;
321 join->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
284 322
285 /* 323 if (wl->band == IEEE80211_BAND_5GHZ)
286 * FIXME: disable temporarily all filters because after commit
287 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
288 * association. The filter logic needs to be implemented properly
289 * and once that is done, this hack can be removed.
290 */
291 join->rx_config_options = cpu_to_le32(0);
292 join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
293
294 if (wl->band == IEEE80211_BAND_2GHZ)
295 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
296 CONF_HW_BIT_RATE_2MBPS |
297 CONF_HW_BIT_RATE_5_5MBPS |
298 CONF_HW_BIT_RATE_11MBPS);
299 else {
300 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 324 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
301 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS |
302 CONF_HW_BIT_RATE_12MBPS |
303 CONF_HW_BIT_RATE_24MBPS);
304 }
305 325
306 join->beacon_interval = cpu_to_le16(WL1271_DEFAULT_BEACON_INT); 326 join->beacon_interval = cpu_to_le16(wl->beacon_int);
307 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 327 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
308 328
309 join->channel = wl->channel; 329 join->channel = wl->channel;
@@ -320,8 +340,7 @@ int wl1271_cmd_join(struct wl1271 *wl)
320 340
321 /* reset TX security counters */ 341 /* reset TX security counters */
322 wl->tx_security_last_seq = 0; 342 wl->tx_security_last_seq = 0;
323 wl->tx_security_seq_16 = 0; 343 wl->tx_security_seq = 0;
324 wl->tx_security_seq_32 = 0;
325 344
326 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); 345 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
327 if (ret < 0) { 346 if (ret < 0) {
@@ -329,11 +348,9 @@ int wl1271_cmd_join(struct wl1271 *wl)
329 goto out_free; 348 goto out_free;
330 } 349 }
331 350
332 /* 351 ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID);
333 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to 352 if (ret < 0)
334 * simplify locking we just sleep instead, for now 353 wl1271_error("cmd join event completion error");
335 */
336 msleep(10);
337 354
338out_free: 355out_free:
339 kfree(join); 356 kfree(join);
@@ -465,7 +482,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
465 if (ret < 0) { 482 if (ret < 0) {
466 wl1271_error("tx %s cmd for channel %d failed", 483 wl1271_error("tx %s cmd for channel %d failed",
467 enable ? "start" : "stop", cmd->channel); 484 enable ? "start" : "stop", cmd->channel);
468 return ret; 485 goto out;
469 } 486 }
470 487
471 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 488 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
@@ -499,7 +516,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
499 ps_params->ps_mode = ps_mode; 516 ps_params->ps_mode = ps_mode;
500 ps_params->send_null_data = send; 517 ps_params->send_null_data = send;
501 ps_params->retries = 5; 518 ps_params->retries = 5;
502 ps_params->hang_over_period = 128; 519 ps_params->hang_over_period = 1;
503 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */ 520 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
504 521
505 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 522 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
@@ -549,25 +566,29 @@ out:
549 return ret; 566 return ret;
550} 567}
551 568
552int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 569int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
553 u8 active_scan, u8 high_prio, u8 band, 570 const u8 *ie, size_t ie_len, u8 active_scan,
554 u8 probe_requests) 571 u8 high_prio, u8 band, u8 probe_requests)
555{ 572{
556 573
557 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 574 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
558 struct wl1271_cmd_scan *params = NULL; 575 struct wl1271_cmd_scan *params = NULL;
559 struct ieee80211_channel *channels; 576 struct ieee80211_channel *channels;
577 u32 rate;
560 int i, j, n_ch, ret; 578 int i, j, n_ch, ret;
561 u16 scan_options = 0; 579 u16 scan_options = 0;
562 u8 ieee_band; 580 u8 ieee_band;
563 581
564 if (band == WL1271_SCAN_BAND_2_4_GHZ) 582 if (band == WL1271_SCAN_BAND_2_4_GHZ) {
565 ieee_band = IEEE80211_BAND_2GHZ; 583 ieee_band = IEEE80211_BAND_2GHZ;
566 else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) 584 rate = wl->conf.tx.basic_rate;
585 } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) {
567 ieee_band = IEEE80211_BAND_2GHZ; 586 ieee_band = IEEE80211_BAND_2GHZ;
568 else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) 587 rate = wl->conf.tx.basic_rate;
588 } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) {
569 ieee_band = IEEE80211_BAND_5GHZ; 589 ieee_band = IEEE80211_BAND_5GHZ;
570 else 590 rate = wl->conf.tx.basic_rate_5;
591 } else
571 return -EINVAL; 592 return -EINVAL;
572 593
573 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) 594 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
@@ -594,8 +615,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
594 params->params.scan_options = cpu_to_le16(scan_options); 615 params->params.scan_options = cpu_to_le16(scan_options);
595 616
596 params->params.num_probe_requests = probe_requests; 617 params->params.num_probe_requests = probe_requests;
597 /* Let the fw autodetect suitable tx_rate for probes */ 618 params->params.tx_rate = cpu_to_le32(rate);
598 params->params.tx_rate = 0;
599 params->params.tid_trigger = 0; 619 params->params.tid_trigger = 0;
600 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 620 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
601 621
@@ -622,12 +642,13 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
622 642
623 params->params.num_channels = j; 643 params->params.num_channels = j;
624 644
625 if (len && ssid) { 645 if (ssid_len && ssid) {
626 params->params.ssid_len = len; 646 params->params.ssid_len = ssid_len;
627 memcpy(params->params.ssid, ssid, len); 647 memcpy(params->params.ssid, ssid, ssid_len);
628 } 648 }
629 649
630 ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band); 650 ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len,
651 ie, ie_len, ieee_band);
631 if (ret < 0) { 652 if (ret < 0) {
632 wl1271_error("PROBE request template failed"); 653 wl1271_error("PROBE request template failed");
633 goto out; 654 goto out;
@@ -658,9 +679,9 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
658 wl->scan.active = active_scan; 679 wl->scan.active = active_scan;
659 wl->scan.high_prio = high_prio; 680 wl->scan.high_prio = high_prio;
660 wl->scan.probe_requests = probe_requests; 681 wl->scan.probe_requests = probe_requests;
661 if (len && ssid) { 682 if (ssid_len && ssid) {
662 wl->scan.ssid_len = len; 683 wl->scan.ssid_len = ssid_len;
663 memcpy(wl->scan.ssid, ssid, len); 684 memcpy(wl->scan.ssid, ssid, ssid_len);
664 } else 685 } else
665 wl->scan.ssid_len = 0; 686 wl->scan.ssid_len = 0;
666 } 687 }
@@ -675,11 +696,12 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
675 696
676out: 697out:
677 kfree(params); 698 kfree(params);
699 kfree(trigger);
678 return ret; 700 return ret;
679} 701}
680 702
681int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 703int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
682 void *buf, size_t buf_len) 704 void *buf, size_t buf_len, int index, u32 rates)
683{ 705{
684 struct wl1271_cmd_template_set *cmd; 706 struct wl1271_cmd_template_set *cmd;
685 int ret = 0; 707 int ret = 0;
@@ -697,9 +719,10 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
697 719
698 cmd->len = cpu_to_le16(buf_len); 720 cmd->len = cpu_to_le16(buf_len);
699 cmd->template_type = template_id; 721 cmd->template_type = template_id;
700 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates); 722 cmd->enabled_rates = cpu_to_le32(rates);
701 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; 723 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
702 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; 724 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
725 cmd->index = index;
703 726
704 if (buf) 727 if (buf)
705 memcpy(cmd->template_data, buf, buf_len); 728 memcpy(cmd->template_data, buf, buf_len);
@@ -717,155 +740,129 @@ out:
717 return ret; 740 return ret;
718} 741}
719 742
720static int wl1271_build_basic_rates(u8 *rates, u8 band) 743int wl1271_cmd_build_null_data(struct wl1271 *wl)
721{ 744{
722 u8 index = 0; 745 struct sk_buff *skb = NULL;
723 746 int size;
724 if (band == IEEE80211_BAND_2GHZ) { 747 void *ptr;
725 rates[index++] = 748 int ret = -ENOMEM;
726 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
727 rates[index++] =
728 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
729 rates[index++] =
730 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
731 rates[index++] =
732 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
733 } else if (band == IEEE80211_BAND_5GHZ) {
734 rates[index++] =
735 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
736 rates[index++] =
737 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
738 rates[index++] =
739 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
740 } else {
741 wl1271_error("build_basic_rates invalid band: %d", band);
742 }
743 749
744 return index;
745}
746 750
747static int wl1271_build_extended_rates(u8 *rates, u8 band) 751 if (wl->bss_type == BSS_TYPE_IBSS) {
748{ 752 size = sizeof(struct wl12xx_null_data_template);
749 u8 index = 0; 753 ptr = NULL;
750
751 if (band == IEEE80211_BAND_2GHZ) {
752 rates[index++] = IEEE80211_OFDM_RATE_6MB;
753 rates[index++] = IEEE80211_OFDM_RATE_9MB;
754 rates[index++] = IEEE80211_OFDM_RATE_12MB;
755 rates[index++] = IEEE80211_OFDM_RATE_18MB;
756 rates[index++] = IEEE80211_OFDM_RATE_24MB;
757 rates[index++] = IEEE80211_OFDM_RATE_36MB;
758 rates[index++] = IEEE80211_OFDM_RATE_48MB;
759 rates[index++] = IEEE80211_OFDM_RATE_54MB;
760 } else if (band == IEEE80211_BAND_5GHZ) {
761 rates[index++] =
762 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
763 rates[index++] =
764 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
765 rates[index++] =
766 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
767 rates[index++] =
768 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
769 rates[index++] =
770 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
771 rates[index++] =
772 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
773 } else { 754 } else {
774 wl1271_error("build_basic_rates invalid band: %d", band); 755 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
756 if (!skb)
757 goto out;
758 size = skb->len;
759 ptr = skb->data;
775 } 760 }
776 761
777 return index; 762 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
763 WL1271_RATE_AUTOMATIC);
764
765out:
766 dev_kfree_skb(skb);
767 if (ret)
768 wl1271_warning("cmd buld null data failed %d", ret);
769
770 return ret;
771
778} 772}
779 773
780int wl1271_cmd_build_null_data(struct wl1271 *wl) 774int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
781{ 775{
782 struct wl12xx_null_data_template template; 776 struct sk_buff *skb = NULL;
777 int ret = -ENOMEM;
783 778
784 if (!is_zero_ether_addr(wl->bssid)) { 779 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
785 memcpy(template.header.da, wl->bssid, ETH_ALEN); 780 if (!skb)
786 memcpy(template.header.bssid, wl->bssid, ETH_ALEN); 781 goto out;
787 } else { 782
788 memset(template.header.da, 0xff, ETH_ALEN); 783 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
789 memset(template.header.bssid, 0xff, ETH_ALEN); 784 skb->data, skb->len,
790 } 785 CMD_TEMPL_KLV_IDX_NULL_DATA,
786 WL1271_RATE_AUTOMATIC);
791 787
792 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 788out:
793 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 789 dev_kfree_skb(skb);
794 IEEE80211_STYPE_NULLFUNC | 790 if (ret)
795 IEEE80211_FCTL_TODS); 791 wl1271_warning("cmd build klv null data failed %d", ret);
796 792
797 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template, 793 return ret;
798 sizeof(template));
799 794
800} 795}
801 796
802int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) 797int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
803{ 798{
804 struct wl12xx_ps_poll_template template; 799 struct sk_buff *skb;
805 800 int ret = 0;
806 memcpy(template.bssid, wl->bssid, ETH_ALEN);
807 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
808
809 /* aid in PS-Poll has its two MSBs each set to 1 */
810 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
811 801
812 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 802 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
803 if (!skb)
804 goto out;
813 805
814 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template, 806 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
815 sizeof(template)); 807 skb->len, 0, wl->basic_rate);
816 808
809out:
810 dev_kfree_skb(skb);
811 return ret;
817} 812}
818 813
819int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 814int wl1271_cmd_build_probe_req(struct wl1271 *wl,
820 u8 band) 815 const u8 *ssid, size_t ssid_len,
816 const u8 *ie, size_t ie_len, u8 band)
821{ 817{
822 struct wl12xx_probe_req_template template; 818 struct sk_buff *skb;
823 struct wl12xx_ie_rates *rates;
824 char *ptr;
825 u16 size;
826 int ret; 819 int ret;
827 820
828 ptr = (char *)&template; 821 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
829 size = sizeof(struct ieee80211_header); 822 ie, ie_len);
830 823 if (!skb) {
831 memset(template.header.da, 0xff, ETH_ALEN); 824 ret = -ENOMEM;
832 memset(template.header.bssid, 0xff, ETH_ALEN); 825 goto out;
833 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 826 }
834 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 827
835 828 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
836 /* IEs */
837 /* SSID */
838 template.ssid.header.id = WLAN_EID_SSID;
839 template.ssid.header.len = ssid_len;
840 if (ssid_len && ssid)
841 memcpy(template.ssid.ssid, ssid, ssid_len);
842 size += sizeof(struct wl12xx_ie_header) + ssid_len;
843 ptr += size;
844
845 /* Basic Rates */
846 rates = (struct wl12xx_ie_rates *)ptr;
847 rates->header.id = WLAN_EID_SUPP_RATES;
848 rates->header.len = wl1271_build_basic_rates(rates->rates, band);
849 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
850 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
851
852 /* Extended rates */
853 rates = (struct wl12xx_ie_rates *)ptr;
854 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
855 rates->header.len = wl1271_build_extended_rates(rates->rates, band);
856 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
857
858 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
859 829
860 if (band == IEEE80211_BAND_2GHZ) 830 if (band == IEEE80211_BAND_2GHZ)
861 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 831 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
862 &template, size); 832 skb->data, skb->len, 0,
833 wl->conf.tx.basic_rate);
863 else 834 else
864 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 835 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
865 &template, size); 836 skb->data, skb->len, 0,
837 wl->conf.tx.basic_rate_5);
838
839out:
840 dev_kfree_skb(skb);
866 return ret; 841 return ret;
867} 842}
868 843
844int wl1271_build_qos_null_data(struct wl1271 *wl)
845{
846 struct ieee80211_qos_hdr template;
847
848 memset(&template, 0, sizeof(template));
849
850 memcpy(template.addr1, wl->bssid, ETH_ALEN);
851 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
852 memcpy(template.addr3, wl->bssid, ETH_ALEN);
853
854 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
855 IEEE80211_STYPE_QOS_NULLFUNC |
856 IEEE80211_FCTL_TODS);
857
858 /* FIXME: not sure what priority to use here */
859 template.qos_ctrl = cpu_to_le16(0);
860
861 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
862 sizeof(template), 0,
863 WL1271_RATE_AUTOMATIC);
864}
865
869int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 866int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
870{ 867{
871 struct wl1271_cmd_set_keys *cmd; 868 struct wl1271_cmd_set_keys *cmd;
@@ -976,6 +973,10 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
976 goto out_free; 973 goto out_free;
977 } 974 }
978 975
976 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
977 if (ret < 0)
978 wl1271_error("cmd disconnect event completion error");
979
979out_free: 980out_free:
980 kfree(cmd); 981 kfree(cmd);
981 982
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 2dc06c73532b..f2820b42a943 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -33,7 +33,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
33 size_t res_len); 33 size_t res_len);
34int wl1271_cmd_general_parms(struct wl1271 *wl); 34int wl1271_cmd_general_parms(struct wl1271 *wl);
35int wl1271_cmd_radio_parms(struct wl1271 *wl); 35int wl1271_cmd_radio_parms(struct wl1271 *wl);
36int wl1271_cmd_join(struct wl1271 *wl); 36int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 37int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
@@ -41,15 +41,18 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); 41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 44int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 u8 active_scan, u8 high_prio, u8 band, 45 const u8 *ie, size_t ie_len, u8 active_scan,
46 u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len); 48 void *buf, size_t buf_len, int index, u32 rates);
49int wl1271_cmd_build_null_data(struct wl1271 *wl); 49int wl1271_cmd_build_null_data(struct wl1271 *wl);
50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); 50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
51int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 51int wl1271_cmd_build_probe_req(struct wl1271 *wl,
52 u8 band); 52 const u8 *ssid, size_t ssid_len,
53 const u8 *ie, size_t ie_len, u8 band);
54int wl1271_build_qos_null_data(struct wl1271 *wl);
55int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
53int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 56int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
54int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 57int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
55 u8 key_size, const u8 *key, const u8 *addr, 58 u8 key_size, const u8 *key, const u8 *addr,
@@ -99,6 +102,11 @@ enum wl1271_commands {
99 102
100#define MAX_CMD_PARAMS 572 103#define MAX_CMD_PARAMS 572
101 104
105enum {
106 CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
107 CMD_TEMPL_KLV_IDX_MAX = 4
108};
109
102enum cmd_templ { 110enum cmd_templ {
103 CMD_TEMPL_NULL_DATA = 0, 111 CMD_TEMPL_NULL_DATA = 0,
104 CMD_TEMPL_BEACON, 112 CMD_TEMPL_BEACON,
@@ -121,6 +129,7 @@ enum cmd_templ {
121/* unit ms */ 129/* unit ms */
122#define WL1271_COMMAND_TIMEOUT 2000 130#define WL1271_COMMAND_TIMEOUT 2000
123#define WL1271_CMD_TEMPL_MAX_SIZE 252 131#define WL1271_CMD_TEMPL_MAX_SIZE 252
132#define WL1271_EVENT_TIMEOUT 750
124 133
125struct wl1271_cmd_header { 134struct wl1271_cmd_header {
126 __le16 id; 135 __le16 id;
@@ -243,6 +252,8 @@ struct cmd_enabledisable_path {
243 u8 padding[3]; 252 u8 padding[3];
244} __attribute__ ((packed)); 253} __attribute__ ((packed));
245 254
255#define WL1271_RATE_AUTOMATIC 0
256
246struct wl1271_cmd_template_set { 257struct wl1271_cmd_template_set {
247 struct wl1271_cmd_header header; 258 struct wl1271_cmd_header header;
248 259
@@ -509,6 +520,8 @@ enum wl1271_disconnect_type {
509}; 520};
510 521
511struct wl1271_cmd_disconnect { 522struct wl1271_cmd_disconnect {
523 struct wl1271_cmd_header header;
524
512 __le32 rx_config_options; 525 __le32 rx_config_options;
513 __le32 rx_filter_options; 526 __le32 rx_filter_options;
514 527
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 6f9e75cc5640..d046d044b5bd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -65,110 +65,344 @@ enum {
65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
66}; 66};
67 67
68struct conf_sg_settings { 68enum {
69 CONF_HW_RXTX_RATE_MCS7 = 0,
70 CONF_HW_RXTX_RATE_MCS6,
71 CONF_HW_RXTX_RATE_MCS5,
72 CONF_HW_RXTX_RATE_MCS4,
73 CONF_HW_RXTX_RATE_MCS3,
74 CONF_HW_RXTX_RATE_MCS2,
75 CONF_HW_RXTX_RATE_MCS1,
76 CONF_HW_RXTX_RATE_MCS0,
77 CONF_HW_RXTX_RATE_54,
78 CONF_HW_RXTX_RATE_48,
79 CONF_HW_RXTX_RATE_36,
80 CONF_HW_RXTX_RATE_24,
81 CONF_HW_RXTX_RATE_22,
82 CONF_HW_RXTX_RATE_18,
83 CONF_HW_RXTX_RATE_12,
84 CONF_HW_RXTX_RATE_11,
85 CONF_HW_RXTX_RATE_9,
86 CONF_HW_RXTX_RATE_6,
87 CONF_HW_RXTX_RATE_5_5,
88 CONF_HW_RXTX_RATE_2,
89 CONF_HW_RXTX_RATE_1,
90 CONF_HW_RXTX_RATE_MAX,
91 CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
92};
93
94enum {
95 CONF_SG_DISABLE = 0,
96 CONF_SG_PROTECTIVE,
97 CONF_SG_OPPORTUNISTIC
98};
99
100enum {
69 /* 101 /*
70 * Defines the PER threshold in PPM of the BT voice of which reaching 102 * PER threshold in PPM of the BT voice
71 * this value will trigger raising the priority of the BT voice by
72 * the BT IP until next NFS sample interval time as defined in
73 * nfs_sample_interval.
74 * 103 *
75 * Unit: PER value in PPM (parts per million) 104 * Range: 0 - 10000000
76 * #Error_packets / #Total_packets 105 */
106 CONF_SG_BT_PER_THRESHOLD = 0,
77 107
78 * Range: u32 108 /*
109 * Number of consequent RX_ACTIVE activities to override BT voice
110 * frames to ensure WLAN connection
111 *
112 * Range: 0 - 100
113 */
114 CONF_SG_HV3_MAX_OVERRIDE,
115
116 /*
117 * Defines the PER threshold of the BT voice
118 *
119 * Range: 0 - 65000
120 */
121 CONF_SG_BT_NFS_SAMPLE_INTERVAL,
122
123 /*
124 * Defines the load ratio of BT
125 *
126 * Range: 0 - 100 (%)
127 */
128 CONF_SG_BT_LOAD_RATIO,
129
130 /*
131 * Defines whether the SG will force WLAN host to enter/exit PSM
132 *
133 * Range: 1 - SG can force, 0 - host handles PSM
134 */
135 CONF_SG_AUTO_PS_MODE,
136
137 /*
138 * Compensation percentage of probe requests when scan initiated
139 * during BT voice/ACL link.
140 *
141 * Range: 0 - 255 (%)
142 */
143 CONF_SG_AUTO_SCAN_PROBE_REQ,
144
145 /*
146 * Compensation percentage of probe requests when active scan initiated
147 * during BT voice
148 *
149 * Range: 0 - 255 (%)
150 */
151 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3,
152
153 /*
154 * Defines antenna configuration (single/dual antenna)
155 *
156 * Range: 0 - single antenna, 1 - dual antenna
157 */
158 CONF_SG_ANTENNA_CONFIGURATION,
159
160 /*
161 * The threshold (percent) of max consequtive beacon misses before
162 * increasing priority of beacon reception.
163 *
164 * Range: 0 - 100 (%)
165 */
166 CONF_SG_BEACON_MISS_PERCENT,
167
168 /*
169 * The rate threshold below which receiving a data frame from the AP
170 * will increase the priority of the data frame above BT traffic.
171 *
172 * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54
173 */
174 CONF_SG_RATE_ADAPT_THRESH,
175
176 /*
177 * Not used currently.
178 *
179 * Range: 0
180 */
181 CONF_SG_RATE_ADAPT_SNR,
182
183 /*
184 * Configure the min and max time BT gains the antenna
185 * in WLAN PSM / BT master basic rate
186 *
187 * Range: 0 - 255 (ms)
188 */
189 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR,
190 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR,
191
192 /*
193 * The time after it expires no new WLAN trigger frame is trasmitted
194 * in WLAN PSM / BT master basic rate
195 *
196 * Range: 0 - 255 (ms)
197 */
198 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR,
199
200 /*
201 * Configure the min and max time BT gains the antenna
202 * in WLAN PSM / BT slave basic rate
203 *
204 * Range: 0 - 255 (ms)
205 */
206 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR,
207 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR,
208
209 /*
210 * The time after it expires no new WLAN trigger frame is trasmitted
211 * in WLAN PSM / BT slave basic rate
212 *
213 * Range: 0 - 255 (ms)
214 */
215 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR,
216
217 /*
218 * Configure the min and max time BT gains the antenna
219 * in WLAN PSM / BT master EDR
220 *
221 * Range: 0 - 255 (ms)
222 */
223 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR,
224 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR,
225
226 /*
227 * The time after it expires no new WLAN trigger frame is trasmitted
228 * in WLAN PSM / BT master EDR
229 *
230 * Range: 0 - 255 (ms)
231 */
232 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR,
233
234 /*
235 * Configure the min and max time BT gains the antenna
236 * in WLAN PSM / BT slave EDR
237 *
238 * Range: 0 - 255 (ms)
239 */
240 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR,
241 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR,
242
243 /*
244 * The time after it expires no new WLAN trigger frame is trasmitted
245 * in WLAN PSM / BT slave EDR
246 *
247 * Range: 0 - 255 (ms)
248 */
249 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR,
250
251 /*
252 * RX guard time before the beginning of a new BT voice frame during
253 * which no new WLAN trigger frame is transmitted.
254 *
255 * Range: 0 - 100000 (us)
256 */
257 CONF_SG_RXT,
258
259 /*
260 * TX guard time before the beginning of a new BT voice frame during
261 * which no new WLAN frame is transmitted.
262 *
263 * Range: 0 - 100000 (us)
264 */
265
266 CONF_SG_TXT,
267
268 /*
269 * Enable adaptive RXT/TXT algorithm. If disabled, the host values
270 * will be utilized.
271 *
272 * Range: 0 - disable, 1 - enable
273 */
274 CONF_SG_ADAPTIVE_RXT_TXT,
275
276 /*
277 * The used WLAN legacy service period during active BT ACL link
278 *
279 * Range: 0 - 255 (ms)
280 */
281 CONF_SG_PS_POLL_TIMEOUT,
282
283 /*
284 * The used WLAN UPSD service period during active BT ACL link
285 *
286 * Range: 0 - 255 (ms)
79 */ 287 */
80 u32 per_threshold; 288 CONF_SG_UPSD_TIMEOUT,
81 289
82 /* 290 /*
83 * This value is an absolute time in micro-seconds to limit the 291 * Configure the min and max time BT gains the antenna
84 * maximum scan duration compensation while in SG 292 * in WLAN Active / BT master EDR
293 *
294 * Range: 0 - 255 (ms)
85 */ 295 */
86 u32 max_scan_compensation_time; 296 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR,
297 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR,
87 298
88 /* Defines the PER threshold of the BT voice of which reaching this 299 /*
89 * value will trigger raising the priority of the BT voice until next 300 * The maximum time WLAN can gain the antenna for
90 * NFS sample interval time as defined in sample_interval. 301 * in WLAN Active / BT master EDR
91 * 302 *
92 * Unit: msec 303 * Range: 0 - 255 (ms)
93 * Range: 1-65000
94 */ 304 */
95 u16 nfs_sample_interval; 305 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR,
96 306
97 /* 307 /*
98 * Defines the load ratio for the BT. 308 * Configure the min and max time BT gains the antenna
99 * The WLAN ratio is: 100 - load_ratio 309 * in WLAN Active / BT slave EDR
100 * 310 *
101 * Unit: Percent 311 * Range: 0 - 255 (ms)
102 * Range: 0-100
103 */ 312 */
104 u8 load_ratio; 313 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR,
314 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR,
105 315
106 /* 316 /*
107 * true - Co-ex is allowed to enter/exit P.S automatically and 317 * The maximum time WLAN can gain the antenna for
108 * transparently to the host 318 * in WLAN Active / BT slave EDR
109 * 319 *
110 * false - Co-ex is disallowed to enter/exit P.S and will trigger an 320 * Range: 0 - 255 (ms)
111 * event to the host to notify for the need to enter/exit P.S 321 */
112 * due to BT change state 322 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR,
323
324 /*
325 * Configure the min and max time BT gains the antenna
326 * in WLAN Active / BT basic rate
327 *
328 * Range: 0 - 255 (ms)
329 */
330 CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR,
331 CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR,
332
333 /*
334 * The maximum time WLAN can gain the antenna for
335 * in WLAN Active / BT basic rate
113 * 336 *
337 * Range: 0 - 255 (ms)
114 */ 338 */
115 u8 auto_ps_mode; 339 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR,
116 340
117 /* 341 /*
118 * This parameter defines the compensation percentage of num of probe 342 * Compensation percentage of WLAN passive scan window if initiated
119 * requests in case scan is initiated during BT voice/BT ACL 343 * during BT voice
120 * guaranteed link.
121 * 344 *
122 * Unit: Percent 345 * Range: 0 - 1000 (%)
123 * Range: 0-255 (0 - No compensation)
124 */ 346 */
125 u8 probe_req_compensation; 347 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3,
126 348
127 /* 349 /*
128 * This parameter defines the compensation percentage of scan window 350 * Compensation percentage of WLAN passive scan window if initiated
129 * size in case scan is initiated during BT voice/BT ACL Guaranteed 351 * during BT A2DP
130 * link.
131 * 352 *
132 * Unit: Percent 353 * Range: 0 - 1000 (%)
133 * Range: 0-255 (0 - No compensation)
134 */ 354 */
135 u8 scan_window_compensation; 355 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP,
136 356
137 /* 357 /*
138 * Defines the antenna configuration. 358 * Fixed time ensured for BT traffic to gain the antenna during WLAN
359 * passive scan.
139 * 360 *
140 * Range: 0 - Single Antenna; 1 - Dual Antenna 361 * Range: 0 - 1000 ms
141 */ 362 */
142 u8 antenna_config; 363 CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME,
143 364
144 /* 365 /*
145 * The percent out of the Max consecutive beacon miss roaming trigger 366 * Fixed time ensured for WLAN traffic to gain the antenna during WLAN
146 * which is the threshold for raising the priority of beacon 367 * passive scan.
147 * reception.
148 * 368 *
149 * Range: 1-100 369 * Range: 0 - 1000 ms
150 * N = MaxConsecutiveBeaconMiss
151 * P = coexMaxConsecutiveBeaconMissPrecent
152 * Threshold = MIN( N-1, round(N * P / 100))
153 */ 370 */
154 u8 beacon_miss_threshold; 371 CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME,
155 372
156 /* 373 /*
157 * The RX rate threshold below which rate adaptation is assumed to be 374 * Number of consequent BT voice frames not interrupted by WLAN
158 * occurring at the AP which will raise priority for ACTIVE_RX and RX
159 * SP.
160 * 375 *
161 * Range: HW_BIT_RATE_* 376 * Range: 0 - 100
162 */ 377 */
163 u32 rate_adaptation_threshold; 378 CONF_SG_HV3_MAX_SERVED,
164 379
165 /* 380 /*
166 * The SNR above which the RX rate threshold indicating AP rate 381 * Protection time of the DHCP procedure.
167 * adaptation is valid
168 * 382 *
169 * Range: -128 - 127 383 * Range: 0 - 100000 (ms)
170 */ 384 */
171 s8 rate_adaptation_snr; 385 CONF_SG_DHCP_TIME,
386
387 /*
388 * Compensation percentage of WLAN active scan window if initiated
389 * during BT A2DP
390 *
391 * Range: 0 - 1000 (%)
392 */
393 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP,
394 CONF_SG_TEMP_PARAM_1,
395 CONF_SG_TEMP_PARAM_2,
396 CONF_SG_TEMP_PARAM_3,
397 CONF_SG_TEMP_PARAM_4,
398 CONF_SG_TEMP_PARAM_5,
399 CONF_SG_PARAMS_MAX,
400 CONF_SG_PARAMS_ALL = 0xff
401};
402
403struct conf_sg_settings {
404 u32 params[CONF_SG_PARAMS_MAX];
405 u8 state;
172}; 406};
173 407
174enum conf_rx_queue_type { 408enum conf_rx_queue_type {
@@ -440,6 +674,19 @@ struct conf_tx_settings {
440 */ 674 */
441 u16 tx_compl_threshold; 675 u16 tx_compl_threshold;
442 676
677 /*
678 * The rate used for control messages and scanning on the 2.4GHz band
679 *
680 * Range: CONF_HW_BIT_RATE_* bit mask
681 */
682 u32 basic_rate;
683
684 /*
685 * The rate used for control messages and scanning on the 5GHz band
686 *
687 * Range: CONF_HW_BIT_RATE_* bit mask
688 */
689 u32 basic_rate_5;
443}; 690};
444 691
445enum { 692enum {
@@ -509,65 +756,6 @@ enum {
509 CONF_TRIG_EVENT_DIR_BIDIR 756 CONF_TRIG_EVENT_DIR_BIDIR
510}; 757};
511 758
512
513struct conf_sig_trigger {
514 /*
515 * The RSSI / SNR threshold value.
516 *
517 * FIXME: what is the range?
518 */
519 s16 threshold;
520
521 /*
522 * Minimum delay between two trigger events for this trigger in ms.
523 *
524 * Range: 0 - 60000
525 */
526 u16 pacing;
527
528 /*
529 * The measurement data source for this trigger.
530 *
531 * Range: CONF_TRIG_METRIC_*
532 */
533 u8 metric;
534
535 /*
536 * The trigger type of this trigger.
537 *
538 * Range: CONF_TRIG_EVENT_TYPE_*
539 */
540 u8 type;
541
542 /*
543 * The direction of the trigger.
544 *
545 * Range: CONF_TRIG_EVENT_DIR_*
546 */
547 u8 direction;
548
549 /*
550 * Hysteresis range of the trigger around the threshold (in dB)
551 *
552 * Range: u8
553 */
554 u8 hysteresis;
555
556 /*
557 * Index of the trigger rule.
558 *
559 * Range: 0 - CONF_MAX_RSSI_SNR_TRIGGERS-1
560 */
561 u8 index;
562
563 /*
564 * Enable / disable this rule (to use for clearing rules.)
565 *
566 * Range: 1 - Enabled, 2 - Not enabled
567 */
568 u8 enable;
569};
570
571struct conf_sig_weights { 759struct conf_sig_weights {
572 760
573 /* 761 /*
@@ -686,12 +874,6 @@ struct conf_conn_settings {
686 u8 ps_poll_threshold; 874 u8 ps_poll_threshold;
687 875
688 /* 876 /*
689 * Configuration of signal (rssi/snr) triggers.
690 */
691 u8 sig_trigger_count;
692 struct conf_sig_trigger sig_trigger[CONF_MAX_RSSI_SNR_TRIGGERS];
693
694 /*
695 * Configuration of signal average weights. 877 * Configuration of signal average weights.
696 */ 878 */
697 struct conf_sig_weights sig_weights; 879 struct conf_sig_weights sig_weights;
@@ -721,6 +903,22 @@ struct conf_conn_settings {
721 * Range 0 - 255 903 * Range 0 - 255
722 */ 904 */
723 u8 psm_entry_retries; 905 u8 psm_entry_retries;
906
907 /*
908 *
909 * Specifies the interval of the connection keep-alive null-func
910 * frame in ms.
911 *
912 * Range: 1000 - 3600000
913 */
914 u32 keep_alive_interval;
915
916 /*
917 * Maximum listen interval supported by the driver in units of beacons.
918 *
919 * Range: u16
920 */
921 u8 max_listen_interval;
724}; 922};
725 923
726enum { 924enum {
@@ -782,6 +980,43 @@ struct conf_pm_config_settings {
782 bool host_fast_wakeup_support; 980 bool host_fast_wakeup_support;
783}; 981};
784 982
983struct conf_roam_trigger_settings {
984 /*
985 * The minimum interval between two trigger events.
986 *
987 * Range: 0 - 60000 ms
988 */
989 u16 trigger_pacing;
990
991 /*
992 * The weight for rssi/beacon average calculation
993 *
994 * Range: 0 - 255
995 */
996 u8 avg_weight_rssi_beacon;
997
998 /*
999 * The weight for rssi/data frame average calculation
1000 *
1001 * Range: 0 - 255
1002 */
1003 u8 avg_weight_rssi_data;
1004
1005 /*
1006 * The weight for snr/beacon average calculation
1007 *
1008 * Range: 0 - 255
1009 */
1010 u8 avg_weight_snr_beacon;
1011
1012 /*
1013 * The weight for snr/data frame average calculation
1014 *
1015 * Range: 0 - 255
1016 */
1017 u8 avg_weight_snr_data;
1018};
1019
785struct conf_drv_settings { 1020struct conf_drv_settings {
786 struct conf_sg_settings sg; 1021 struct conf_sg_settings sg;
787 struct conf_rx_settings rx; 1022 struct conf_rx_settings rx;
@@ -790,6 +1025,7 @@ struct conf_drv_settings {
790 struct conf_init_settings init; 1025 struct conf_init_settings init;
791 struct conf_itrim_settings itrim; 1026 struct conf_itrim_settings itrim;
792 struct conf_pm_config_settings pm_config; 1027 struct conf_pm_config_settings pm_config;
1028 struct conf_roam_trigger_settings roam_trigger;
793}; 1029};
794 1030
795#endif 1031#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index 3f7ff8d0cf5a..c239ef4d0b8d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -29,6 +29,7 @@
29#include "wl1271.h" 29#include "wl1271.h"
30#include "wl1271_acx.h" 30#include "wl1271_acx.h"
31#include "wl1271_ps.h" 31#include "wl1271_ps.h"
32#include "wl1271_io.h"
32 33
33/* ms */ 34/* ms */
34#define WL1271_DEBUGFS_STATS_LIFETIME 1000 35#define WL1271_DEBUGFS_STATS_LIFETIME 1000
@@ -277,13 +278,10 @@ static ssize_t gpio_power_write(struct file *file,
277 goto out; 278 goto out;
278 } 279 }
279 280
280 if (value) { 281 if (value)
281 wl->set_power(true); 282 wl1271_power_on(wl);
282 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 283 else
283 } else { 284 wl1271_power_off(wl);
284 wl->set_power(false);
285 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
286 }
287 285
288out: 286out:
289 mutex_unlock(&wl->mutex); 287 mutex_unlock(&wl->mutex);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 7468ef10194b..cf37aa6eb137 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -23,7 +23,6 @@
23 23
24#include "wl1271.h" 24#include "wl1271.h"
25#include "wl1271_reg.h" 25#include "wl1271_reg.h"
26#include "wl1271_spi.h"
27#include "wl1271_io.h" 26#include "wl1271_io.h"
28#include "wl1271_event.h" 27#include "wl1271_event.h"
29#include "wl1271_ps.h" 28#include "wl1271_ps.h"
@@ -32,34 +31,24 @@
32static int wl1271_event_scan_complete(struct wl1271 *wl, 31static int wl1271_event_scan_complete(struct wl1271 *wl,
33 struct event_mailbox *mbox) 32 struct event_mailbox *mbox)
34{ 33{
35 int size = sizeof(struct wl12xx_probe_req_template);
36 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 34 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
37 mbox->scheduled_scan_status); 35 mbox->scheduled_scan_status);
38 36
39 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { 37 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
40 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { 38 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
41 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
42 NULL, size);
43 /* 2.4 GHz band scanned, scan 5 GHz band, pretend 39 /* 2.4 GHz band scanned, scan 5 GHz band, pretend
44 * to the wl1271_cmd_scan function that we are not 40 * to the wl1271_cmd_scan function that we are not
45 * scanning as it checks that. 41 * scanning as it checks that.
46 */ 42 */
47 clear_bit(WL1271_FLAG_SCANNING, &wl->flags); 43 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
44 /* FIXME: ie missing! */
48 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 45 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
46 NULL, 0,
49 wl->scan.active, 47 wl->scan.active,
50 wl->scan.high_prio, 48 wl->scan.high_prio,
51 WL1271_SCAN_BAND_5_GHZ, 49 WL1271_SCAN_BAND_5_GHZ,
52 wl->scan.probe_requests); 50 wl->scan.probe_requests);
53 } else { 51 } else {
54 if (wl->scan.state == WL1271_SCAN_BAND_2_4_GHZ)
55 wl1271_cmd_template_set(wl,
56 CMD_TEMPL_CFG_PROBE_REQ_2_4,
57 NULL, size);
58 else
59 wl1271_cmd_template_set(wl,
60 CMD_TEMPL_CFG_PROBE_REQ_5,
61 NULL, size);
62
63 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
64 ieee80211_scan_completed(wl->hw, false); 53 ieee80211_scan_completed(wl->hw, false);
65 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
@@ -92,16 +81,9 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
92 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 81 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
93 true); 82 true);
94 } else { 83 } else {
95 wl1271_error("PSM entry failed, giving up.\n"); 84 wl1271_info("No ack to nullfunc from AP.");
96 /* FIXME: this may need to be reconsidered. for now it
97 is not possible to indicate to the mac80211
98 afterwards that PSM entry failed. To maximize
99 functionality (receiving data and remaining
100 associated) make sure that we are in sync with the
101 AP in regard of PSM mode. */
102 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
103 false);
104 wl->psm_entry_retry = 0; 85 wl->psm_entry_retry = 0;
86 *beacon_loss = true;
105 } 87 }
106 break; 88 break;
107 case EVENT_ENTER_POWER_SAVE_SUCCESS: 89 case EVENT_ENTER_POWER_SAVE_SUCCESS:
@@ -143,6 +125,24 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
143 return ret; 125 return ret;
144} 126}
145 127
128static void wl1271_event_rssi_trigger(struct wl1271 *wl,
129 struct event_mailbox *mbox)
130{
131 enum nl80211_cqm_rssi_threshold_event event;
132 s8 metric = mbox->rssi_snr_trigger_metric[0];
133
134 wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);
135
136 if (metric <= wl->rssi_thold)
137 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
138 else
139 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
140
141 if (event != wl->last_rssi_event)
142 ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL);
143 wl->last_rssi_event = event;
144}
145
146static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 146static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
147{ 147{
148 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 148 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -172,10 +172,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon 172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
173 * filtering) is enabled. Without PSM, the stack will receive all 173 * filtering) is enabled. Without PSM, the stack will receive all
174 * beacons and can detect beacon loss by itself. 174 * beacons and can detect beacon loss by itself.
175 *
176 * As there's possibility that the driver disables PSM before receiving
177 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
178 *
175 */ 179 */
176 if (vector & BSS_LOSE_EVENT_ID && 180 if (vector & BSS_LOSE_EVENT_ID) {
177 test_bit(WL1271_FLAG_PSM, &wl->flags)) { 181 wl1271_info("Beacon loss detected.");
178 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
179 182
180 /* indicate to the stack, that beacons have been lost */ 183 /* indicate to the stack, that beacons have been lost */
181 beacon_loss = true; 184 beacon_loss = true;
@@ -188,17 +191,15 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
188 return ret; 191 return ret;
189 } 192 }
190 193
191 if (wl->vif && beacon_loss) { 194 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
192 /* Obviously, it's dangerous to release the mutex while 195 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
193 we are holding many of the variables in the wl struct. 196 if (wl->vif)
194 That's why it's done last in the function, and care must 197 wl1271_event_rssi_trigger(wl, mbox);
195 be taken that nothing more is done after this function
196 returns. */
197 mutex_unlock(&wl->mutex);
198 ieee80211_beacon_loss(wl->vif);
199 mutex_lock(&wl->mutex);
200 } 198 }
201 199
200 if (wl->vif && beacon_loss)
201 ieee80211_connection_loss(wl->vif);
202
202 return 0; 203 return 0;
203} 204}
204 205
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 278f9206aa56..58371008f270 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -38,6 +38,14 @@
38 */ 38 */
39 39
40enum { 40enum {
41 RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0),
42 RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1),
43 RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2),
44 RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3),
45 RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4),
46 RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5),
47 RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6),
48 RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7),
41 MEASUREMENT_START_EVENT_ID = BIT(8), 49 MEASUREMENT_START_EVENT_ID = BIT(8),
42 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), 50 MEASUREMENT_COMPLETE_EVENT_ID = BIT(9),
43 SCAN_COMPLETE_EVENT_ID = BIT(10), 51 SCAN_COMPLETE_EVENT_ID = BIT(10),
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index d189e8fe05a6..4447af1557f5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -52,50 +52,65 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
52 52
53int wl1271_init_templates_config(struct wl1271 *wl) 53int wl1271_init_templates_config(struct wl1271 *wl)
54{ 54{
55 int ret; 55 int ret, i;
56 56
57 /* send empty templates for fw memory reservation */ 57 /* send empty templates for fw memory reservation */
58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
59 sizeof(struct wl12xx_probe_req_template)); 59 sizeof(struct wl12xx_probe_req_template),
60 0, WL1271_RATE_AUTOMATIC);
60 if (ret < 0) 61 if (ret < 0)
61 return ret; 62 return ret;
62 63
63 if (wl1271_11a_enabled()) { 64 if (wl1271_11a_enabled()) {
65 size_t size = sizeof(struct wl12xx_probe_req_template);
64 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 66 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
65 NULL, 67 NULL, size, 0,
66 sizeof(struct wl12xx_probe_req_template)); 68 WL1271_RATE_AUTOMATIC);
67 if (ret < 0) 69 if (ret < 0)
68 return ret; 70 return ret;
69 } 71 }
70 72
71 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 73 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
72 sizeof(struct wl12xx_null_data_template)); 74 sizeof(struct wl12xx_null_data_template),
75 0, WL1271_RATE_AUTOMATIC);
73 if (ret < 0) 76 if (ret < 0)
74 return ret; 77 return ret;
75 78
76 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 79 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
77 sizeof(struct wl12xx_ps_poll_template)); 80 sizeof(struct wl12xx_ps_poll_template),
81 0, WL1271_RATE_AUTOMATIC);
78 if (ret < 0) 82 if (ret < 0)
79 return ret; 83 return ret;
80 84
81 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 85 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
82 sizeof 86 sizeof
83 (struct wl12xx_qos_null_data_template)); 87 (struct wl12xx_qos_null_data_template),
88 0, WL1271_RATE_AUTOMATIC);
84 if (ret < 0) 89 if (ret < 0)
85 return ret; 90 return ret;
86 91
87 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 92 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
88 sizeof 93 sizeof
89 (struct wl12xx_probe_resp_template)); 94 (struct wl12xx_probe_resp_template),
95 0, WL1271_RATE_AUTOMATIC);
90 if (ret < 0) 96 if (ret < 0)
91 return ret; 97 return ret;
92 98
93 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 99 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
94 sizeof 100 sizeof
95 (struct wl12xx_beacon_template)); 101 (struct wl12xx_beacon_template),
102 0, WL1271_RATE_AUTOMATIC);
96 if (ret < 0) 103 if (ret < 0)
97 return ret; 104 return ret;
98 105
106 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
107 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
108 WL1271_CMD_TEMPL_MAX_SIZE, i,
109 WL1271_RATE_AUTOMATIC);
110 if (ret < 0)
111 return ret;
112 }
113
99 return 0; 114 return 0;
100} 115}
101 116
@@ -161,11 +176,11 @@ int wl1271_init_pta(struct wl1271 *wl)
161{ 176{
162 int ret; 177 int ret;
163 178
164 ret = wl1271_acx_sg_enable(wl); 179 ret = wl1271_acx_sg_cfg(wl);
165 if (ret < 0) 180 if (ret < 0)
166 return ret; 181 return ret;
167 182
168 ret = wl1271_acx_sg_cfg(wl); 183 ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
169 if (ret < 0) 184 if (ret < 0)
170 return ret; 185 return ret;
171 186
@@ -237,7 +252,7 @@ int wl1271_hw_init(struct wl1271 *wl)
237 goto out_free_memmap; 252 goto out_free_memmap;
238 253
239 /* Initialize connection monitoring thresholds */ 254 /* Initialize connection monitoring thresholds */
240 ret = wl1271_acx_conn_monit_params(wl); 255 ret = wl1271_acx_conn_monit_params(wl, false);
241 if (ret < 0) 256 if (ret < 0)
242 goto out_free_memmap; 257 goto out_free_memmap;
243 258
@@ -325,6 +340,24 @@ int wl1271_hw_init(struct wl1271 *wl)
325 if (ret < 0) 340 if (ret < 0)
326 goto out_free_memmap; 341 goto out_free_memmap;
327 342
343 /* disable all keep-alive templates */
344 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
345 ret = wl1271_acx_keep_alive_config(wl, i,
346 ACX_KEEP_ALIVE_TPL_INVALID);
347 if (ret < 0)
348 goto out_free_memmap;
349 }
350
351 /* disable the keep-alive feature */
352 ret = wl1271_acx_keep_alive_mode(wl, false);
353 if (ret < 0)
354 goto out_free_memmap;
355
356 /* Configure rssi/snr averaging weights */
357 ret = wl1271_acx_rssi_snr_avg_weights(wl);
358 if (ret < 0)
359 goto out_free_memmap;
360
328 return 0; 361 return 0;
329 362
330 out_free_memmap: 363 out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c
index 5cd94d5666c2..c8759acef131 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.c
+++ b/drivers/net/wireless/wl12xx/wl1271_io.c
@@ -28,30 +28,29 @@
28 28
29#include "wl1271.h" 29#include "wl1271.h"
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "wl1271_spi.h"
32#include "wl1271_io.h" 31#include "wl1271_io.h"
33 32
34static int wl1271_translate_addr(struct wl1271 *wl, int addr) 33#define OCP_CMD_LOOP 32
34
35#define OCP_CMD_WRITE 0x1
36#define OCP_CMD_READ 0x2
37
38#define OCP_READY_MASK BIT(18)
39#define OCP_STATUS_MASK (BIT(16) | BIT(17))
40
41#define OCP_STATUS_NO_RESP 0x00000
42#define OCP_STATUS_OK 0x10000
43#define OCP_STATUS_REQ_FAILED 0x20000
44#define OCP_STATUS_RESP_ERROR 0x30000
45
46void wl1271_disable_interrupts(struct wl1271 *wl)
35{ 47{
36 /* 48 wl->if_ops->disable_irq(wl);
37 * To translate, first check to which window of addresses the 49}
38 * particular address belongs. Then subtract the starting address 50
39 * of that window from the address. Then, add offset of the 51void wl1271_enable_interrupts(struct wl1271 *wl)
40 * translated region. 52{
41 * 53 wl->if_ops->enable_irq(wl);
42 * The translated regions occur next to each other in physical device
43 * memory, so just add the sizes of the preceeding address regions to
44 * get the offset to the new region.
45 *
46 * Currently, only the two first regions are addressed, and the
47 * assumption is that all addresses will fall into either of those
48 * two.
49 */
50 if ((addr >= wl->part.reg.start) &&
51 (addr < wl->part.reg.start + wl->part.reg.size))
52 return addr - wl->part.reg.start + wl->part.mem.size;
53 else
54 return addr - wl->part.mem.start;
55} 54}
56 55
57/* Set the SPI partitions to access the chip addresses 56/* Set the SPI partitions to access the chip addresses
@@ -117,54 +116,12 @@ int wl1271_set_partition(struct wl1271 *wl,
117 116
118void wl1271_io_reset(struct wl1271 *wl) 117void wl1271_io_reset(struct wl1271 *wl)
119{ 118{
120 wl1271_spi_reset(wl); 119 wl->if_ops->reset(wl);
121} 120}
122 121
123void wl1271_io_init(struct wl1271 *wl) 122void wl1271_io_init(struct wl1271 *wl)
124{ 123{
125 wl1271_spi_init(wl); 124 wl->if_ops->init(wl);
126}
127
128void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
129 size_t len, bool fixed)
130{
131 wl1271_spi_raw_write(wl, addr, buf, len, fixed);
132}
133
134void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
135 size_t len, bool fixed)
136{
137 wl1271_spi_raw_read(wl, addr, buf, len, fixed);
138}
139
140void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
141 bool fixed)
142{
143 int physical;
144
145 physical = wl1271_translate_addr(wl, addr);
146
147 wl1271_spi_raw_read(wl, physical, buf, len, fixed);
148}
149
150void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
151 bool fixed)
152{
153 int physical;
154
155 physical = wl1271_translate_addr(wl, addr);
156
157 wl1271_spi_raw_write(wl, physical, buf, len, fixed);
158}
159
160u32 wl1271_read32(struct wl1271 *wl, int addr)
161{
162 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
163}
164
165void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
166{
167 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
168} 125}
169 126
170void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) 127void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index fa9a0b35788f..bc806c74c63a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -25,44 +25,145 @@
25#ifndef __WL1271_IO_H__ 25#ifndef __WL1271_IO_H__
26#define __WL1271_IO_H__ 26#define __WL1271_IO_H__
27 27
28#include "wl1271_reg.h"
29
30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
31
32#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0
33#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
34#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
35#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
36#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
37#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
38#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
39#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
40
41#define HW_ACCESS_REGISTER_SIZE 4
42
43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
44
28struct wl1271; 45struct wl1271;
29 46
47void wl1271_disable_interrupts(struct wl1271 *wl);
48void wl1271_enable_interrupts(struct wl1271 *wl);
49
30void wl1271_io_reset(struct wl1271 *wl); 50void wl1271_io_reset(struct wl1271 *wl);
31void wl1271_io_init(struct wl1271 *wl); 51void wl1271_io_init(struct wl1271 *wl);
32 52
33/* Raw target IO, address is not translated */ 53static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl)
34void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, 54{
35 size_t len, bool fixed); 55 return wl->if_ops->dev(wl);
36void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, 56}
37 size_t len, bool fixed);
38 57
39/* Translated target IO */
40void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,
41 bool fixed);
42void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,
43 bool fixed);
44u32 wl1271_read32(struct wl1271 *wl, int addr);
45void wl1271_write32(struct wl1271 *wl, int addr, u32 val);
46 58
47/* Top Register IO */ 59/* Raw target IO, address is not translated */
48void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); 60static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
49u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); 61 size_t len, bool fixed)
62{
63 wl->if_ops->write(wl, addr, buf, len, fixed);
64}
50 65
51int wl1271_set_partition(struct wl1271 *wl, 66static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
52 struct wl1271_partition_set *p); 67 size_t len, bool fixed)
68{
69 wl->if_ops->read(wl, addr, buf, len, fixed);
70}
53 71
54static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) 72static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
55{ 73{
56 wl1271_raw_read(wl, addr, &wl->buffer_32, 74 wl1271_raw_read(wl, addr, &wl->buffer_32,
57 sizeof(wl->buffer_32), false); 75 sizeof(wl->buffer_32), false);
58 76
59 return wl->buffer_32; 77 return le32_to_cpu(wl->buffer_32);
60} 78}
61 79
62static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) 80static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
63{ 81{
64 wl->buffer_32 = val; 82 wl->buffer_32 = cpu_to_le32(val);
65 wl1271_raw_write(wl, addr, &wl->buffer_32, 83 wl1271_raw_write(wl, addr, &wl->buffer_32,
66 sizeof(wl->buffer_32), false); 84 sizeof(wl->buffer_32), false);
67} 85}
86
87/* Translated target IO */
88static inline int wl1271_translate_addr(struct wl1271 *wl, int addr)
89{
90 /*
91 * To translate, first check to which window of addresses the
92 * particular address belongs. Then subtract the starting address
93 * of that window from the address. Then, add offset of the
94 * translated region.
95 *
96 * The translated regions occur next to each other in physical device
97 * memory, so just add the sizes of the preceeding address regions to
98 * get the offset to the new region.
99 *
100 * Currently, only the two first regions are addressed, and the
101 * assumption is that all addresses will fall into either of those
102 * two.
103 */
104 if ((addr >= wl->part.reg.start) &&
105 (addr < wl->part.reg.start + wl->part.reg.size))
106 return addr - wl->part.reg.start + wl->part.mem.size;
107 else
108 return addr - wl->part.mem.start;
109}
110
111static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
112 size_t len, bool fixed)
113{
114 int physical;
115
116 physical = wl1271_translate_addr(wl, addr);
117
118 wl1271_raw_read(wl, physical, buf, len, fixed);
119}
120
121static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
122 size_t len, bool fixed)
123{
124 int physical;
125
126 physical = wl1271_translate_addr(wl, addr);
127
128 wl1271_raw_write(wl, physical, buf, len, fixed);
129}
130
131static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
132{
133 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));
134}
135
136static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
137{
138 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
139}
140
141static inline void wl1271_power_off(struct wl1271 *wl)
142{
143 wl->if_ops->power(wl, false);
144 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
145}
146
147static inline void wl1271_power_on(struct wl1271 *wl)
148{
149 wl->if_ops->power(wl, true);
150 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
151}
152
153
154/* Top Register IO */
155void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
156u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
157
158int wl1271_set_partition(struct wl1271 *wl,
159 struct wl1271_partition_set *p);
160
161/* Functions from wl1271_main.c */
162
163int wl1271_register_hw(struct wl1271 *wl);
164void wl1271_unregister_hw(struct wl1271 *wl);
165int wl1271_init_ieee80211(struct wl1271 *wl);
166struct ieee80211_hw *wl1271_alloc_hw(void);
167int wl1271_free_hw(struct wl1271 *wl);
168
68#endif 169#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 65a1aeba2419..b7d9137851ac 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -22,23 +22,19 @@
22 */ 22 */
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/interrupt.h>
27#include <linux/firmware.h> 25#include <linux/firmware.h>
28#include <linux/delay.h> 26#include <linux/delay.h>
29#include <linux/irq.h>
30#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
31#include <linux/crc32.h> 28#include <linux/crc32.h>
32#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
33#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
34#include <linux/spi/wl12xx.h>
35#include <linux/inetdevice.h> 31#include <linux/inetdevice.h>
32#include <linux/platform_device.h>
36#include <linux/slab.h> 33#include <linux/slab.h>
37 34
38#include "wl1271.h" 35#include "wl1271.h"
39#include "wl12xx_80211.h" 36#include "wl12xx_80211.h"
40#include "wl1271_reg.h" 37#include "wl1271_reg.h"
41#include "wl1271_spi.h"
42#include "wl1271_io.h" 38#include "wl1271_io.h"
43#include "wl1271_event.h" 39#include "wl1271_event.h"
44#include "wl1271_tx.h" 40#include "wl1271_tx.h"
@@ -54,17 +50,57 @@
54 50
55static struct conf_drv_settings default_conf = { 51static struct conf_drv_settings default_conf = {
56 .sg = { 52 .sg = {
57 .per_threshold = 7500, 53 .params = {
58 .max_scan_compensation_time = 120000, 54 [CONF_SG_BT_PER_THRESHOLD] = 7500,
59 .nfs_sample_interval = 400, 55 [CONF_SG_HV3_MAX_OVERRIDE] = 0,
60 .load_ratio = 50, 56 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
61 .auto_ps_mode = 0, 57 [CONF_SG_BT_LOAD_RATIO] = 50,
62 .probe_req_compensation = 170, 58 [CONF_SG_AUTO_PS_MODE] = 0,
63 .scan_window_compensation = 50, 59 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
64 .antenna_config = 0, 60 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
65 .beacon_miss_threshold = 60, 61 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
66 .rate_adaptation_threshold = CONF_HW_BIT_RATE_12MBPS, 62 [CONF_SG_BEACON_MISS_PERCENT] = 60,
67 .rate_adaptation_snr = 0 63 [CONF_SG_RATE_ADAPT_THRESH] = 12,
64 [CONF_SG_RATE_ADAPT_SNR] = 0,
65 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10,
66 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30,
67 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8,
68 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20,
69 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50,
70 /* Note: with UPSD, this should be 4 */
71 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8,
72 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7,
73 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25,
74 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20,
75 /* Note: with UPDS, this should be 15 */
76 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8,
77 /* Note: with UPDS, this should be 50 */
78 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40,
79 /* Note: with UPDS, this should be 10 */
80 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20,
81 [CONF_SG_RXT] = 1200,
82 [CONF_SG_TXT] = 1000,
83 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
84 [CONF_SG_PS_POLL_TIMEOUT] = 10,
85 [CONF_SG_UPSD_TIMEOUT] = 10,
86 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
87 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
88 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
89 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8,
90 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20,
91 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15,
92 [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20,
93 [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50,
94 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10,
95 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
96 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
97 [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75,
98 [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15,
99 [CONF_SG_HV3_MAX_SERVED] = 6,
100 [CONF_SG_DHCP_TIME] = 5000,
101 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
102 },
103 .state = CONF_SG_PROTECTIVE,
68 }, 104 },
69 .rx = { 105 .rx = {
70 .rx_msdu_life_time = 512000, 106 .rx_msdu_life_time = 512000,
@@ -81,8 +117,7 @@ static struct conf_drv_settings default_conf = {
81 .tx = { 117 .tx = {
82 .tx_energy_detection = 0, 118 .tx_energy_detection = 0,
83 .rc_conf = { 119 .rc_conf = {
84 .enabled_rates = CONF_HW_BIT_RATE_1MBPS | 120 .enabled_rates = 0,
85 CONF_HW_BIT_RATE_2MBPS,
86 .short_retry_limit = 10, 121 .short_retry_limit = 10,
87 .long_retry_limit = 10, 122 .long_retry_limit = 10,
88 .aflags = 0 123 .aflags = 0
@@ -179,11 +214,13 @@ static struct conf_drv_settings default_conf = {
179 }, 214 },
180 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, 215 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
181 .tx_compl_timeout = 700, 216 .tx_compl_timeout = 700,
182 .tx_compl_threshold = 4 217 .tx_compl_threshold = 4,
218 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
219 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
183 }, 220 },
184 .conn = { 221 .conn = {
185 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 222 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
186 .listen_interval = 0, 223 .listen_interval = 1,
187 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, 224 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
188 .bcn_filt_ie_count = 1, 225 .bcn_filt_ie_count = 1,
189 .bcn_filt_ie = { 226 .bcn_filt_ie = {
@@ -198,38 +235,11 @@ static struct conf_drv_settings default_conf = {
198 .broadcast_timeout = 20000, 235 .broadcast_timeout = 20000,
199 .rx_broadcast_in_ps = 1, 236 .rx_broadcast_in_ps = 1,
200 .ps_poll_threshold = 20, 237 .ps_poll_threshold = 20,
201 .sig_trigger_count = 2,
202 .sig_trigger = {
203 [0] = {
204 .threshold = -75,
205 .pacing = 500,
206 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
207 .type = CONF_TRIG_EVENT_TYPE_EDGE,
208 .direction = CONF_TRIG_EVENT_DIR_LOW,
209 .hysteresis = 2,
210 .index = 0,
211 .enable = 1
212 },
213 [1] = {
214 .threshold = -75,
215 .pacing = 500,
216 .metric = CONF_TRIG_METRIC_RSSI_BEACON,
217 .type = CONF_TRIG_EVENT_TYPE_EDGE,
218 .direction = CONF_TRIG_EVENT_DIR_HIGH,
219 .hysteresis = 2,
220 .index = 1,
221 .enable = 1
222 }
223 },
224 .sig_weights = {
225 .rssi_bcn_avg_weight = 10,
226 .rssi_pkt_avg_weight = 10,
227 .snr_bcn_avg_weight = 10,
228 .snr_pkt_avg_weight = 10
229 },
230 .bet_enable = CONF_BET_MODE_ENABLE, 238 .bet_enable = CONF_BET_MODE_ENABLE,
231 .bet_max_consecutive = 10, 239 .bet_max_consecutive = 10,
232 .psm_entry_retries = 3 240 .psm_entry_retries = 3,
241 .keep_alive_interval = 55000,
242 .max_listen_interval = 20,
233 }, 243 },
234 .init = { 244 .init = {
235 .radioparam = { 245 .radioparam = {
@@ -243,9 +253,32 @@ static struct conf_drv_settings default_conf = {
243 .pm_config = { 253 .pm_config = {
244 .host_clk_settling_time = 5000, 254 .host_clk_settling_time = 5000,
245 .host_fast_wakeup_support = false 255 .host_fast_wakeup_support = false
256 },
257 .roam_trigger = {
258 /* FIXME: due to firmware bug, must use value 1 for now */
259 .trigger_pacing = 1,
260 .avg_weight_rssi_beacon = 20,
261 .avg_weight_rssi_data = 10,
262 .avg_weight_snr_beacon = 20,
263 .avg_weight_snr_data = 10
246 } 264 }
247}; 265};
248 266
267static void wl1271_device_release(struct device *dev)
268{
269
270}
271
272static struct platform_device wl1271_device = {
273 .name = "wl1271",
274 .id = -1,
275
276 /* device model insists to have a release function */
277 .dev = {
278 .release = wl1271_device_release,
279 },
280};
281
249static LIST_HEAD(wl_list); 282static LIST_HEAD(wl_list);
250 283
251static void wl1271_conf_init(struct wl1271 *wl) 284static void wl1271_conf_init(struct wl1271 *wl)
@@ -298,7 +331,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
298 goto out_free_memmap; 331 goto out_free_memmap;
299 332
300 /* Initialize connection monitoring thresholds */ 333 /* Initialize connection monitoring thresholds */
301 ret = wl1271_acx_conn_monit_params(wl); 334 ret = wl1271_acx_conn_monit_params(wl, false);
302 if (ret < 0) 335 if (ret < 0)
303 goto out_free_memmap; 336 goto out_free_memmap;
304 337
@@ -365,30 +398,14 @@ static int wl1271_plt_init(struct wl1271 *wl)
365 return ret; 398 return ret;
366} 399}
367 400
368static void wl1271_disable_interrupts(struct wl1271 *wl)
369{
370 disable_irq(wl->irq);
371}
372
373static void wl1271_power_off(struct wl1271 *wl)
374{
375 wl->set_power(false);
376 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
377}
378
379static void wl1271_power_on(struct wl1271 *wl)
380{
381 wl->set_power(true);
382 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
383}
384
385static void wl1271_fw_status(struct wl1271 *wl, 401static void wl1271_fw_status(struct wl1271 *wl,
386 struct wl1271_fw_status *status) 402 struct wl1271_fw_status *status)
387{ 403{
404 struct timespec ts;
388 u32 total = 0; 405 u32 total = 0;
389 int i; 406 int i;
390 407
391 wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); 408 wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
392 409
393 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 410 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
394 "drv_rx_counter = %d, tx_results_counter = %d)", 411 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -413,14 +430,19 @@ static void wl1271_fw_status(struct wl1271 *wl,
413 ieee80211_queue_work(wl->hw, &wl->tx_work); 430 ieee80211_queue_work(wl->hw, &wl->tx_work);
414 431
415 /* update the host-chipset time offset */ 432 /* update the host-chipset time offset */
416 wl->time_offset = jiffies_to_usecs(jiffies) - 433 getnstimeofday(&ts);
417 le32_to_cpu(status->fw_localtime); 434 wl->time_offset = (timespec_to_ns(&ts) >> 10) -
435 (s64)le32_to_cpu(status->fw_localtime);
418} 436}
419 437
438#define WL1271_IRQ_MAX_LOOPS 10
439
420static void wl1271_irq_work(struct work_struct *work) 440static void wl1271_irq_work(struct work_struct *work)
421{ 441{
422 int ret; 442 int ret;
423 u32 intr; 443 u32 intr;
444 int loopcount = WL1271_IRQ_MAX_LOOPS;
445 unsigned long flags;
424 struct wl1271 *wl = 446 struct wl1271 *wl =
425 container_of(work, struct wl1271, irq_work); 447 container_of(work, struct wl1271, irq_work);
426 448
@@ -428,91 +450,78 @@ static void wl1271_irq_work(struct work_struct *work)
428 450
429 wl1271_debug(DEBUG_IRQ, "IRQ work"); 451 wl1271_debug(DEBUG_IRQ, "IRQ work");
430 452
431 if (wl->state == WL1271_STATE_OFF) 453 if (unlikely(wl->state == WL1271_STATE_OFF))
432 goto out; 454 goto out;
433 455
434 ret = wl1271_ps_elp_wakeup(wl, true); 456 ret = wl1271_ps_elp_wakeup(wl, true);
435 if (ret < 0) 457 if (ret < 0)
436 goto out; 458 goto out;
437 459
438 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); 460 spin_lock_irqsave(&wl->wl_lock, flags);
439 461 while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) {
440 wl1271_fw_status(wl, wl->fw_status); 462 clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
441 intr = le32_to_cpu(wl->fw_status->intr); 463 spin_unlock_irqrestore(&wl->wl_lock, flags);
442 if (!intr) { 464 loopcount--;
443 wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); 465
444 goto out_sleep; 466 wl1271_fw_status(wl, wl->fw_status);
445 } 467 intr = le32_to_cpu(wl->fw_status->intr);
468 if (!intr) {
469 wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
470 spin_lock_irqsave(&wl->wl_lock, flags);
471 continue;
472 }
446 473
447 intr &= WL1271_INTR_MASK; 474 intr &= WL1271_INTR_MASK;
448 475
449 if (intr & WL1271_ACX_INTR_EVENT_A) { 476 if (intr & WL1271_ACX_INTR_DATA) {
450 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); 477 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
451 wl1271_event_handle(wl, 0);
452 }
453 478
454 if (intr & WL1271_ACX_INTR_EVENT_B) { 479 /* check for tx results */
455 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); 480 if (wl->fw_status->tx_results_counter !=
456 wl1271_event_handle(wl, 1); 481 (wl->tx_results_count & 0xff))
457 } 482 wl1271_tx_complete(wl);
458 483
459 if (intr & WL1271_ACX_INTR_INIT_COMPLETE) 484 wl1271_rx(wl, wl->fw_status);
460 wl1271_debug(DEBUG_IRQ, 485 }
461 "WL1271_ACX_INTR_INIT_COMPLETE");
462 486
463 if (intr & WL1271_ACX_INTR_HW_AVAILABLE) 487 if (intr & WL1271_ACX_INTR_EVENT_A) {
464 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); 488 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
489 wl1271_event_handle(wl, 0);
490 }
465 491
466 if (intr & WL1271_ACX_INTR_DATA) { 492 if (intr & WL1271_ACX_INTR_EVENT_B) {
467 u8 tx_res_cnt = wl->fw_status->tx_results_counter - 493 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
468 wl->tx_results_count; 494 wl1271_event_handle(wl, 1);
495 }
469 496
470 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); 497 if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
498 wl1271_debug(DEBUG_IRQ,
499 "WL1271_ACX_INTR_INIT_COMPLETE");
471 500
472 /* check for tx results */ 501 if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
473 if (tx_res_cnt) 502 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
474 wl1271_tx_complete(wl, tx_res_cnt);
475 503
476 wl1271_rx(wl, wl->fw_status); 504 spin_lock_irqsave(&wl->wl_lock, flags);
477 } 505 }
478 506
479out_sleep: 507 if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags))
480 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, 508 ieee80211_queue_work(wl->hw, &wl->irq_work);
481 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 509 else
510 clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
511 spin_unlock_irqrestore(&wl->wl_lock, flags);
512
482 wl1271_ps_elp_sleep(wl); 513 wl1271_ps_elp_sleep(wl);
483 514
484out: 515out:
485 mutex_unlock(&wl->mutex); 516 mutex_unlock(&wl->mutex);
486} 517}
487 518
488static irqreturn_t wl1271_irq(int irq, void *cookie)
489{
490 struct wl1271 *wl;
491 unsigned long flags;
492
493 wl1271_debug(DEBUG_IRQ, "IRQ");
494
495 wl = cookie;
496
497 /* complete the ELP completion */
498 spin_lock_irqsave(&wl->wl_lock, flags);
499 if (wl->elp_compl) {
500 complete(wl->elp_compl);
501 wl->elp_compl = NULL;
502 }
503
504 ieee80211_queue_work(wl->hw, &wl->irq_work);
505 spin_unlock_irqrestore(&wl->wl_lock, flags);
506
507 return IRQ_HANDLED;
508}
509
510static int wl1271_fetch_firmware(struct wl1271 *wl) 519static int wl1271_fetch_firmware(struct wl1271 *wl)
511{ 520{
512 const struct firmware *fw; 521 const struct firmware *fw;
513 int ret; 522 int ret;
514 523
515 ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev); 524 ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
516 525
517 if (ret < 0) { 526 if (ret < 0) {
518 wl1271_error("could not get firmware: %d", ret); 527 wl1271_error("could not get firmware: %d", ret);
@@ -545,46 +554,12 @@ out:
545 return ret; 554 return ret;
546} 555}
547 556
548static int wl1271_update_mac_addr(struct wl1271 *wl)
549{
550 int ret = 0;
551 u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
552
553 /* get mac address from the NVS */
554 wl->mac_addr[0] = nvs_ptr[11];
555 wl->mac_addr[1] = nvs_ptr[10];
556 wl->mac_addr[2] = nvs_ptr[6];
557 wl->mac_addr[3] = nvs_ptr[5];
558 wl->mac_addr[4] = nvs_ptr[4];
559 wl->mac_addr[5] = nvs_ptr[3];
560
561 /* FIXME: if it is a zero-address, we should bail out. Now, instead,
562 we randomize an address */
563 if (is_zero_ether_addr(wl->mac_addr)) {
564 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
565 memcpy(wl->mac_addr, nokia_oui, 3);
566 get_random_bytes(wl->mac_addr + 3, 3);
567
568 /* update this address to the NVS */
569 nvs_ptr[11] = wl->mac_addr[0];
570 nvs_ptr[10] = wl->mac_addr[1];
571 nvs_ptr[6] = wl->mac_addr[2];
572 nvs_ptr[5] = wl->mac_addr[3];
573 nvs_ptr[4] = wl->mac_addr[4];
574 nvs_ptr[3] = wl->mac_addr[5];
575 }
576
577 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
578
579 return ret;
580}
581
582static int wl1271_fetch_nvs(struct wl1271 *wl) 557static int wl1271_fetch_nvs(struct wl1271 *wl)
583{ 558{
584 const struct firmware *fw; 559 const struct firmware *fw;
585 int ret; 560 int ret;
586 561
587 ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev); 562 ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
588 563
589 if (ret < 0) { 564 if (ret < 0) {
590 wl1271_error("could not get nvs file: %d", ret); 565 wl1271_error("could not get nvs file: %d", ret);
@@ -608,8 +583,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
608 583
609 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); 584 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));
610 585
611 ret = wl1271_update_mac_addr(wl);
612
613out: 586out:
614 release_firmware(fw); 587 release_firmware(fw);
615 588
@@ -826,15 +799,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
826 * The workqueue is slow to process the tx_queue and we need stop 799 * The workqueue is slow to process the tx_queue and we need stop
827 * the queue here, otherwise the queue will get too long. 800 * the queue here, otherwise the queue will get too long.
828 */ 801 */
829 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) { 802 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
830 ieee80211_stop_queues(wl->hw); 803 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
831 804
832 /* 805 spin_lock_irqsave(&wl->wl_lock, flags);
833 * FIXME: this is racy, the variable is not properly 806 ieee80211_stop_queues(wl->hw);
834 * protected. Maybe fix this by removing the stupid
835 * variable altogether and checking the real queue state?
836 */
837 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); 807 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
808 spin_unlock_irqrestore(&wl->wl_lock, flags);
838 } 809 }
839 810
840 return NETDEV_TX_OK; 811 return NETDEV_TX_OK;
@@ -882,7 +853,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
882 if (wl == wl_temp) 853 if (wl == wl_temp)
883 break; 854 break;
884 } 855 }
885 if (wl == NULL) 856 if (wl != wl_temp)
886 return NOTIFY_DONE; 857 return NOTIFY_DONE;
887 858
888 /* Get the interface IP address for the device. "ifa" will become 859 /* Get the interface IP address for the device. "ifa" will become
@@ -929,13 +900,60 @@ static struct notifier_block wl1271_dev_notifier = {
929 900
930static int wl1271_op_start(struct ieee80211_hw *hw) 901static int wl1271_op_start(struct ieee80211_hw *hw)
931{ 902{
903 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
904
905 /*
906 * We have to delay the booting of the hardware because
907 * we need to know the local MAC address before downloading and
908 * initializing the firmware. The MAC address cannot be changed
909 * after boot, and without the proper MAC address, the firmware
910 * will not function properly.
911 *
912 * The MAC address is first known when the corresponding interface
913 * is added. That is where we will initialize the hardware.
914 */
915
916 return 0;
917}
918
919static void wl1271_op_stop(struct ieee80211_hw *hw)
920{
921 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
922}
923
924static int wl1271_op_add_interface(struct ieee80211_hw *hw,
925 struct ieee80211_vif *vif)
926{
932 struct wl1271 *wl = hw->priv; 927 struct wl1271 *wl = hw->priv;
933 int retries = WL1271_BOOT_RETRIES; 928 int retries = WL1271_BOOT_RETRIES;
934 int ret = 0; 929 int ret = 0;
935 930
936 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 931 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
932 vif->type, vif->addr);
937 933
938 mutex_lock(&wl->mutex); 934 mutex_lock(&wl->mutex);
935 if (wl->vif) {
936 ret = -EBUSY;
937 goto out;
938 }
939
940 wl->vif = vif;
941
942 switch (vif->type) {
943 case NL80211_IFTYPE_STATION:
944 wl->bss_type = BSS_TYPE_STA_BSS;
945 wl->set_bss_type = BSS_TYPE_STA_BSS;
946 break;
947 case NL80211_IFTYPE_ADHOC:
948 wl->bss_type = BSS_TYPE_IBSS;
949 wl->set_bss_type = BSS_TYPE_STA_BSS;
950 break;
951 default:
952 ret = -EOPNOTSUPP;
953 goto out;
954 }
955
956 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
939 957
940 if (wl->state != WL1271_STATE_OFF) { 958 if (wl->state != WL1271_STATE_OFF) {
941 wl1271_error("cannot start because not in off state: %d", 959 wl1271_error("cannot start because not in off state: %d",
@@ -991,19 +1009,20 @@ out:
991 return ret; 1009 return ret;
992} 1010}
993 1011
994static void wl1271_op_stop(struct ieee80211_hw *hw) 1012static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1013 struct ieee80211_vif *vif)
995{ 1014{
996 struct wl1271 *wl = hw->priv; 1015 struct wl1271 *wl = hw->priv;
997 int i; 1016 int i;
998 1017
999 wl1271_info("down");
1000
1001 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
1002
1003 unregister_inetaddr_notifier(&wl1271_dev_notifier); 1018 unregister_inetaddr_notifier(&wl1271_dev_notifier);
1004 list_del(&wl->list);
1005 1019
1006 mutex_lock(&wl->mutex); 1020 mutex_lock(&wl->mutex);
1021 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1022
1023 wl1271_info("down");
1024
1025 list_del(&wl->list);
1007 1026
1008 WARN_ON(wl->state != WL1271_STATE_ON); 1027 WARN_ON(wl->state != WL1271_STATE_ON);
1009 1028
@@ -1032,6 +1051,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1032 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); 1051 memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
1033 wl->ssid_len = 0; 1052 wl->ssid_len = 0;
1034 wl->bss_type = MAX_BSS_TYPE; 1053 wl->bss_type = MAX_BSS_TYPE;
1054 wl->set_bss_type = MAX_BSS_TYPE;
1035 wl->band = IEEE80211_BAND_2GHZ; 1055 wl->band = IEEE80211_BAND_2GHZ;
1036 1056
1037 wl->rx_counter = 0; 1057 wl->rx_counter = 0;
@@ -1041,163 +1061,142 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1041 wl->tx_results_count = 0; 1061 wl->tx_results_count = 0;
1042 wl->tx_packets_count = 0; 1062 wl->tx_packets_count = 0;
1043 wl->tx_security_last_seq = 0; 1063 wl->tx_security_last_seq = 0;
1044 wl->tx_security_seq_16 = 0; 1064 wl->tx_security_seq = 0;
1045 wl->tx_security_seq_32 = 0;
1046 wl->time_offset = 0; 1065 wl->time_offset = 0;
1047 wl->session_counter = 0; 1066 wl->session_counter = 0;
1048 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1067 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1049 wl->sta_rate_set = 0; 1068 wl->sta_rate_set = 0;
1050 wl->flags = 0; 1069 wl->flags = 0;
1070 wl->vif = NULL;
1071 wl->filters = 0;
1051 1072
1052 for (i = 0; i < NUM_TX_QUEUES; i++) 1073 for (i = 0; i < NUM_TX_QUEUES; i++)
1053 wl->tx_blocks_freed[i] = 0; 1074 wl->tx_blocks_freed[i] = 0;
1054 1075
1055 wl1271_debugfs_reset(wl); 1076 wl1271_debugfs_reset(wl);
1077
1078 kfree(wl->fw_status);
1079 wl->fw_status = NULL;
1080 kfree(wl->tx_res_if);
1081 wl->tx_res_if = NULL;
1082 kfree(wl->target_mem_map);
1083 wl->target_mem_map = NULL;
1084
1056 mutex_unlock(&wl->mutex); 1085 mutex_unlock(&wl->mutex);
1057} 1086}
1058 1087
1059static int wl1271_op_add_interface(struct ieee80211_hw *hw, 1088static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
1060 struct ieee80211_vif *vif)
1061{ 1089{
1062 struct wl1271 *wl = hw->priv; 1090 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1063 int ret = 0; 1091 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1064 1092
1065 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 1093 /* combine requested filters with current filter config */
1066 vif->type, vif->addr); 1094 filters = wl->filters | filters;
1067 1095
1068 mutex_lock(&wl->mutex); 1096 wl1271_debug(DEBUG_FILTERS, "RX filters set: ");
1069 if (wl->vif) { 1097
1070 ret = -EBUSY; 1098 if (filters & FIF_PROMISC_IN_BSS) {
1071 goto out; 1099 wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS");
1100 wl->rx_config &= ~CFG_UNI_FILTER_EN;
1101 wl->rx_config |= CFG_BSSID_FILTER_EN;
1102 }
1103 if (filters & FIF_BCN_PRBRESP_PROMISC) {
1104 wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC");
1105 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1106 wl->rx_config &= ~CFG_SSID_FILTER_EN;
1072 } 1107 }
1108 if (filters & FIF_OTHER_BSS) {
1109 wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS");
1110 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1111 }
1112 if (filters & FIF_CONTROL) {
1113 wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL");
1114 wl->rx_filter |= CFG_RX_CTL_EN;
1115 }
1116 if (filters & FIF_FCSFAIL) {
1117 wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL");
1118 wl->rx_filter |= CFG_RX_FCS_ERROR;
1119 }
1120}
1073 1121
1074 wl->vif = vif; 1122static int wl1271_dummy_join(struct wl1271 *wl)
1123{
1124 int ret = 0;
1125 /* we need to use a dummy BSSID for now */
1126 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1127 0xad, 0xbe, 0xef };
1075 1128
1076 switch (vif->type) { 1129 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1077 case NL80211_IFTYPE_STATION: 1130
1078 wl->bss_type = BSS_TYPE_STA_BSS; 1131 /* pass through frames from all BSS */
1079 break; 1132 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1080 case NL80211_IFTYPE_ADHOC: 1133
1081 wl->bss_type = BSS_TYPE_IBSS; 1134 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1082 break; 1135 if (ret < 0)
1083 default:
1084 ret = -EOPNOTSUPP;
1085 goto out; 1136 goto out;
1086 }
1087 1137
1088 /* FIXME: what if conf->mac_addr changes? */ 1138 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1089 1139
1090out: 1140out:
1091 mutex_unlock(&wl->mutex);
1092 return ret; 1141 return ret;
1093} 1142}
1094 1143
1095static void wl1271_op_remove_interface(struct ieee80211_hw *hw, 1144static int wl1271_join(struct wl1271 *wl, bool set_assoc)
1096 struct ieee80211_vif *vif)
1097{
1098 struct wl1271 *wl = hw->priv;
1099
1100 mutex_lock(&wl->mutex);
1101 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1102 wl->vif = NULL;
1103 mutex_unlock(&wl->mutex);
1104}
1105
1106#if 0
1107static int wl1271_op_config_interface(struct ieee80211_hw *hw,
1108 struct ieee80211_vif *vif,
1109 struct ieee80211_if_conf *conf)
1110{ 1145{
1111 struct wl1271 *wl = hw->priv;
1112 struct sk_buff *beacon;
1113 int ret; 1146 int ret;
1114 1147
1115 wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM", 1148 /*
1116 conf->bssid); 1149 * One of the side effects of the JOIN command is that is clears
1117 wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid, 1150 * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
1118 conf->ssid_len); 1151 * to a WPA/WPA2 access point will therefore kill the data-path.
1152 * Currently there is no supported scenario for JOIN during
1153 * association - if it becomes a supported scenario, the WPA/WPA2 keys
1154 * must be handled somehow.
1155 *
1156 */
1157 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1158 wl1271_info("JOIN while associated.");
1119 1159
1120 mutex_lock(&wl->mutex); 1160 if (set_assoc)
1161 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1121 1162
1122 ret = wl1271_ps_elp_wakeup(wl, false); 1163 ret = wl1271_cmd_join(wl, wl->set_bss_type);
1123 if (ret < 0) 1164 if (ret < 0)
1124 goto out; 1165 goto out;
1125 1166
1126 if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) { 1167 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1127 wl1271_debug(DEBUG_MAC80211, "bssid changed");
1128
1129 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
1130
1131 ret = wl1271_cmd_join(wl);
1132 if (ret < 0)
1133 goto out_sleep;
1134
1135 ret = wl1271_cmd_build_null_data(wl);
1136 if (ret < 0)
1137 goto out_sleep;
1138 }
1139
1140 wl->ssid_len = conf->ssid_len;
1141 if (wl->ssid_len)
1142 memcpy(wl->ssid, conf->ssid, wl->ssid_len);
1143
1144 if (conf->changed & IEEE80211_IFCC_BEACON) {
1145 beacon = ieee80211_beacon_get(hw, vif);
1146 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1147 beacon->data, beacon->len);
1148
1149 if (ret < 0) {
1150 dev_kfree_skb(beacon);
1151 goto out_sleep;
1152 }
1153
1154 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
1155 beacon->data, beacon->len);
1156
1157 dev_kfree_skb(beacon);
1158
1159 if (ret < 0)
1160 goto out_sleep;
1161 }
1162
1163out_sleep:
1164 wl1271_ps_elp_sleep(wl);
1165
1166out:
1167 mutex_unlock(&wl->mutex);
1168
1169 return ret;
1170}
1171#endif
1172
1173static int wl1271_join_channel(struct wl1271 *wl, int channel)
1174{
1175 int ret = 0;
1176 /* we need to use a dummy BSSID for now */
1177 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1178 0xad, 0xbe, 0xef };
1179 1168
1180 /* the dummy join is not required for ad-hoc */ 1169 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1181 if (wl->bss_type == BSS_TYPE_IBSS)
1182 goto out; 1170 goto out;
1183 1171
1184 /* disable mac filter, so we hear everything */ 1172 /*
1185 wl->rx_config &= ~CFG_BSSID_FILTER_EN; 1173 * The join command disable the keep-alive mode, shut down its process,
1174 * and also clear the template config, so we need to reset it all after
1175 * the join. The acx_aid starts the keep-alive process, and the order
1176 * of the commands below is relevant.
1177 */
1178 ret = wl1271_acx_keep_alive_mode(wl, true);
1179 if (ret < 0)
1180 goto out;
1186 1181
1187 wl->channel = channel; 1182 ret = wl1271_acx_aid(wl, wl->aid);
1188 memcpy(wl->bssid, dummy_bssid, ETH_ALEN); 1183 if (ret < 0)
1184 goto out;
1189 1185
1190 ret = wl1271_cmd_join(wl); 1186 ret = wl1271_cmd_build_klv_null_data(wl);
1191 if (ret < 0) 1187 if (ret < 0)
1192 goto out; 1188 goto out;
1193 1189
1194 set_bit(WL1271_FLAG_JOINED, &wl->flags); 1190 ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1191 ACX_KEEP_ALIVE_TPL_VALID);
1192 if (ret < 0)
1193 goto out;
1195 1194
1196out: 1195out:
1197 return ret; 1196 return ret;
1198} 1197}
1199 1198
1200static int wl1271_unjoin_channel(struct wl1271 *wl) 1199static int wl1271_unjoin(struct wl1271 *wl)
1201{ 1200{
1202 int ret; 1201 int ret;
1203 1202
@@ -1207,14 +1206,41 @@ static int wl1271_unjoin_channel(struct wl1271 *wl)
1207 goto out; 1206 goto out;
1208 1207
1209 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 1208 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1210 wl->channel = 0;
1211 memset(wl->bssid, 0, ETH_ALEN); 1209 memset(wl->bssid, 0, ETH_ALEN);
1212 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 1210
1211 /* stop filterting packets based on bssid */
1212 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1213 1213
1214out: 1214out:
1215 return ret; 1215 return ret;
1216} 1216}
1217 1217
1218static void wl1271_set_band_rate(struct wl1271 *wl)
1219{
1220 if (wl->band == IEEE80211_BAND_2GHZ)
1221 wl->basic_rate_set = wl->conf.tx.basic_rate;
1222 else
1223 wl->basic_rate_set = wl->conf.tx.basic_rate_5;
1224}
1225
1226static u32 wl1271_min_rate_get(struct wl1271 *wl)
1227{
1228 int i;
1229 u32 rate = 0;
1230
1231 if (!wl->basic_rate_set) {
1232 WARN_ON(1);
1233 wl->basic_rate_set = wl->conf.tx.basic_rate;
1234 }
1235
1236 for (i = 0; !rate; i++) {
1237 if ((wl->basic_rate_set >> i) & 0x1)
1238 rate = 1 << i;
1239 }
1240
1241 return rate;
1242}
1243
1218static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1244static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1219{ 1245{
1220 struct wl1271 *wl = hw->priv; 1246 struct wl1271 *wl = hw->priv;
@@ -1231,38 +1257,62 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1231 1257
1232 mutex_lock(&wl->mutex); 1258 mutex_lock(&wl->mutex);
1233 1259
1234 wl->band = conf->channel->band; 1260 if (unlikely(wl->state == WL1271_STATE_OFF))
1261 goto out;
1235 1262
1236 ret = wl1271_ps_elp_wakeup(wl, false); 1263 ret = wl1271_ps_elp_wakeup(wl, false);
1237 if (ret < 0) 1264 if (ret < 0)
1238 goto out; 1265 goto out;
1239 1266
1267 /* if the channel changes while joined, join again */
1268 if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
1269 ((wl->band != conf->channel->band) ||
1270 (wl->channel != channel))) {
1271 wl->band = conf->channel->band;
1272 wl->channel = channel;
1273
1274 /*
1275 * FIXME: the mac80211 should really provide a fixed rate
1276 * to use here. for now, just use the smallest possible rate
1277 * for the band as a fixed rate for association frames and
1278 * other control messages.
1279 */
1280 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1281 wl1271_set_band_rate(wl);
1282
1283 wl->basic_rate = wl1271_min_rate_get(wl);
1284 ret = wl1271_acx_rate_policies(wl);
1285 if (ret < 0)
1286 wl1271_warning("rate policy for update channel "
1287 "failed %d", ret);
1288
1289 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1290 ret = wl1271_join(wl, false);
1291 if (ret < 0)
1292 wl1271_warning("cmd join to update channel "
1293 "failed %d", ret);
1294 }
1295 }
1296
1240 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1297 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1241 if (conf->flags & IEEE80211_CONF_IDLE && 1298 if (conf->flags & IEEE80211_CONF_IDLE &&
1242 test_bit(WL1271_FLAG_JOINED, &wl->flags)) 1299 test_bit(WL1271_FLAG_JOINED, &wl->flags))
1243 wl1271_unjoin_channel(wl); 1300 wl1271_unjoin(wl);
1244 else if (!(conf->flags & IEEE80211_CONF_IDLE)) 1301 else if (!(conf->flags & IEEE80211_CONF_IDLE))
1245 wl1271_join_channel(wl, channel); 1302 wl1271_dummy_join(wl);
1246 1303
1247 if (conf->flags & IEEE80211_CONF_IDLE) { 1304 if (conf->flags & IEEE80211_CONF_IDLE) {
1248 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1305 wl->rate_set = wl1271_min_rate_get(wl);
1249 wl->sta_rate_set = 0; 1306 wl->sta_rate_set = 0;
1250 wl1271_acx_rate_policies(wl); 1307 wl1271_acx_rate_policies(wl);
1251 } 1308 wl1271_acx_keep_alive_config(
1309 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1310 ACX_KEEP_ALIVE_TPL_INVALID);
1311 set_bit(WL1271_FLAG_IDLE, &wl->flags);
1312 } else
1313 clear_bit(WL1271_FLAG_IDLE, &wl->flags);
1252 } 1314 }
1253 1315
1254 /* if the channel changes while joined, join again */
1255 if (channel != wl->channel &&
1256 test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1257 wl->channel = channel;
1258 /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */
1259 ret = wl1271_cmd_join(wl);
1260 if (ret < 0)
1261 wl1271_warning("cmd join to update channel failed %d",
1262 ret);
1263 } else
1264 wl->channel = channel;
1265
1266 if (conf->flags & IEEE80211_CONF_PS && 1316 if (conf->flags & IEEE80211_CONF_PS &&
1267 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1317 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1268 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1318 set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
@@ -1273,13 +1323,13 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1273 * through the bss_info_changed() hook. 1323 * through the bss_info_changed() hook.
1274 */ 1324 */
1275 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { 1325 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1276 wl1271_info("psm enabled"); 1326 wl1271_debug(DEBUG_PSM, "psm enabled");
1277 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 1327 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1278 true); 1328 true);
1279 } 1329 }
1280 } else if (!(conf->flags & IEEE80211_CONF_PS) && 1330 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1281 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1331 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
1282 wl1271_info("psm disabled"); 1332 wl1271_debug(DEBUG_PSM, "psm disabled");
1283 1333
1284 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1334 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
1285 1335
@@ -1311,11 +1361,15 @@ struct wl1271_filter_params {
1311 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; 1361 u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
1312}; 1362};
1313 1363
1314static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 1364static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
1315 struct dev_addr_list *mc_list) 1365 struct netdev_hw_addr_list *mc_list)
1316{ 1366{
1317 struct wl1271_filter_params *fp; 1367 struct wl1271_filter_params *fp;
1318 int i; 1368 struct netdev_hw_addr *ha;
1369 struct wl1271 *wl = hw->priv;
1370
1371 if (unlikely(wl->state == WL1271_STATE_OFF))
1372 return 0;
1319 1373
1320 fp = kzalloc(sizeof(*fp), GFP_ATOMIC); 1374 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
1321 if (!fp) { 1375 if (!fp) {
@@ -1324,21 +1378,16 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
1324 } 1378 }
1325 1379
1326 /* update multicast filtering parameters */ 1380 /* update multicast filtering parameters */
1327 fp->enabled = true;
1328 if (mc_count > ACX_MC_ADDRESS_GROUP_MAX) {
1329 mc_count = 0;
1330 fp->enabled = false;
1331 }
1332
1333 fp->mc_list_length = 0; 1381 fp->mc_list_length = 0;
1334 for (i = 0; i < mc_count; i++) { 1382 if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
1335 if (mc_list->da_addrlen == ETH_ALEN) { 1383 fp->enabled = false;
1384 } else {
1385 fp->enabled = true;
1386 netdev_hw_addr_list_for_each(ha, mc_list) {
1336 memcpy(fp->mc_list[fp->mc_list_length], 1387 memcpy(fp->mc_list[fp->mc_list_length],
1337 mc_list->da_addr, ETH_ALEN); 1388 ha->addr, ETH_ALEN);
1338 fp->mc_list_length++; 1389 fp->mc_list_length++;
1339 } else 1390 }
1340 wl1271_warning("Unknown mc address length.");
1341 mc_list = mc_list->next;
1342 } 1391 }
1343 1392
1344 return (u64)(unsigned long)fp; 1393 return (u64)(unsigned long)fp;
@@ -1363,15 +1412,16 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1363 1412
1364 mutex_lock(&wl->mutex); 1413 mutex_lock(&wl->mutex);
1365 1414
1366 if (wl->state == WL1271_STATE_OFF) 1415 *total &= WL1271_SUPPORTED_FILTERS;
1416 changed &= WL1271_SUPPORTED_FILTERS;
1417
1418 if (unlikely(wl->state == WL1271_STATE_OFF))
1367 goto out; 1419 goto out;
1368 1420
1369 ret = wl1271_ps_elp_wakeup(wl, false); 1421 ret = wl1271_ps_elp_wakeup(wl, false);
1370 if (ret < 0) 1422 if (ret < 0)
1371 goto out; 1423 goto out;
1372 1424
1373 *total &= WL1271_SUPPORTED_FILTERS;
1374 changed &= WL1271_SUPPORTED_FILTERS;
1375 1425
1376 if (*total & FIF_ALLMULTI) 1426 if (*total & FIF_ALLMULTI)
1377 ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); 1427 ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0);
@@ -1382,14 +1432,14 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1382 if (ret < 0) 1432 if (ret < 0)
1383 goto out_sleep; 1433 goto out_sleep;
1384 1434
1385 kfree(fp);
1386
1387 /* FIXME: We still need to set our filters properly */
1388
1389 /* determine, whether supported filter values have changed */ 1435 /* determine, whether supported filter values have changed */
1390 if (changed == 0) 1436 if (changed == 0)
1391 goto out_sleep; 1437 goto out_sleep;
1392 1438
1439 /* configure filters */
1440 wl->filters = *total;
1441 wl1271_configure_filters(wl, 0);
1442
1393 /* apply configured filters */ 1443 /* apply configured filters */
1394 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); 1444 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
1395 if (ret < 0) 1445 if (ret < 0)
@@ -1400,6 +1450,7 @@ out_sleep:
1400 1450
1401out: 1451out:
1402 mutex_unlock(&wl->mutex); 1452 mutex_unlock(&wl->mutex);
1453 kfree(fp);
1403} 1454}
1404 1455
1405static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 1456static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -1450,15 +1501,15 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1450 key_type = KEY_TKIP; 1501 key_type = KEY_TKIP;
1451 1502
1452 key_conf->hw_key_idx = key_conf->keyidx; 1503 key_conf->hw_key_idx = key_conf->keyidx;
1453 tx_seq_32 = wl->tx_security_seq_32; 1504 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1454 tx_seq_16 = wl->tx_security_seq_16; 1505 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1455 break; 1506 break;
1456 case ALG_CCMP: 1507 case ALG_CCMP:
1457 key_type = KEY_AES; 1508 key_type = KEY_AES;
1458 1509
1459 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 1510 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1460 tx_seq_32 = wl->tx_security_seq_32; 1511 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
1461 tx_seq_16 = wl->tx_security_seq_16; 1512 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
1462 break; 1513 break;
1463 default: 1514 default:
1464 wl1271_error("Unknown key algo 0x%x", key_conf->alg); 1515 wl1271_error("Unknown key algo 0x%x", key_conf->alg);
@@ -1508,8 +1559,6 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1508 default: 1559 default:
1509 wl1271_error("Unsupported key cmd 0x%x", cmd); 1560 wl1271_error("Unsupported key cmd 0x%x", cmd);
1510 ret = -EOPNOTSUPP; 1561 ret = -EOPNOTSUPP;
1511 goto out_sleep;
1512
1513 break; 1562 break;
1514 } 1563 }
1515 1564
@@ -1524,6 +1573,7 @@ out:
1524} 1573}
1525 1574
1526static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 1575static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1576 struct ieee80211_vif *vif,
1527 struct cfg80211_scan_request *req) 1577 struct cfg80211_scan_request *req)
1528{ 1578{
1529 struct wl1271 *wl = hw->priv; 1579 struct wl1271 *wl = hw->priv;
@@ -1545,10 +1595,12 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1545 goto out; 1595 goto out;
1546 1596
1547 if (wl1271_11a_enabled()) 1597 if (wl1271_11a_enabled())
1548 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1598 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1599 req->ie, req->ie_len, 1, 0,
1549 WL1271_SCAN_BAND_DUAL, 3); 1600 WL1271_SCAN_BAND_DUAL, 3);
1550 else 1601 else
1551 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1602 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1603 req->ie, req->ie_len, 1, 0,
1552 WL1271_SCAN_BAND_2_4_GHZ, 3); 1604 WL1271_SCAN_BAND_2_4_GHZ, 3);
1553 1605
1554 wl1271_ps_elp_sleep(wl); 1606 wl1271_ps_elp_sleep(wl);
@@ -1562,10 +1614,13 @@ out:
1562static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1614static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1563{ 1615{
1564 struct wl1271 *wl = hw->priv; 1616 struct wl1271 *wl = hw->priv;
1565 int ret; 1617 int ret = 0;
1566 1618
1567 mutex_lock(&wl->mutex); 1619 mutex_lock(&wl->mutex);
1568 1620
1621 if (unlikely(wl->state == WL1271_STATE_OFF))
1622 goto out;
1623
1569 ret = wl1271_ps_elp_wakeup(wl, false); 1624 ret = wl1271_ps_elp_wakeup(wl, false);
1570 if (ret < 0) 1625 if (ret < 0)
1571 goto out; 1626 goto out;
@@ -1607,6 +1662,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1607 enum wl1271_cmd_ps_mode mode; 1662 enum wl1271_cmd_ps_mode mode;
1608 struct wl1271 *wl = hw->priv; 1663 struct wl1271 *wl = hw->priv;
1609 bool do_join = false; 1664 bool do_join = false;
1665 bool set_assoc = false;
1610 int ret; 1666 int ret;
1611 1667
1612 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 1668 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1617,20 +1673,29 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1617 if (ret < 0) 1673 if (ret < 0)
1618 goto out; 1674 goto out;
1619 1675
1620 if (wl->bss_type == BSS_TYPE_IBSS) { 1676 if ((changed && BSS_CHANGED_BEACON_INT) &&
1621 /* FIXME: This implements rudimentary ad-hoc support - 1677 (wl->bss_type == BSS_TYPE_IBSS)) {
1622 proper templates are on the wish list and notification 1678 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
1623 on when they change. This patch will update the templates 1679 bss_conf->beacon_int);
1624 on every call to this function. */ 1680
1681 wl->beacon_int = bss_conf->beacon_int;
1682 do_join = true;
1683 }
1684
1685 if ((changed && BSS_CHANGED_BEACON) &&
1686 (wl->bss_type == BSS_TYPE_IBSS)) {
1625 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 1687 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
1626 1688
1689 wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated");
1690
1627 if (beacon) { 1691 if (beacon) {
1628 struct ieee80211_hdr *hdr; 1692 struct ieee80211_hdr *hdr;
1629 1693
1630 wl1271_ssid_set(wl, beacon); 1694 wl1271_ssid_set(wl, beacon);
1631 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1695 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1632 beacon->data, 1696 beacon->data,
1633 beacon->len); 1697 beacon->len, 0,
1698 wl1271_min_rate_get(wl));
1634 1699
1635 if (ret < 0) { 1700 if (ret < 0) {
1636 dev_kfree_skb(beacon); 1701 dev_kfree_skb(beacon);
@@ -1645,7 +1710,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1645 ret = wl1271_cmd_template_set(wl, 1710 ret = wl1271_cmd_template_set(wl,
1646 CMD_TEMPL_PROBE_RESPONSE, 1711 CMD_TEMPL_PROBE_RESPONSE,
1647 beacon->data, 1712 beacon->data,
1648 beacon->len); 1713 beacon->len, 0,
1714 wl1271_min_rate_get(wl));
1649 dev_kfree_skb(beacon); 1715 dev_kfree_skb(beacon);
1650 if (ret < 0) 1716 if (ret < 0)
1651 goto out_sleep; 1717 goto out_sleep;
@@ -1655,20 +1721,48 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1655 } 1721 }
1656 } 1722 }
1657 1723
1724 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1725 (wl->bss_type == BSS_TYPE_IBSS)) {
1726 wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
1727 bss_conf->enable_beacon ? "enabled" : "disabled");
1728
1729 if (bss_conf->enable_beacon)
1730 wl->set_bss_type = BSS_TYPE_IBSS;
1731 else
1732 wl->set_bss_type = BSS_TYPE_STA_BSS;
1733 do_join = true;
1734 }
1735
1736 if (changed & BSS_CHANGED_CQM) {
1737 bool enable = false;
1738 if (bss_conf->cqm_rssi_thold)
1739 enable = true;
1740 ret = wl1271_acx_rssi_snr_trigger(wl, enable,
1741 bss_conf->cqm_rssi_thold,
1742 bss_conf->cqm_rssi_hyst);
1743 if (ret < 0)
1744 goto out;
1745 wl->rssi_thold = bss_conf->cqm_rssi_thold;
1746 }
1747
1658 if ((changed & BSS_CHANGED_BSSID) && 1748 if ((changed & BSS_CHANGED_BSSID) &&
1659 /* 1749 /*
1660 * Now we know the correct bssid, so we send a new join command 1750 * Now we know the correct bssid, so we send a new join command
1661 * and enable the BSSID filter 1751 * and enable the BSSID filter
1662 */ 1752 */
1663 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { 1753 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1664 wl->rx_config |= CFG_BSSID_FILTER_EN;
1665 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1754 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1755
1666 ret = wl1271_cmd_build_null_data(wl); 1756 ret = wl1271_cmd_build_null_data(wl);
1667 if (ret < 0) { 1757 if (ret < 0)
1668 wl1271_warning("cmd buld null data failed %d", 1758 goto out_sleep;
1669 ret); 1759
1760 ret = wl1271_build_qos_null_data(wl);
1761 if (ret < 0)
1670 goto out_sleep; 1762 goto out_sleep;
1671 } 1763
1764 /* filter out all packets not from this BSSID */
1765 wl1271_configure_filters(wl, 0);
1672 1766
1673 /* Need to update the BSSID (for filtering etc) */ 1767 /* Need to update the BSSID (for filtering etc) */
1674 do_join = true; 1768 do_join = true;
@@ -1676,8 +1770,21 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1676 1770
1677 if (changed & BSS_CHANGED_ASSOC) { 1771 if (changed & BSS_CHANGED_ASSOC) {
1678 if (bss_conf->assoc) { 1772 if (bss_conf->assoc) {
1773 u32 rates;
1679 wl->aid = bss_conf->aid; 1774 wl->aid = bss_conf->aid;
1680 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1775 set_assoc = true;
1776
1777 /*
1778 * use basic rates from AP, and determine lowest rate
1779 * to use with control frames.
1780 */
1781 rates = bss_conf->basic_rates;
1782 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
1783 rates);
1784 wl->basic_rate = wl1271_min_rate_get(wl);
1785 ret = wl1271_acx_rate_policies(wl);
1786 if (ret < 0)
1787 goto out_sleep;
1681 1788
1682 /* 1789 /*
1683 * with wl1271, we don't need to update the 1790 * with wl1271, we don't need to update the
@@ -1689,7 +1796,17 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1689 if (ret < 0) 1796 if (ret < 0)
1690 goto out_sleep; 1797 goto out_sleep;
1691 1798
1692 ret = wl1271_acx_aid(wl, wl->aid); 1799 /*
1800 * The SSID is intentionally set to NULL here - the
1801 * firmware will set the probe request with a
1802 * broadcast SSID regardless of what we set in the
1803 * template.
1804 */
1805 ret = wl1271_cmd_build_probe_req(wl, NULL, 0,
1806 NULL, 0, wl->band);
1807
1808 /* enable the connection monitoring feature */
1809 ret = wl1271_acx_conn_monit_params(wl, true);
1693 if (ret < 0) 1810 if (ret < 0)
1694 goto out_sleep; 1811 goto out_sleep;
1695 1812
@@ -1705,6 +1822,22 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1705 /* use defaults when not associated */ 1822 /* use defaults when not associated */
1706 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 1823 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1707 wl->aid = 0; 1824 wl->aid = 0;
1825
1826 /* revert back to minimum rates for the current band */
1827 wl1271_set_band_rate(wl);
1828 wl->basic_rate = wl1271_min_rate_get(wl);
1829 ret = wl1271_acx_rate_policies(wl);
1830 if (ret < 0)
1831 goto out_sleep;
1832
1833 /* disable connection monitor features */
1834 ret = wl1271_acx_conn_monit_params(wl, false);
1835
1836 /* Disable the keep-alive feature */
1837 ret = wl1271_acx_keep_alive_mode(wl, false);
1838
1839 if (ret < 0)
1840 goto out_sleep;
1708 } 1841 }
1709 1842
1710 } 1843 }
@@ -1739,12 +1872,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1739 } 1872 }
1740 1873
1741 if (do_join) { 1874 if (do_join) {
1742 ret = wl1271_cmd_join(wl); 1875 ret = wl1271_join(wl, set_assoc);
1743 if (ret < 0) { 1876 if (ret < 0) {
1744 wl1271_warning("cmd join failed %d", ret); 1877 wl1271_warning("cmd join failed %d", ret);
1745 goto out_sleep; 1878 goto out_sleep;
1746 } 1879 }
1747 set_bit(WL1271_FLAG_JOINED, &wl->flags);
1748 } 1880 }
1749 1881
1750out_sleep: 1882out_sleep:
@@ -1758,6 +1890,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1758 const struct ieee80211_tx_queue_params *params) 1890 const struct ieee80211_tx_queue_params *params)
1759{ 1891{
1760 struct wl1271 *wl = hw->priv; 1892 struct wl1271 *wl = hw->priv;
1893 u8 ps_scheme;
1761 int ret; 1894 int ret;
1762 1895
1763 mutex_lock(&wl->mutex); 1896 mutex_lock(&wl->mutex);
@@ -1768,17 +1901,22 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1768 if (ret < 0) 1901 if (ret < 0)
1769 goto out; 1902 goto out;
1770 1903
1904 /* the txop is confed in units of 32us by the mac80211, we need us */
1771 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), 1905 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
1772 params->cw_min, params->cw_max, 1906 params->cw_min, params->cw_max,
1773 params->aifs, params->txop); 1907 params->aifs, params->txop << 5);
1774 if (ret < 0) 1908 if (ret < 0)
1775 goto out_sleep; 1909 goto out_sleep;
1776 1910
1911 if (params->uapsd)
1912 ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
1913 else
1914 ps_scheme = CONF_PS_SCHEME_LEGACY;
1915
1777 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), 1916 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
1778 CONF_CHANNEL_TYPE_EDCF, 1917 CONF_CHANNEL_TYPE_EDCF,
1779 wl1271_tx_get_queue(queue), 1918 wl1271_tx_get_queue(queue),
1780 CONF_PS_SCHEME_LEGACY_PSPOLL, 1919 ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0);
1781 CONF_ACK_POLICY_LEGACY, 0, 0);
1782 if (ret < 0) 1920 if (ret < 0)
1783 goto out_sleep; 1921 goto out_sleep;
1784 1922
@@ -1852,6 +1990,36 @@ static struct ieee80211_channel wl1271_channels[] = {
1852 { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, 1990 { .hw_value = 13, .center_freq = 2472, .max_power = 25 },
1853}; 1991};
1854 1992
1993/* mapping to indexes for wl1271_rates */
1994const static u8 wl1271_rate_to_idx_2ghz[] = {
1995 /* MCS rates are used only with 11n */
1996 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
1997 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
1998 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
1999 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
2000 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
2001 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
2002 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
2003 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
2004
2005 11, /* CONF_HW_RXTX_RATE_54 */
2006 10, /* CONF_HW_RXTX_RATE_48 */
2007 9, /* CONF_HW_RXTX_RATE_36 */
2008 8, /* CONF_HW_RXTX_RATE_24 */
2009
2010 /* TI-specific rate */
2011 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
2012
2013 7, /* CONF_HW_RXTX_RATE_18 */
2014 6, /* CONF_HW_RXTX_RATE_12 */
2015 3, /* CONF_HW_RXTX_RATE_11 */
2016 5, /* CONF_HW_RXTX_RATE_9 */
2017 4, /* CONF_HW_RXTX_RATE_6 */
2018 2, /* CONF_HW_RXTX_RATE_5_5 */
2019 1, /* CONF_HW_RXTX_RATE_2 */
2020 0 /* CONF_HW_RXTX_RATE_1 */
2021};
2022
1855/* can't be const, mac80211 writes to this */ 2023/* can't be const, mac80211 writes to this */
1856static struct ieee80211_supported_band wl1271_band_2ghz = { 2024static struct ieee80211_supported_band wl1271_band_2ghz = {
1857 .channels = wl1271_channels, 2025 .channels = wl1271_channels,
@@ -1934,6 +2102,35 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
1934 { .hw_value = 165, .center_freq = 5825}, 2102 { .hw_value = 165, .center_freq = 5825},
1935}; 2103};
1936 2104
2105/* mapping to indexes for wl1271_rates_5ghz */
2106const static u8 wl1271_rate_to_idx_5ghz[] = {
2107 /* MCS rates are used only with 11n */
2108 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
2109 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
2110 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
2111 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
2112 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
2113 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
2114 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
2115 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
2116
2117 7, /* CONF_HW_RXTX_RATE_54 */
2118 6, /* CONF_HW_RXTX_RATE_48 */
2119 5, /* CONF_HW_RXTX_RATE_36 */
2120 4, /* CONF_HW_RXTX_RATE_24 */
2121
2122 /* TI-specific rate */
2123 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
2124
2125 3, /* CONF_HW_RXTX_RATE_18 */
2126 2, /* CONF_HW_RXTX_RATE_12 */
2127 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
2128 1, /* CONF_HW_RXTX_RATE_9 */
2129 0, /* CONF_HW_RXTX_RATE_6 */
2130 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
2131 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
2132 CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
2133};
1937 2134
1938static struct ieee80211_supported_band wl1271_band_5ghz = { 2135static struct ieee80211_supported_band wl1271_band_5ghz = {
1939 .channels = wl1271_channels_5ghz, 2136 .channels = wl1271_channels_5ghz,
@@ -1942,13 +2139,17 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
1942 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2139 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
1943}; 2140};
1944 2141
2142const static u8 *wl1271_band_rate_to_idx[] = {
2143 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
2144 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
2145};
2146
1945static const struct ieee80211_ops wl1271_ops = { 2147static const struct ieee80211_ops wl1271_ops = {
1946 .start = wl1271_op_start, 2148 .start = wl1271_op_start,
1947 .stop = wl1271_op_stop, 2149 .stop = wl1271_op_stop,
1948 .add_interface = wl1271_op_add_interface, 2150 .add_interface = wl1271_op_add_interface,
1949 .remove_interface = wl1271_op_remove_interface, 2151 .remove_interface = wl1271_op_remove_interface,
1950 .config = wl1271_op_config, 2152 .config = wl1271_op_config,
1951/* .config_interface = wl1271_op_config_interface, */
1952 .prepare_multicast = wl1271_op_prepare_multicast, 2153 .prepare_multicast = wl1271_op_prepare_multicast,
1953 .configure_filter = wl1271_op_configure_filter, 2154 .configure_filter = wl1271_op_configure_filter,
1954 .tx = wl1271_op_tx, 2155 .tx = wl1271_op_tx,
@@ -1960,7 +2161,113 @@ static const struct ieee80211_ops wl1271_ops = {
1960 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 2161 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
1961}; 2162};
1962 2163
1963static int wl1271_register_hw(struct wl1271 *wl) 2164
2165u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate)
2166{
2167 u8 idx;
2168
2169 BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
2170
2171 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
2172 wl1271_error("Illegal RX rate from HW: %d", rate);
2173 return 0;
2174 }
2175
2176 idx = wl1271_band_rate_to_idx[wl->band][rate];
2177 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
2178 wl1271_error("Unsupported RX rate from HW: %d", rate);
2179 return 0;
2180 }
2181
2182 return idx;
2183}
2184
2185static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
2186 struct device_attribute *attr,
2187 char *buf)
2188{
2189 struct wl1271 *wl = dev_get_drvdata(dev);
2190 ssize_t len;
2191
2192 /* FIXME: what's the maximum length of buf? page size?*/
2193 len = 500;
2194
2195 mutex_lock(&wl->mutex);
2196 len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
2197 wl->sg_enabled);
2198 mutex_unlock(&wl->mutex);
2199
2200 return len;
2201
2202}
2203
2204static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
2205 struct device_attribute *attr,
2206 const char *buf, size_t count)
2207{
2208 struct wl1271 *wl = dev_get_drvdata(dev);
2209 unsigned long res;
2210 int ret;
2211
2212 ret = strict_strtoul(buf, 10, &res);
2213
2214 if (ret < 0) {
2215 wl1271_warning("incorrect value written to bt_coex_mode");
2216 return count;
2217 }
2218
2219 mutex_lock(&wl->mutex);
2220
2221 res = !!res;
2222
2223 if (res == wl->sg_enabled)
2224 goto out;
2225
2226 wl->sg_enabled = res;
2227
2228 if (wl->state == WL1271_STATE_OFF)
2229 goto out;
2230
2231 ret = wl1271_ps_elp_wakeup(wl, false);
2232 if (ret < 0)
2233 goto out;
2234
2235 wl1271_acx_sg_enable(wl, wl->sg_enabled);
2236 wl1271_ps_elp_sleep(wl);
2237
2238 out:
2239 mutex_unlock(&wl->mutex);
2240 return count;
2241}
2242
2243static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
2244 wl1271_sysfs_show_bt_coex_state,
2245 wl1271_sysfs_store_bt_coex_state);
2246
2247static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
2248 struct device_attribute *attr,
2249 char *buf)
2250{
2251 struct wl1271 *wl = dev_get_drvdata(dev);
2252 ssize_t len;
2253
2254 /* FIXME: what's the maximum length of buf? page size?*/
2255 len = 500;
2256
2257 mutex_lock(&wl->mutex);
2258 if (wl->hw_pg_ver >= 0)
2259 len = snprintf(buf, len, "%d\n", wl->hw_pg_ver);
2260 else
2261 len = snprintf(buf, len, "n/a\n");
2262 mutex_unlock(&wl->mutex);
2263
2264 return len;
2265}
2266
2267static DEVICE_ATTR(hw_pg_ver, S_IRUGO | S_IWUSR,
2268 wl1271_sysfs_show_hw_pg_ver, NULL);
2269
2270int wl1271_register_hw(struct wl1271 *wl)
1964{ 2271{
1965 int ret; 2272 int ret;
1966 2273
@@ -1981,8 +2288,17 @@ static int wl1271_register_hw(struct wl1271 *wl)
1981 2288
1982 return 0; 2289 return 0;
1983} 2290}
2291EXPORT_SYMBOL_GPL(wl1271_register_hw);
2292
2293void wl1271_unregister_hw(struct wl1271 *wl)
2294{
2295 ieee80211_unregister_hw(wl->hw);
2296 wl->mac80211_registered = false;
2297
2298}
2299EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
1984 2300
1985static int wl1271_init_ieee80211(struct wl1271 *wl) 2301int wl1271_init_ieee80211(struct wl1271 *wl)
1986{ 2302{
1987 /* The tx descriptor buffer and the TKIP space. */ 2303 /* The tx descriptor buffer and the TKIP space. */
1988 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + 2304 wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
@@ -1991,11 +2307,15 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
1991 /* unit us */ 2307 /* unit us */
1992 /* FIXME: find a proper value */ 2308 /* FIXME: find a proper value */
1993 wl->hw->channel_change_time = 10000; 2309 wl->hw->channel_change_time = 10000;
2310 wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
1994 2311
1995 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 2312 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1996 IEEE80211_HW_NOISE_DBM |
1997 IEEE80211_HW_BEACON_FILTER | 2313 IEEE80211_HW_BEACON_FILTER |
1998 IEEE80211_HW_SUPPORTS_PS; 2314 IEEE80211_HW_SUPPORTS_PS |
2315 IEEE80211_HW_SUPPORTS_UAPSD |
2316 IEEE80211_HW_HAS_RATE_CONTROL |
2317 IEEE80211_HW_CONNECTION_MONITOR |
2318 IEEE80211_HW_SUPPORTS_CQM_RSSI;
1999 2319
2000 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2320 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2001 BIT(NL80211_IFTYPE_ADHOC); 2321 BIT(NL80211_IFTYPE_ADHOC);
@@ -2005,51 +2325,53 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
2005 if (wl1271_11a_enabled()) 2325 if (wl1271_11a_enabled())
2006 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; 2326 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2007 2327
2008 SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); 2328 wl->hw->queues = 4;
2329 wl->hw->max_rates = 1;
2009 2330
2010 return 0; 2331 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
2011}
2012
2013static void wl1271_device_release(struct device *dev)
2014{
2015 2332
2333 return 0;
2016} 2334}
2017 2335EXPORT_SYMBOL_GPL(wl1271_init_ieee80211);
2018static struct platform_device wl1271_device = {
2019 .name = "wl1271",
2020 .id = -1,
2021
2022 /* device model insists to have a release function */
2023 .dev = {
2024 .release = wl1271_device_release,
2025 },
2026};
2027 2336
2028#define WL1271_DEFAULT_CHANNEL 0 2337#define WL1271_DEFAULT_CHANNEL 0
2029 2338
2030static struct ieee80211_hw *wl1271_alloc_hw(void) 2339struct ieee80211_hw *wl1271_alloc_hw(void)
2031{ 2340{
2032 struct ieee80211_hw *hw; 2341 struct ieee80211_hw *hw;
2342 struct platform_device *plat_dev = NULL;
2033 struct wl1271 *wl; 2343 struct wl1271 *wl;
2034 int i; 2344 int i, ret;
2035 2345
2036 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2346 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
2037 if (!hw) { 2347 if (!hw) {
2038 wl1271_error("could not alloc ieee80211_hw"); 2348 wl1271_error("could not alloc ieee80211_hw");
2039 return ERR_PTR(-ENOMEM); 2349 ret = -ENOMEM;
2350 goto err_hw_alloc;
2351 }
2352
2353 plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL);
2354 if (!plat_dev) {
2355 wl1271_error("could not allocate platform_device");
2356 ret = -ENOMEM;
2357 goto err_plat_alloc;
2040 } 2358 }
2041 2359
2360 memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device));
2361
2042 wl = hw->priv; 2362 wl = hw->priv;
2043 memset(wl, 0, sizeof(*wl)); 2363 memset(wl, 0, sizeof(*wl));
2044 2364
2045 INIT_LIST_HEAD(&wl->list); 2365 INIT_LIST_HEAD(&wl->list);
2046 2366
2047 wl->hw = hw; 2367 wl->hw = hw;
2368 wl->plat_dev = plat_dev;
2048 2369
2049 skb_queue_head_init(&wl->tx_queue); 2370 skb_queue_head_init(&wl->tx_queue);
2050 2371
2051 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2372 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2052 wl->channel = WL1271_DEFAULT_CHANNEL; 2373 wl->channel = WL1271_DEFAULT_CHANNEL;
2374 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
2053 wl->default_key = 0; 2375 wl->default_key = 0;
2054 wl->rx_counter = 0; 2376 wl->rx_counter = 0;
2055 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 2377 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
@@ -2057,11 +2379,14 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
2057 wl->psm_entry_retry = 0; 2379 wl->psm_entry_retry = 0;
2058 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 2380 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
2059 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 2381 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
2382 wl->basic_rate = CONF_TX_RATE_MASK_BASIC;
2060 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 2383 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2061 wl->sta_rate_set = 0; 2384 wl->sta_rate_set = 0;
2062 wl->band = IEEE80211_BAND_2GHZ; 2385 wl->band = IEEE80211_BAND_2GHZ;
2063 wl->vif = NULL; 2386 wl->vif = NULL;
2064 wl->flags = 0; 2387 wl->flags = 0;
2388 wl->sg_enabled = true;
2389 wl->hw_pg_ver = -1;
2065 2390
2066 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 2391 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
2067 wl->tx_frames[i] = NULL; 2392 wl->tx_frames[i] = NULL;
@@ -2074,167 +2399,72 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
2074 /* Apply default driver configuration. */ 2399 /* Apply default driver configuration. */
2075 wl1271_conf_init(wl); 2400 wl1271_conf_init(wl);
2076 2401
2077 return hw; 2402 wl1271_debugfs_init(wl);
2078}
2079
2080int wl1271_free_hw(struct wl1271 *wl)
2081{
2082 ieee80211_unregister_hw(wl->hw);
2083
2084 wl1271_debugfs_exit(wl);
2085
2086 kfree(wl->target_mem_map);
2087 vfree(wl->fw);
2088 wl->fw = NULL;
2089 kfree(wl->nvs);
2090 wl->nvs = NULL;
2091
2092 kfree(wl->fw_status);
2093 kfree(wl->tx_res_if);
2094
2095 ieee80211_free_hw(wl->hw);
2096
2097 return 0;
2098}
2099
2100static int __devinit wl1271_probe(struct spi_device *spi)
2101{
2102 struct wl12xx_platform_data *pdata;
2103 struct ieee80211_hw *hw;
2104 struct wl1271 *wl;
2105 int ret;
2106 2403
2107 pdata = spi->dev.platform_data; 2404 /* Register platform device */
2108 if (!pdata) { 2405 ret = platform_device_register(wl->plat_dev);
2109 wl1271_error("no platform data"); 2406 if (ret) {
2110 return -ENODEV; 2407 wl1271_error("couldn't register platform device");
2408 goto err_hw;
2111 } 2409 }
2410 dev_set_drvdata(&wl->plat_dev->dev, wl);
2112 2411
2113 hw = wl1271_alloc_hw(); 2412 /* Create sysfs file to control bt coex state */
2114 if (IS_ERR(hw)) 2413 ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state);
2115 return PTR_ERR(hw);
2116
2117 wl = hw->priv;
2118
2119 dev_set_drvdata(&spi->dev, wl);
2120 wl->spi = spi;
2121
2122 /* This is the only SPI value that we need to set here, the rest
2123 * comes from the board-peripherals file */
2124 spi->bits_per_word = 32;
2125
2126 ret = spi_setup(spi);
2127 if (ret < 0) { 2414 if (ret < 0) {
2128 wl1271_error("spi_setup failed"); 2415 wl1271_error("failed to create sysfs file bt_coex_state");
2129 goto out_free; 2416 goto err_platform;
2130 }
2131
2132 wl->set_power = pdata->set_power;
2133 if (!wl->set_power) {
2134 wl1271_error("set power function missing in platform data");
2135 ret = -ENODEV;
2136 goto out_free;
2137 } 2417 }
2138 2418
2139 wl->irq = spi->irq; 2419 /* Create sysfs file to get HW PG version */
2140 if (wl->irq < 0) { 2420 ret = device_create_file(&wl->plat_dev->dev, &dev_attr_hw_pg_ver);
2141 wl1271_error("irq missing in platform data");
2142 ret = -ENODEV;
2143 goto out_free;
2144 }
2145
2146 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
2147 if (ret < 0) { 2421 if (ret < 0) {
2148 wl1271_error("request_irq() failed: %d", ret); 2422 wl1271_error("failed to create sysfs file hw_pg_ver");
2149 goto out_free; 2423 goto err_bt_coex_state;
2150 }
2151
2152 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
2153
2154 disable_irq(wl->irq);
2155
2156 ret = platform_device_register(&wl1271_device);
2157 if (ret) {
2158 wl1271_error("couldn't register platform device");
2159 goto out_irq;
2160 } 2424 }
2161 dev_set_drvdata(&wl1271_device.dev, wl);
2162
2163 ret = wl1271_init_ieee80211(wl);
2164 if (ret)
2165 goto out_platform;
2166
2167 ret = wl1271_register_hw(wl);
2168 if (ret)
2169 goto out_platform;
2170
2171 wl1271_debugfs_init(wl);
2172 2425
2173 wl1271_notice("initialized"); 2426 return hw;
2174 2427
2175 return 0; 2428err_bt_coex_state:
2429 device_remove_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state);
2176 2430
2177 out_platform: 2431err_platform:
2178 platform_device_unregister(&wl1271_device); 2432 platform_device_unregister(wl->plat_dev);
2179 2433
2180 out_irq: 2434err_hw:
2181 free_irq(wl->irq, wl); 2435 wl1271_debugfs_exit(wl);
2436 kfree(plat_dev);
2182 2437
2183 out_free: 2438err_plat_alloc:
2184 ieee80211_free_hw(hw); 2439 ieee80211_free_hw(hw);
2185 2440
2186 return ret; 2441err_hw_alloc:
2187}
2188
2189static int __devexit wl1271_remove(struct spi_device *spi)
2190{
2191 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
2192 2442
2193 platform_device_unregister(&wl1271_device); 2443 return ERR_PTR(ret);
2194 free_irq(wl->irq, wl);
2195
2196 wl1271_free_hw(wl);
2197
2198 return 0;
2199} 2444}
2445EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
2200 2446
2201 2447int wl1271_free_hw(struct wl1271 *wl)
2202static struct spi_driver wl1271_spi_driver = {
2203 .driver = {
2204 .name = "wl1271",
2205 .bus = &spi_bus_type,
2206 .owner = THIS_MODULE,
2207 },
2208
2209 .probe = wl1271_probe,
2210 .remove = __devexit_p(wl1271_remove),
2211};
2212
2213static int __init wl1271_init(void)
2214{ 2448{
2215 int ret; 2449 platform_device_unregister(wl->plat_dev);
2450 kfree(wl->plat_dev);
2216 2451
2217 ret = spi_register_driver(&wl1271_spi_driver); 2452 wl1271_debugfs_exit(wl);
2218 if (ret < 0) {
2219 wl1271_error("failed to register spi driver: %d", ret);
2220 goto out;
2221 }
2222 2453
2223out: 2454 vfree(wl->fw);
2224 return ret; 2455 wl->fw = NULL;
2225} 2456 kfree(wl->nvs);
2457 wl->nvs = NULL;
2226 2458
2227static void __exit wl1271_exit(void) 2459 kfree(wl->fw_status);
2228{ 2460 kfree(wl->tx_res_if);
2229 spi_unregister_driver(&wl1271_spi_driver);
2230 2461
2231 wl1271_notice("unloaded"); 2462 ieee80211_free_hw(wl->hw);
2232}
2233 2463
2234module_init(wl1271_init); 2464 return 0;
2235module_exit(wl1271_exit); 2465}
2466EXPORT_SYMBOL_GPL(wl1271_free_hw);
2236 2467
2237MODULE_LICENSE("GPL"); 2468MODULE_LICENSE("GPL");
2238MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); 2469MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
2239MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 2470MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
2240MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index e2b1ebf096e8..a5e60e0403e5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -23,7 +23,6 @@
23 23
24#include "wl1271_reg.h" 24#include "wl1271_reg.h"
25#include "wl1271_ps.h" 25#include "wl1271_ps.h"
26#include "wl1271_spi.h"
27#include "wl1271_io.h" 26#include "wl1271_io.h"
28 27
29#define WL1271_WAKEUP_TIMEOUT 500 28#define WL1271_WAKEUP_TIMEOUT 500
@@ -41,7 +40,8 @@ void wl1271_elp_work(struct work_struct *work)
41 mutex_lock(&wl->mutex); 40 mutex_lock(&wl->mutex);
42 41
43 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || 42 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
44 !test_bit(WL1271_FLAG_PSM, &wl->flags)) 43 (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
44 !test_bit(WL1271_FLAG_IDLE, &wl->flags)))
45 goto out; 45 goto out;
46 46
47 wl1271_debug(DEBUG_PSM, "chip to elp"); 47 wl1271_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,8 @@ out:
57/* Routines to toggle sleep mode while in ELP */ 57/* Routines to toggle sleep mode while in ELP */
58void wl1271_ps_elp_sleep(struct wl1271 *wl) 58void wl1271_ps_elp_sleep(struct wl1271 *wl)
59{ 59{
60 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { 60 if (test_bit(WL1271_FLAG_PSM, &wl->flags) ||
61 test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
61 cancel_delayed_work(&wl->elp_work); 62 cancel_delayed_work(&wl->elp_work);
62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 63 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
63 msecs_to_jiffies(ELP_ENTRY_DELAY)); 64 msecs_to_jiffies(ELP_ENTRY_DELAY));
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index c723d9c7e131..57f4bfd959c8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -27,7 +27,6 @@
27#include "wl1271_acx.h" 27#include "wl1271_acx.h"
28#include "wl1271_reg.h" 28#include "wl1271_reg.h"
29#include "wl1271_rx.h" 29#include "wl1271_rx.h"
30#include "wl1271_spi.h"
31#include "wl1271_io.h" 30#include "wl1271_io.h"
32 31
33static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, 32static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
@@ -44,66 +43,6 @@ static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
44 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 43 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
45} 44}
46 45
47/* The values of this table must match the wl1271_rates[] array */
48static u8 wl1271_rx_rate_to_idx[] = {
49 /* MCS rates are used only with 11n */
50 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
51 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
52 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
53 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
54 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
55 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
56 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
57 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
58
59 11, /* WL1271_RATE_54 */
60 10, /* WL1271_RATE_48 */
61 9, /* WL1271_RATE_36 */
62 8, /* WL1271_RATE_24 */
63
64 /* TI-specific rate */
65 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
66
67 7, /* WL1271_RATE_18 */
68 6, /* WL1271_RATE_12 */
69 3, /* WL1271_RATE_11 */
70 5, /* WL1271_RATE_9 */
71 4, /* WL1271_RATE_6 */
72 2, /* WL1271_RATE_5_5 */
73 1, /* WL1271_RATE_2 */
74 0 /* WL1271_RATE_1 */
75};
76
77/* The values of this table must match the wl1271_rates[] array */
78static u8 wl1271_5_ghz_rx_rate_to_idx[] = {
79 /* MCS rates are used only with 11n */
80 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
81 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
82 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
83 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
84 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
85 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
86 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
87 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
88
89 7, /* WL1271_RATE_54 */
90 6, /* WL1271_RATE_48 */
91 5, /* WL1271_RATE_36 */
92 4, /* WL1271_RATE_24 */
93
94 /* TI-specific rate */
95 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22 */
96
97 3, /* WL1271_RATE_18 */
98 2, /* WL1271_RATE_12 */
99 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_11 */
100 1, /* WL1271_RATE_9 */
101 0, /* WL1271_RATE_6 */
102 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_5_5 */
103 WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_2 */
104 WL1271_RX_RATE_UNSUPPORTED /* WL1271_RATE_1 */
105};
106
107static void wl1271_rx_status(struct wl1271 *wl, 46static void wl1271_rx_status(struct wl1271 *wl,
108 struct wl1271_rx_descriptor *desc, 47 struct wl1271_rx_descriptor *desc,
109 struct ieee80211_rx_status *status, 48 struct ieee80211_rx_status *status,
@@ -111,20 +50,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
111{ 50{
112 memset(status, 0, sizeof(struct ieee80211_rx_status)); 51 memset(status, 0, sizeof(struct ieee80211_rx_status));
113 52
114 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == 53 status->band = wl->band;
115 WL1271_RX_DESC_BAND_BG) { 54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
116 status->band = IEEE80211_BAND_2GHZ;
117 status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
118 } else if ((desc->flags & WL1271_RX_DESC_BAND_MASK) ==
119 WL1271_RX_DESC_BAND_A) {
120 status->band = IEEE80211_BAND_5GHZ;
121 status->rate_idx = wl1271_5_ghz_rx_rate_to_idx[desc->rate];
122 } else
123 wl1271_warning("unsupported band 0x%x",
124 desc->flags & WL1271_RX_DESC_BAND_MASK);
125
126 if (unlikely(status->rate_idx == WL1271_RX_RATE_UNSUPPORTED))
127 wl1271_warning("unsupported rate");
128 55
129 /* 56 /*
130 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the 57 * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the
@@ -134,13 +61,6 @@ static void wl1271_rx_status(struct wl1271 *wl,
134 */ 61 */
135 status->signal = desc->rssi; 62 status->signal = desc->rssi;
136 63
137 /*
138 * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we
139 * need to divide by two for now, but TI has been discussing about
140 * changing it. This needs to be rechecked.
141 */
142 status->noise = desc->rssi - (desc->snr >> 1);
143
144 status->freq = ieee80211_channel_to_frequency(desc->channel); 64 status->freq = ieee80211_channel_to_frequency(desc->channel);
145 65
146 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { 66 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
@@ -162,6 +82,13 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
162 u8 *buf; 82 u8 *buf;
163 u8 beacon = 0; 83 u8 beacon = 0;
164 84
85 /*
86 * In PLT mode we seem to get frames and mac80211 warns about them,
87 * workaround this by not retrieving them at all.
88 */
89 if (unlikely(wl->state == WL1271_STATE_PLT))
90 return;
91
165 skb = __dev_alloc_skb(length, GFP_KERNEL); 92 skb = __dev_alloc_skb(length, GFP_KERNEL);
166 if (!skb) { 93 if (!skb) {
167 wl1271_error("Couldn't allocate RX frame"); 94 wl1271_error("Couldn't allocate RX frame");
@@ -220,6 +147,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
220 147
221 wl->rx_counter++; 148 wl->rx_counter++;
222 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 149 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
223 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
224 } 150 }
151
152 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
225} 153}
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
index 1ae6d1783ed4..b89be4758e78 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -43,7 +43,6 @@
43#define RX_MAX_PACKET_ID 3 43#define RX_MAX_PACKET_ID 3
44 44
45#define NUM_RX_PKT_DESC_MOD_MASK 7 45#define NUM_RX_PKT_DESC_MOD_MASK 7
46#define WL1271_RX_RATE_UNSUPPORTED 0xFF
47 46
48#define RX_DESC_VALID_FCS 0x0001 47#define RX_DESC_VALID_FCS 0x0001
49#define RX_DESC_MATCH_RXADDR1 0x0002 48#define RX_DESC_MATCH_RXADDR1 0x0002
@@ -117,5 +116,6 @@ struct wl1271_rx_descriptor {
117} __attribute__ ((packed)); 116} __attribute__ ((packed));
118 117
119void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); 118void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
119u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
120 120
121#endif 121#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
new file mode 100644
index 000000000000..d3d6f302f705
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -0,0 +1,291 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/irq.h>
25#include <linux/module.h>
26#include <linux/crc7.h>
27#include <linux/vmalloc.h>
28#include <linux/mmc/sdio_func.h>
29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/card.h>
31#include <plat/gpio.h>
32
33#include "wl1271.h"
34#include "wl12xx_80211.h"
35#include "wl1271_io.h"
36
37
38#define RX71_WL1271_IRQ_GPIO 42
39
40#ifndef SDIO_VENDOR_ID_TI
41#define SDIO_VENDOR_ID_TI 0x0097
42#endif
43
44#ifndef SDIO_DEVICE_ID_TI_WL1271
45#define SDIO_DEVICE_ID_TI_WL1271 0x4076
46#endif
47
48static const struct sdio_device_id wl1271_devices[] = {
49 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
50 {}
51};
52MODULE_DEVICE_TABLE(sdio, wl1271_devices);
53
54static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
55{
56 return wl->if_priv;
57}
58
59static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
60{
61 return &(wl_to_func(wl)->dev);
62}
63
64static irqreturn_t wl1271_irq(int irq, void *cookie)
65{
66 struct wl1271 *wl = cookie;
67 unsigned long flags;
68
69 wl1271_debug(DEBUG_IRQ, "IRQ");
70
71 /* complete the ELP completion */
72 spin_lock_irqsave(&wl->wl_lock, flags);
73 if (wl->elp_compl) {
74 complete(wl->elp_compl);
75 wl->elp_compl = NULL;
76 }
77
78 if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
79 ieee80211_queue_work(wl->hw, &wl->irq_work);
80 set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
81 spin_unlock_irqrestore(&wl->wl_lock, flags);
82
83 return IRQ_HANDLED;
84}
85
86static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
87{
88 disable_irq(wl->irq);
89}
90
91static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
92{
93 enable_irq(wl->irq);
94}
95
96static void wl1271_sdio_reset(struct wl1271 *wl)
97{
98}
99
100static void wl1271_sdio_init(struct wl1271 *wl)
101{
102}
103
104static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
105 size_t len, bool fixed)
106{
107 int ret;
108 struct sdio_func *func = wl_to_func(wl);
109
110 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
111 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
112 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
113 addr, ((u8 *)buf)[0]);
114 } else {
115 if (fixed)
116 ret = sdio_readsb(func, buf, addr, len);
117 else
118 ret = sdio_memcpy_fromio(func, buf, addr, len);
119
120 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
121 addr, len);
122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
123 }
124
125 if (ret)
126 wl1271_error("sdio read failed (%d)", ret);
127
128}
129
130static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
131 size_t len, bool fixed)
132{
133 int ret;
134 struct sdio_func *func = wl_to_func(wl);
135
136 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
137 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
139 addr, ((u8 *)buf)[0]);
140 } else {
141 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
142 addr, len);
143 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
144
145 if (fixed)
146 ret = sdio_writesb(func, addr, buf, len);
147 else
148 ret = sdio_memcpy_toio(func, addr, buf, len);
149 }
150 if (ret)
151 wl1271_error("sdio write failed (%d)", ret);
152
153}
154
155static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
156{
157 struct sdio_func *func = wl_to_func(wl);
158
159 /* Let the SDIO stack handle wlan_enable control, so we
160 * keep host claimed while wlan is in use to keep wl1271
161 * alive.
162 */
163 if (enable) {
164 sdio_claim_host(func);
165 sdio_enable_func(func);
166 } else {
167 sdio_disable_func(func);
168 sdio_release_host(func);
169 }
170}
171
172static struct wl1271_if_operations sdio_ops = {
173 .read = wl1271_sdio_raw_read,
174 .write = wl1271_sdio_raw_write,
175 .reset = wl1271_sdio_reset,
176 .init = wl1271_sdio_init,
177 .power = wl1271_sdio_set_power,
178 .dev = wl1271_sdio_wl_to_dev,
179 .enable_irq = wl1271_sdio_enable_interrupts,
180 .disable_irq = wl1271_sdio_disable_interrupts
181};
182
183static int __devinit wl1271_probe(struct sdio_func *func,
184 const struct sdio_device_id *id)
185{
186 struct ieee80211_hw *hw;
187 struct wl1271 *wl;
188 int ret;
189
190 /* We are only able to handle the wlan function */
191 if (func->num != 0x02)
192 return -ENODEV;
193
194 hw = wl1271_alloc_hw();
195 if (IS_ERR(hw))
196 return PTR_ERR(hw);
197
198 wl = hw->priv;
199
200 wl->if_priv = func;
201 wl->if_ops = &sdio_ops;
202
203 /* Grab access to FN0 for ELP reg. */
204 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
205
206 wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO);
207 if (wl->irq < 0) {
208 ret = wl->irq;
209 wl1271_error("could not get irq!");
210 goto out_free;
211 }
212
213 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
214 if (ret < 0) {
215 wl1271_error("request_irq() failed: %d", ret);
216 goto out_free;
217 }
218
219 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
220
221 disable_irq(wl->irq);
222
223 ret = wl1271_init_ieee80211(wl);
224 if (ret)
225 goto out_irq;
226
227 ret = wl1271_register_hw(wl);
228 if (ret)
229 goto out_irq;
230
231 sdio_set_drvdata(func, wl);
232
233 wl1271_notice("initialized");
234
235 return 0;
236
237 out_irq:
238 free_irq(wl->irq, wl);
239
240
241 out_free:
242 wl1271_free_hw(wl);
243
244 return ret;
245}
246
247static void __devexit wl1271_remove(struct sdio_func *func)
248{
249 struct wl1271 *wl = sdio_get_drvdata(func);
250
251 free_irq(wl->irq, wl);
252
253 wl1271_unregister_hw(wl);
254 wl1271_free_hw(wl);
255}
256
257static struct sdio_driver wl1271_sdio_driver = {
258 .name = "wl1271_sdio",
259 .id_table = wl1271_devices,
260 .probe = wl1271_probe,
261 .remove = __devexit_p(wl1271_remove),
262};
263
264static int __init wl1271_init(void)
265{
266 int ret;
267
268 ret = sdio_register_driver(&wl1271_sdio_driver);
269 if (ret < 0) {
270 wl1271_error("failed to register sdio driver: %d", ret);
271 goto out;
272 }
273
274out:
275 return ret;
276}
277
278static void __exit wl1271_exit(void)
279{
280 sdio_unregister_driver(&wl1271_sdio_driver);
281
282 wl1271_notice("unloaded");
283}
284
285module_init(wl1271_init);
286module_exit(wl1271_exit);
287
288MODULE_LICENSE("GPL");
289MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
290MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
291MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 053c84aceb49..5189b812f939 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -21,18 +21,69 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/irq.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/wl12xx.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
29 30
30#include "wl1271.h" 31#include "wl1271.h"
31#include "wl12xx_80211.h" 32#include "wl12xx_80211.h"
32#include "wl1271_spi.h" 33#include "wl1271_io.h"
34
35#include "wl1271_reg.h"
36
37#define WSPI_CMD_READ 0x40000000
38#define WSPI_CMD_WRITE 0x00000000
39#define WSPI_CMD_FIXED 0x20000000
40#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
41#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
42#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
43
44#define WSPI_INIT_CMD_CRC_LEN 5
45
46#define WSPI_INIT_CMD_START 0x00
47#define WSPI_INIT_CMD_TX 0x40
48/* the extra bypass bit is sampled by the TNET as '1' */
49#define WSPI_INIT_CMD_BYPASS_BIT 0x80
50#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
51#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
52#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
53#define WSPI_INIT_CMD_IOD 0x40
54#define WSPI_INIT_CMD_IP 0x20
55#define WSPI_INIT_CMD_CS 0x10
56#define WSPI_INIT_CMD_WS 0x08
57#define WSPI_INIT_CMD_WSPI 0x01
58#define WSPI_INIT_CMD_END 0x01
59
60#define WSPI_INIT_CMD_LEN 8
61
62#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
63 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
64#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
65
66static inline struct spi_device *wl_to_spi(struct wl1271 *wl)
67{
68 return wl->if_priv;
69}
33 70
71static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl)
72{
73 return &(wl_to_spi(wl)->dev);
74}
34 75
35void wl1271_spi_reset(struct wl1271 *wl) 76static void wl1271_spi_disable_interrupts(struct wl1271 *wl)
77{
78 disable_irq(wl->irq);
79}
80
81static void wl1271_spi_enable_interrupts(struct wl1271 *wl)
82{
83 enable_irq(wl->irq);
84}
85
86static void wl1271_spi_reset(struct wl1271 *wl)
36{ 87{
37 u8 *cmd; 88 u8 *cmd;
38 struct spi_transfer t; 89 struct spi_transfer t;
@@ -53,12 +104,13 @@ void wl1271_spi_reset(struct wl1271 *wl)
53 t.len = WSPI_INIT_CMD_LEN; 104 t.len = WSPI_INIT_CMD_LEN;
54 spi_message_add_tail(&t, &m); 105 spi_message_add_tail(&t, &m);
55 106
56 spi_sync(wl->spi, &m); 107 spi_sync(wl_to_spi(wl), &m);
108 kfree(cmd);
57 109
58 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); 110 wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
59} 111}
60 112
61void wl1271_spi_init(struct wl1271 *wl) 113static void wl1271_spi_init(struct wl1271 *wl)
62{ 114{
63 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; 115 u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
64 struct spi_transfer t; 116 struct spi_transfer t;
@@ -107,48 +159,25 @@ void wl1271_spi_init(struct wl1271 *wl)
107 t.len = WSPI_INIT_CMD_LEN; 159 t.len = WSPI_INIT_CMD_LEN;
108 spi_message_add_tail(&t, &m); 160 spi_message_add_tail(&t, &m);
109 161
110 spi_sync(wl->spi, &m); 162 spi_sync(wl_to_spi(wl), &m);
163 kfree(cmd);
111 164
112 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); 165 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
113} 166}
114 167
115#define WL1271_BUSY_WORD_TIMEOUT 1000 168#define WL1271_BUSY_WORD_TIMEOUT 1000
116 169
117/* FIXME: Check busy words, removed due to SPI bug */ 170static int wl1271_spi_read_busy(struct wl1271 *wl)
118#if 0
119static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
120{ 171{
121 struct spi_transfer t[1]; 172 struct spi_transfer t[1];
122 struct spi_message m; 173 struct spi_message m;
123 u32 *busy_buf; 174 u32 *busy_buf;
124 int num_busy_bytes = 0; 175 int num_busy_bytes = 0;
125 176
126 wl1271_info("spi read BUSY!");
127
128 /*
129 * Look for the non-busy word in the read buffer, and if found,
130 * read in the remaining data into the buffer.
131 */
132 busy_buf = (u32 *)buf;
133 for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
134 num_busy_bytes += sizeof(u32);
135 if (*busy_buf & 0x1) {
136 spi_message_init(&m);
137 memset(t, 0, sizeof(t));
138 memmove(buf, busy_buf, len - num_busy_bytes);
139 t[0].rx_buf = buf + (len - num_busy_bytes);
140 t[0].len = num_busy_bytes;
141 spi_message_add_tail(&t[0], &m);
142 spi_sync(wl->spi, &m);
143 return;
144 }
145 }
146
147 /* 177 /*
148 * Read further busy words from SPI until a non-busy word is 178 * Read further busy words from SPI until a non-busy word is
149 * encountered, then read the data itself into the buffer. 179 * encountered, then read the data itself into the buffer.
150 */ 180 */
151 wl1271_info("spi read BUSY-polling needed!");
152 181
153 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; 182 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
154 busy_buf = wl->buffer_busyword; 183 busy_buf = wl->buffer_busyword;
@@ -158,28 +187,21 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
158 memset(t, 0, sizeof(t)); 187 memset(t, 0, sizeof(t));
159 t[0].rx_buf = busy_buf; 188 t[0].rx_buf = busy_buf;
160 t[0].len = sizeof(u32); 189 t[0].len = sizeof(u32);
190 t[0].cs_change = true;
161 spi_message_add_tail(&t[0], &m); 191 spi_message_add_tail(&t[0], &m);
162 spi_sync(wl->spi, &m); 192 spi_sync(wl_to_spi(wl), &m);
163 193
164 if (*busy_buf & 0x1) { 194 if (*busy_buf & 0x1)
165 spi_message_init(&m); 195 return 0;
166 memset(t, 0, sizeof(t));
167 t[0].rx_buf = buf;
168 t[0].len = len;
169 spi_message_add_tail(&t[0], &m);
170 spi_sync(wl->spi, &m);
171 return;
172 }
173 } 196 }
174 197
175 /* The SPI bus is unresponsive, the read failed. */ 198 /* The SPI bus is unresponsive, the read failed. */
176 memset(buf, 0, len);
177 wl1271_error("SPI read busy-word timeout!\n"); 199 wl1271_error("SPI read busy-word timeout!\n");
200 return -ETIMEDOUT;
178} 201}
179#endif
180 202
181void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 203static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
182 size_t len, bool fixed) 204 size_t len, bool fixed)
183{ 205{
184 struct spi_transfer t[3]; 206 struct spi_transfer t[3];
185 struct spi_message m; 207 struct spi_message m;
@@ -202,28 +224,38 @@ void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
202 224
203 t[0].tx_buf = cmd; 225 t[0].tx_buf = cmd;
204 t[0].len = 4; 226 t[0].len = 4;
227 t[0].cs_change = true;
205 spi_message_add_tail(&t[0], &m); 228 spi_message_add_tail(&t[0], &m);
206 229
207 /* Busy and non busy words read */ 230 /* Busy and non busy words read */
208 t[1].rx_buf = busy_buf; 231 t[1].rx_buf = busy_buf;
209 t[1].len = WL1271_BUSY_WORD_LEN; 232 t[1].len = WL1271_BUSY_WORD_LEN;
233 t[1].cs_change = true;
210 spi_message_add_tail(&t[1], &m); 234 spi_message_add_tail(&t[1], &m);
211 235
212 t[2].rx_buf = buf; 236 spi_sync(wl_to_spi(wl), &m);
213 t[2].len = len;
214 spi_message_add_tail(&t[2], &m);
215 237
216 spi_sync(wl->spi, &m); 238 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
239 wl1271_spi_read_busy(wl)) {
240 memset(buf, 0, len);
241 return;
242 }
217 243
218 /* FIXME: Check busy words, removed due to SPI bug */ 244 spi_message_init(&m);
219 /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) 245 memset(t, 0, sizeof(t));
220 wl1271_spi_read_busy(wl, buf, len); */ 246
247 t[0].rx_buf = buf;
248 t[0].len = len;
249 t[0].cs_change = true;
250 spi_message_add_tail(&t[0], &m);
251
252 spi_sync(wl_to_spi(wl), &m);
221 253
222 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 254 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
223 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 255 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
224} 256}
225 257
226void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, 258static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
227 size_t len, bool fixed) 259 size_t len, bool fixed)
228{ 260{
229 struct spi_transfer t[2]; 261 struct spi_transfer t[2];
@@ -251,8 +283,181 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
251 t[1].len = len; 283 t[1].len = len;
252 spi_message_add_tail(&t[1], &m); 284 spi_message_add_tail(&t[1], &m);
253 285
254 spi_sync(wl->spi, &m); 286 spi_sync(wl_to_spi(wl), &m);
255 287
256 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); 288 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
257 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); 289 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
258} 290}
291
292static irqreturn_t wl1271_irq(int irq, void *cookie)
293{
294 struct wl1271 *wl;
295 unsigned long flags;
296
297 wl1271_debug(DEBUG_IRQ, "IRQ");
298
299 wl = cookie;
300
301 /* complete the ELP completion */
302 spin_lock_irqsave(&wl->wl_lock, flags);
303 if (wl->elp_compl) {
304 complete(wl->elp_compl);
305 wl->elp_compl = NULL;
306 }
307
308 if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
309 ieee80211_queue_work(wl->hw, &wl->irq_work);
310 set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
311 spin_unlock_irqrestore(&wl->wl_lock, flags);
312
313 return IRQ_HANDLED;
314}
315
316static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
317{
318 if (wl->set_power)
319 wl->set_power(enable);
320}
321
322static struct wl1271_if_operations spi_ops = {
323 .read = wl1271_spi_raw_read,
324 .write = wl1271_spi_raw_write,
325 .reset = wl1271_spi_reset,
326 .init = wl1271_spi_init,
327 .power = wl1271_spi_set_power,
328 .dev = wl1271_spi_wl_to_dev,
329 .enable_irq = wl1271_spi_enable_interrupts,
330 .disable_irq = wl1271_spi_disable_interrupts
331};
332
333static int __devinit wl1271_probe(struct spi_device *spi)
334{
335 struct wl12xx_platform_data *pdata;
336 struct ieee80211_hw *hw;
337 struct wl1271 *wl;
338 int ret;
339
340 pdata = spi->dev.platform_data;
341 if (!pdata) {
342 wl1271_error("no platform data");
343 return -ENODEV;
344 }
345
346 hw = wl1271_alloc_hw();
347 if (IS_ERR(hw))
348 return PTR_ERR(hw);
349
350 wl = hw->priv;
351
352 dev_set_drvdata(&spi->dev, wl);
353 wl->if_priv = spi;
354
355 wl->if_ops = &spi_ops;
356
357 /* This is the only SPI value that we need to set here, the rest
358 * comes from the board-peripherals file */
359 spi->bits_per_word = 32;
360
361 ret = spi_setup(spi);
362 if (ret < 0) {
363 wl1271_error("spi_setup failed");
364 goto out_free;
365 }
366
367 wl->set_power = pdata->set_power;
368 if (!wl->set_power) {
369 wl1271_error("set power function missing in platform data");
370 ret = -ENODEV;
371 goto out_free;
372 }
373
374 wl->irq = spi->irq;
375 if (wl->irq < 0) {
376 wl1271_error("irq missing in platform data");
377 ret = -ENODEV;
378 goto out_free;
379 }
380
381 ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
382 if (ret < 0) {
383 wl1271_error("request_irq() failed: %d", ret);
384 goto out_free;
385 }
386
387 set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
388
389 disable_irq(wl->irq);
390
391 ret = wl1271_init_ieee80211(wl);
392 if (ret)
393 goto out_irq;
394
395 ret = wl1271_register_hw(wl);
396 if (ret)
397 goto out_irq;
398
399 wl1271_notice("initialized");
400
401 return 0;
402
403 out_irq:
404 free_irq(wl->irq, wl);
405
406 out_free:
407 wl1271_free_hw(wl);
408
409 return ret;
410}
411
412static int __devexit wl1271_remove(struct spi_device *spi)
413{
414 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
415
416 free_irq(wl->irq, wl);
417
418 wl1271_unregister_hw(wl);
419 wl1271_free_hw(wl);
420
421 return 0;
422}
423
424
425static struct spi_driver wl1271_spi_driver = {
426 .driver = {
427 .name = "wl1271_spi",
428 .bus = &spi_bus_type,
429 .owner = THIS_MODULE,
430 },
431
432 .probe = wl1271_probe,
433 .remove = __devexit_p(wl1271_remove),
434};
435
436static int __init wl1271_init(void)
437{
438 int ret;
439
440 ret = spi_register_driver(&wl1271_spi_driver);
441 if (ret < 0) {
442 wl1271_error("failed to register spi driver: %d", ret);
443 goto out;
444 }
445
446out:
447 return ret;
448}
449
450static void __exit wl1271_exit(void)
451{
452 spi_unregister_driver(&wl1271_spi_driver);
453
454 wl1271_notice("unloaded");
455}
456
457module_init(wl1271_init);
458module_exit(wl1271_exit);
459
460MODULE_LICENSE("GPL");
461MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
462MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
463MODULE_FIRMWARE(WL1271_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
deleted file mode 100644
index a803596dad4a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1271_spi.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2009 Nokia Corporation
6 *
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
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
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL1271_SPI_H__
26#define __WL1271_SPI_H__
27
28#include "wl1271_reg.h"
29
30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
31
32#define HW_PARTITION_REGISTERS_ADDR 0x1ffc0
33#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR)
34#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4)
35#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8)
36#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12)
37#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16)
38#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20)
39#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24)
40
41#define HW_ACCESS_REGISTER_SIZE 4
42
43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
44
45#define WSPI_CMD_READ 0x40000000
46#define WSPI_CMD_WRITE 0x00000000
47#define WSPI_CMD_FIXED 0x20000000
48#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
49#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
50#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
51
52#define WSPI_INIT_CMD_CRC_LEN 5
53
54#define WSPI_INIT_CMD_START 0x00
55#define WSPI_INIT_CMD_TX 0x40
56/* the extra bypass bit is sampled by the TNET as '1' */
57#define WSPI_INIT_CMD_BYPASS_BIT 0x80
58#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
59#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
60#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
61#define WSPI_INIT_CMD_IOD 0x40
62#define WSPI_INIT_CMD_IP 0x20
63#define WSPI_INIT_CMD_CS 0x10
64#define WSPI_INIT_CMD_WS 0x08
65#define WSPI_INIT_CMD_WSPI 0x01
66#define WSPI_INIT_CMD_END 0x01
67
68#define WSPI_INIT_CMD_LEN 8
69
70#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
71 ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
72#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
73
74#define OCP_CMD_LOOP 32
75
76#define OCP_CMD_WRITE 0x1
77#define OCP_CMD_READ 0x2
78
79#define OCP_READY_MASK BIT(18)
80#define OCP_STATUS_MASK (BIT(16) | BIT(17))
81
82#define OCP_STATUS_NO_RESP 0x00000
83#define OCP_STATUS_OK 0x10000
84#define OCP_STATUS_REQ_FAILED 0x20000
85#define OCP_STATUS_RESP_ERROR 0x30000
86
87/* Raw target IO, address is not translated */
88void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
89 size_t len, bool fixed);
90void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
91 size_t len, bool fixed);
92
93/* INIT and RESET words */
94void wl1271_spi_reset(struct wl1271 *wl);
95void wl1271_spi_init(struct wl1271 *wl);
96#endif /* __WL1271_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 5c1c4f565fd8..554deb4d024e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -26,7 +26,6 @@
26#include <net/genetlink.h> 26#include <net/genetlink.h>
27 27
28#include "wl1271.h" 28#include "wl1271.h"
29#include "wl1271_spi.h"
30#include "wl1271_acx.h" 29#include "wl1271_acx.h"
31 30
32#define WL1271_TM_MAX_DATA_LENGTH 1024 31#define WL1271_TM_MAX_DATA_LENGTH 1024
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 811e739d05bf..62db79508ddf 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -25,7 +25,6 @@
25#include <linux/module.h> 25#include <linux/module.h>
26 26
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_spi.h"
29#include "wl1271_io.h" 28#include "wl1271_io.h"
30#include "wl1271_reg.h" 29#include "wl1271_reg.h"
31#include "wl1271_ps.h" 30#include "wl1271_ps.h"
@@ -47,7 +46,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
47{ 46{
48 struct wl1271_tx_hw_descr *desc; 47 struct wl1271_tx_hw_descr *desc;
49 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 48 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
50 u32 total_blocks, excluded; 49 u32 total_blocks;
51 int id, ret = -EBUSY; 50 int id, ret = -EBUSY;
52 51
53 /* allocate free identifier for the packet */ 52 /* allocate free identifier for the packet */
@@ -57,12 +56,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
57 56
58 /* approximate the number of blocks required for this packet 57 /* approximate the number of blocks required for this packet
59 in the firmware */ 58 in the firmware */
60 /* FIXME: try to figure out what is done here and make it cleaner */ 59 total_blocks = total_len + TX_HW_BLOCK_SIZE - 1;
61 total_blocks = (total_len + 20) >> TX_HW_BLOCK_SHIFT_DIV; 60 total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE;
62 excluded = (total_blocks << 2) + ((total_len + 20) & 0xff) + 34;
63 total_blocks += (excluded > 252) ? 2 : 1;
64 total_blocks += TX_HW_BLOCK_SPARE;
65
66 if (total_blocks <= wl->tx_blocks_available) { 61 if (total_blocks <= wl->tx_blocks_available) {
67 desc = (struct wl1271_tx_hw_descr *)skb_push( 62 desc = (struct wl1271_tx_hw_descr *)skb_push(
68 skb, total_len - skb->len); 63 skb, total_len - skb->len);
@@ -87,8 +82,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
87static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, 82static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
88 u32 extra, struct ieee80211_tx_info *control) 83 u32 extra, struct ieee80211_tx_info *control)
89{ 84{
85 struct timespec ts;
90 struct wl1271_tx_hw_descr *desc; 86 struct wl1271_tx_hw_descr *desc;
91 int pad, ac; 87 int pad, ac;
88 s64 hosttime;
92 u16 tx_attr; 89 u16 tx_attr;
93 90
94 desc = (struct wl1271_tx_hw_descr *) skb->data; 91 desc = (struct wl1271_tx_hw_descr *) skb->data;
@@ -102,8 +99,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
102 } 99 }
103 100
104 /* configure packet life time */ 101 /* configure packet life time */
105 desc->start_time = cpu_to_le32(jiffies_to_usecs(jiffies) - 102 getnstimeofday(&ts);
106 wl->time_offset); 103 hosttime = (timespec_to_ns(&ts) >> 10);
104 desc->start_time = cpu_to_le32(hosttime - wl->time_offset);
107 desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); 105 desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU);
108 106
109 /* configure the tx attributes */ 107 /* configure the tx attributes */
@@ -170,7 +168,6 @@ static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
170 168
171 /* write packet new counter into the write access register */ 169 /* write packet new counter into the write access register */
172 wl->tx_packets_count++; 170 wl->tx_packets_count++;
173 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
174 171
175 desc = (struct wl1271_tx_hw_descr *) skb->data; 172 desc = (struct wl1271_tx_hw_descr *) skb->data;
176 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", 173 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
@@ -223,7 +220,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
223 return ret; 220 return ret;
224} 221}
225 222
226static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) 223u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
227{ 224{
228 struct ieee80211_supported_band *band; 225 struct ieee80211_supported_band *band;
229 u32 enabled_rates = 0; 226 u32 enabled_rates = 0;
@@ -245,6 +242,7 @@ void wl1271_tx_work(struct work_struct *work)
245 struct sk_buff *skb; 242 struct sk_buff *skb;
246 bool woken_up = false; 243 bool woken_up = false;
247 u32 sta_rates = 0; 244 u32 sta_rates = 0;
245 u32 prev_tx_packets_count;
248 int ret; 246 int ret;
249 247
250 /* check if the rates supported by the AP have changed */ 248 /* check if the rates supported by the AP have changed */
@@ -261,6 +259,8 @@ void wl1271_tx_work(struct work_struct *work)
261 if (unlikely(wl->state == WL1271_STATE_OFF)) 259 if (unlikely(wl->state == WL1271_STATE_OFF))
262 goto out; 260 goto out;
263 261
262 prev_tx_packets_count = wl->tx_packets_count;
263
264 /* if rates have changed, re-configure the rate policy */ 264 /* if rates have changed, re-configure the rate policy */
265 if (unlikely(sta_rates)) { 265 if (unlikely(sta_rates)) {
266 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); 266 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
@@ -271,31 +271,26 @@ void wl1271_tx_work(struct work_struct *work)
271 if (!woken_up) { 271 if (!woken_up) {
272 ret = wl1271_ps_elp_wakeup(wl, false); 272 ret = wl1271_ps_elp_wakeup(wl, false);
273 if (ret < 0) 273 if (ret < 0)
274 goto out; 274 goto out_ack;
275 woken_up = true; 275 woken_up = true;
276 } 276 }
277 277
278 ret = wl1271_tx_frame(wl, skb); 278 ret = wl1271_tx_frame(wl, skb);
279 if (ret == -EBUSY) { 279 if (ret == -EBUSY) {
280 /* firmware buffer is full, stop queues */ 280 /* firmware buffer is full, lets stop transmitting. */
281 wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
282 "stop queues");
283 ieee80211_stop_queues(wl->hw);
284 set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
285 skb_queue_head(&wl->tx_queue, skb); 281 skb_queue_head(&wl->tx_queue, skb);
286 goto out; 282 goto out_ack;
287 } else if (ret < 0) { 283 } else if (ret < 0) {
288 dev_kfree_skb(skb); 284 dev_kfree_skb(skb);
289 goto out; 285 goto out_ack;
290 } else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED,
291 &wl->flags)) {
292 /* firmware buffer has space, restart queues */
293 wl1271_debug(DEBUG_TX,
294 "complete_packet: waking queues");
295 ieee80211_wake_queues(wl->hw);
296 } 286 }
297 } 287 }
298 288
289out_ack:
290 /* interrupt the firmware with the new packets */
291 if (prev_tx_packets_count != wl->tx_packets_count)
292 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
293
299out: 294out:
300 if (woken_up) 295 if (woken_up)
301 wl1271_ps_elp_sleep(wl); 296 wl1271_ps_elp_sleep(wl);
@@ -308,11 +303,12 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
308{ 303{
309 struct ieee80211_tx_info *info; 304 struct ieee80211_tx_info *info;
310 struct sk_buff *skb; 305 struct sk_buff *skb;
311 u16 seq;
312 int id = result->id; 306 int id = result->id;
307 int rate = -1;
308 u8 retries = 0;
313 309
314 /* check for id legality */ 310 /* check for id legality */
315 if (id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL) { 311 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) {
316 wl1271_warning("TX result illegal id: %d", id); 312 wl1271_warning("TX result illegal id: %d", id);
317 return; 313 return;
318 } 314 }
@@ -320,31 +316,29 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
320 skb = wl->tx_frames[id]; 316 skb = wl->tx_frames[id];
321 info = IEEE80211_SKB_CB(skb); 317 info = IEEE80211_SKB_CB(skb);
322 318
323 /* update packet status */ 319 /* update the TX status info */
324 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 320 if (result->status == TX_SUCCESS) {
325 if (result->status == TX_SUCCESS) 321 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
326 info->flags |= IEEE80211_TX_STAT_ACK; 322 info->flags |= IEEE80211_TX_STAT_ACK;
327 if (result->status & TX_RETRY_EXCEEDED) { 323 rate = wl1271_rate_to_idx(wl, result->rate_class_index);
328 /* FIXME */ 324 retries = result->ack_failures;
329 /* info->status.excessive_retries = 1; */ 325 } else if (result->status == TX_RETRY_EXCEEDED) {
330 wl->stats.excessive_retries++; 326 wl->stats.excessive_retries++;
331 } 327 retries = result->ack_failures;
332 } 328 }
333 329
334 /* FIXME */ 330 info->status.rates[0].idx = rate;
335 /* info->status.retry_count = result->ack_failures; */ 331 info->status.rates[0].count = retries;
332 info->status.rates[0].flags = 0;
333 info->status.ack_signal = -1;
334
336 wl->stats.retry_count += result->ack_failures; 335 wl->stats.retry_count += result->ack_failures;
337 336
338 /* update security sequence number */ 337 /* update security sequence number */
339 seq = wl->tx_security_seq_16 + 338 wl->tx_security_seq += (result->lsb_security_sequence_number -
340 (result->lsb_security_sequence_number - 339 wl->tx_security_last_seq);
341 wl->tx_security_last_seq);
342 wl->tx_security_last_seq = result->lsb_security_sequence_number; 340 wl->tx_security_last_seq = result->lsb_security_sequence_number;
343 341
344 if (seq < wl->tx_security_seq_16)
345 wl->tx_security_seq_32++;
346 wl->tx_security_seq_16 = seq;
347
348 /* remove private header from packet */ 342 /* remove private header from packet */
349 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 343 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
350 344
@@ -367,23 +361,29 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
367} 361}
368 362
369/* Called upon reception of a TX complete interrupt */ 363/* Called upon reception of a TX complete interrupt */
370void wl1271_tx_complete(struct wl1271 *wl, u32 count) 364void wl1271_tx_complete(struct wl1271 *wl)
371{ 365{
372 struct wl1271_acx_mem_map *memmap = 366 struct wl1271_acx_mem_map *memmap =
373 (struct wl1271_acx_mem_map *)wl->target_mem_map; 367 (struct wl1271_acx_mem_map *)wl->target_mem_map;
368 u32 count, fw_counter;
374 u32 i; 369 u32 i;
375 370
376 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
377
378 /* read the tx results from the chipset */ 371 /* read the tx results from the chipset */
379 wl1271_read(wl, le32_to_cpu(memmap->tx_result), 372 wl1271_read(wl, le32_to_cpu(memmap->tx_result),
380 wl->tx_res_if, sizeof(*wl->tx_res_if), false); 373 wl->tx_res_if, sizeof(*wl->tx_res_if), false);
374 fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
375
376 /* write host counter to chipset (to ack) */
377 wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
378 offsetof(struct wl1271_tx_hw_res_if,
379 tx_result_host_counter), fw_counter);
380
381 count = fw_counter - wl->tx_results_count;
382 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
381 383
382 /* verify that the result buffer is not getting overrun */ 384 /* verify that the result buffer is not getting overrun */
383 if (count > TX_HW_RESULT_QUEUE_LEN) { 385 if (unlikely(count > TX_HW_RESULT_QUEUE_LEN))
384 wl1271_warning("TX result overflow from chipset: %d", count); 386 wl1271_warning("TX result overflow from chipset: %d", count);
385 count = TX_HW_RESULT_QUEUE_LEN;
386 }
387 387
388 /* process the results */ 388 /* process the results */
389 for (i = 0; i < count; i++) { 389 for (i = 0; i < count; i++) {
@@ -397,11 +397,18 @@ void wl1271_tx_complete(struct wl1271 *wl, u32 count)
397 wl->tx_results_count++; 397 wl->tx_results_count++;
398 } 398 }
399 399
400 /* write host counter to chipset (to ack) */ 400 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
401 wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + 401 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
402 offsetof(struct wl1271_tx_hw_res_if, 402 unsigned long flags;
403 tx_result_host_counter), 403
404 le32_to_cpu(wl->tx_res_if->tx_result_fw_counter)); 404 /* firmware buffer has space, restart queues */
405 wl1271_debug(DEBUG_TX, "tx_complete: waking queues");
406 spin_lock_irqsave(&wl->wl_lock, flags);
407 ieee80211_wake_queues(wl->hw);
408 clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
409 spin_unlock_irqrestore(&wl->wl_lock, flags);
410 ieee80211_queue_work(wl->hw, &wl->tx_work);
411 }
405} 412}
406 413
407/* caller must hold wl->mutex */ 414/* caller must hold wl->mutex */
@@ -409,31 +416,19 @@ void wl1271_tx_flush(struct wl1271 *wl)
409{ 416{
410 int i; 417 int i;
411 struct sk_buff *skb; 418 struct sk_buff *skb;
412 struct ieee80211_tx_info *info;
413 419
414 /* TX failure */ 420 /* TX failure */
415/* control->flags = 0; FIXME */ 421/* control->flags = 0; FIXME */
416 422
417 while ((skb = skb_dequeue(&wl->tx_queue))) { 423 while ((skb = skb_dequeue(&wl->tx_queue))) {
418 info = IEEE80211_SKB_CB(skb);
419
420 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); 424 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb);
421
422 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
423 continue;
424
425 ieee80211_tx_status(wl->hw, skb); 425 ieee80211_tx_status(wl->hw, skb);
426 } 426 }
427 427
428 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 428 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
429 if (wl->tx_frames[i] != NULL) { 429 if (wl->tx_frames[i] != NULL) {
430 skb = wl->tx_frames[i]; 430 skb = wl->tx_frames[i];
431 info = IEEE80211_SKB_CB(skb);
432
433 if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
434 continue;
435
436 ieee80211_tx_status(wl->hw, skb);
437 wl->tx_frames[i] = NULL; 431 wl->tx_frames[i] = NULL;
432 ieee80211_tx_status(wl->hw, skb);
438 } 433 }
439} 434}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 17e405a09caa..3b8b7ac253fd 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -26,7 +26,7 @@
26#define __WL1271_TX_H__ 26#define __WL1271_TX_H__
27 27
28#define TX_HW_BLOCK_SPARE 2 28#define TX_HW_BLOCK_SPARE 2
29#define TX_HW_BLOCK_SHIFT_DIV 8 29#define TX_HW_BLOCK_SIZE 252
30 30
31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
32/* The chipset reference driver states, that the "aid" value 1 32/* The chipset reference driver states, that the "aid" value 1
@@ -125,9 +125,6 @@ struct wl1271_tx_hw_res_if {
125 125
126static inline int wl1271_tx_get_queue(int queue) 126static inline int wl1271_tx_get_queue(int queue)
127{ 127{
128 /* FIXME: use best effort until WMM is enabled */
129 return CONF_TX_AC_BE;
130
131 switch (queue) { 128 switch (queue) {
132 case 0: 129 case 0:
133 return CONF_TX_AC_VO; 130 return CONF_TX_AC_VO;
@@ -160,7 +157,9 @@ static inline int wl1271_tx_ac_to_tid(int ac)
160} 157}
161 158
162void wl1271_tx_work(struct work_struct *work); 159void wl1271_tx_work(struct work_struct *work);
163void wl1271_tx_complete(struct wl1271 *wl, u32 count); 160void wl1271_tx_complete(struct wl1271 *wl);
164void wl1271_tx_flush(struct wl1271 *wl); 161void wl1271_tx_flush(struct wl1271 *wl);
162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
163u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
165 164
166#endif 165#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 5e5d24c1ce2b..376c6b964a9c 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1307,7 +1307,7 @@ static void wl3501_tx_timeout(struct net_device *dev)
1307 printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n", 1307 printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
1308 dev->name, rc); 1308 dev->name, rc);
1309 else { 1309 else {
1310 dev->trans_start = jiffies; 1310 dev->trans_start = jiffies; /* prevent tx timeout */
1311 netif_wake_queue(dev); 1311 netif_wake_queue(dev);
1312 } 1312 }
1313} 1313}
@@ -1326,7 +1326,6 @@ static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
1326 1326
1327 spin_lock_irqsave(&this->lock, flags); 1327 spin_lock_irqsave(&this->lock, flags);
1328 enabled = wl3501_block_interrupt(this); 1328 enabled = wl3501_block_interrupt(this);
1329 dev->trans_start = jiffies;
1330 rc = wl3501_send_pkt(this, skb->data, skb->len); 1329 rc = wl3501_send_pkt(this, skb->data, skb->len);
1331 if (enabled) 1330 if (enabled)
1332 wl3501_unblock_interrupt(this); 1331 wl3501_unblock_interrupt(this);
@@ -1455,8 +1454,6 @@ static void wl3501_detach(struct pcmcia_device *link)
1455 1454
1456 if (link->priv) 1455 if (link->priv)
1457 free_netdev(link->priv); 1456 free_netdev(link->priv);
1458
1459 return;
1460} 1457}
1461 1458
1462static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info, 1459static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
@@ -1836,32 +1833,32 @@ out:
1836} 1833}
1837 1834
1838static const iw_handler wl3501_handler[] = { 1835static const iw_handler wl3501_handler[] = {
1839 [SIOCGIWNAME - SIOCIWFIRST] = wl3501_get_name, 1836 IW_HANDLER(SIOCGIWNAME, wl3501_get_name),
1840 [SIOCSIWFREQ - SIOCIWFIRST] = wl3501_set_freq, 1837 IW_HANDLER(SIOCSIWFREQ, wl3501_set_freq),
1841 [SIOCGIWFREQ - SIOCIWFIRST] = wl3501_get_freq, 1838 IW_HANDLER(SIOCGIWFREQ, wl3501_get_freq),
1842 [SIOCSIWMODE - SIOCIWFIRST] = wl3501_set_mode, 1839 IW_HANDLER(SIOCSIWMODE, wl3501_set_mode),
1843 [SIOCGIWMODE - SIOCIWFIRST] = wl3501_get_mode, 1840 IW_HANDLER(SIOCGIWMODE, wl3501_get_mode),
1844 [SIOCGIWSENS - SIOCIWFIRST] = wl3501_get_sens, 1841 IW_HANDLER(SIOCGIWSENS, wl3501_get_sens),
1845 [SIOCGIWRANGE - SIOCIWFIRST] = wl3501_get_range, 1842 IW_HANDLER(SIOCGIWRANGE, wl3501_get_range),
1846 [SIOCSIWSPY - SIOCIWFIRST] = iw_handler_set_spy, 1843 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1847 [SIOCGIWSPY - SIOCIWFIRST] = iw_handler_get_spy, 1844 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1848 [SIOCSIWTHRSPY - SIOCIWFIRST] = iw_handler_set_thrspy, 1845 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1849 [SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy, 1846 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1850 [SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap, 1847 IW_HANDLER(SIOCSIWAP, wl3501_set_wap),
1851 [SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap, 1848 IW_HANDLER(SIOCGIWAP, wl3501_get_wap),
1852 [SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan, 1849 IW_HANDLER(SIOCSIWSCAN, wl3501_set_scan),
1853 [SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan, 1850 IW_HANDLER(SIOCGIWSCAN, wl3501_get_scan),
1854 [SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid, 1851 IW_HANDLER(SIOCSIWESSID, wl3501_set_essid),
1855 [SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid, 1852 IW_HANDLER(SIOCGIWESSID, wl3501_get_essid),
1856 [SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick, 1853 IW_HANDLER(SIOCSIWNICKN, wl3501_set_nick),
1857 [SIOCGIWNICKN - SIOCIWFIRST] = wl3501_get_nick, 1854 IW_HANDLER(SIOCGIWNICKN, wl3501_get_nick),
1858 [SIOCGIWRATE - SIOCIWFIRST] = wl3501_get_rate, 1855 IW_HANDLER(SIOCGIWRATE, wl3501_get_rate),
1859 [SIOCGIWRTS - SIOCIWFIRST] = wl3501_get_rts_threshold, 1856 IW_HANDLER(SIOCGIWRTS, wl3501_get_rts_threshold),
1860 [SIOCGIWFRAG - SIOCIWFIRST] = wl3501_get_frag_threshold, 1857 IW_HANDLER(SIOCGIWFRAG, wl3501_get_frag_threshold),
1861 [SIOCGIWTXPOW - SIOCIWFIRST] = wl3501_get_txpow, 1858 IW_HANDLER(SIOCGIWTXPOW, wl3501_get_txpow),
1862 [SIOCGIWRETRY - SIOCIWFIRST] = wl3501_get_retry, 1859 IW_HANDLER(SIOCGIWRETRY, wl3501_get_retry),
1863 [SIOCGIWENCODE - SIOCIWFIRST] = wl3501_get_encode, 1860 IW_HANDLER(SIOCGIWENCODE, wl3501_get_encode),
1864 [SIOCGIWPOWER - SIOCIWFIRST] = wl3501_get_power, 1861 IW_HANDLER(SIOCGIWPOWER, wl3501_get_power),
1865}; 1862};
1866 1863
1867static const struct iw_handler_def wl3501_handler_def = { 1864static const struct iw_handler_def wl3501_handler_def = {
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 9d1277874645..390d77f762c4 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -134,7 +134,6 @@ static void zd1201_usbfree(struct urb *urb)
134 134
135 kfree(urb->transfer_buffer); 135 kfree(urb->transfer_buffer);
136 usb_free_urb(urb); 136 usb_free_urb(urb);
137 return;
138} 137}
139 138
140/* cmdreq message: 139/* cmdreq message:
@@ -185,7 +184,6 @@ static void zd1201_usbtx(struct urb *urb)
185{ 184{
186 struct zd1201 *zd = urb->context; 185 struct zd1201 *zd = urb->context;
187 netif_wake_queue(zd->dev); 186 netif_wake_queue(zd->dev);
188 return;
189} 187}
190 188
191/* Incoming data */ 189/* Incoming data */
@@ -407,7 +405,6 @@ exit:
407 wake_up(&zd->rxdataq); 405 wake_up(&zd->rxdataq);
408 kfree(urb->transfer_buffer); 406 kfree(urb->transfer_buffer);
409 } 407 }
410 return;
411} 408}
412 409
413static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata, 410static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
@@ -827,7 +824,6 @@ static netdev_tx_t zd1201_hard_start_xmit(struct sk_buff *skb,
827 } else { 824 } else {
828 dev->stats.tx_packets++; 825 dev->stats.tx_packets++;
829 dev->stats.tx_bytes += skb->len; 826 dev->stats.tx_bytes += skb->len;
830 dev->trans_start = jiffies;
831 } 827 }
832 kfree_skb(skb); 828 kfree_skb(skb);
833 829
@@ -845,7 +841,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
845 usb_unlink_urb(zd->tx_urb); 841 usb_unlink_urb(zd->tx_urb);
846 dev->stats.tx_errors++; 842 dev->stats.tx_errors++;
847 /* Restart the timeout to quiet the watchdog: */ 843 /* Restart the timeout to quiet the watchdog: */
848 dev->trans_start = jiffies; 844 dev->trans_start = jiffies; /* prevent tx timeout */
849} 845}
850 846
851static int zd1201_set_mac_address(struct net_device *dev, void *p) 847static int zd1201_set_mac_address(struct net_device *dev, void *p)
@@ -876,7 +872,7 @@ static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
876static void zd1201_set_multicast(struct net_device *dev) 872static void zd1201_set_multicast(struct net_device *dev)
877{ 873{
878 struct zd1201 *zd = netdev_priv(dev); 874 struct zd1201 *zd = netdev_priv(dev);
879 struct dev_mc_list *mc; 875 struct netdev_hw_addr *ha;
880 unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI]; 876 unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
881 int i; 877 int i;
882 878
@@ -884,8 +880,8 @@ static void zd1201_set_multicast(struct net_device *dev)
884 return; 880 return;
885 881
886 i = 0; 882 i = 0;
887 netdev_for_each_mc_addr(mc, dev) 883 netdev_for_each_mc_addr(ha, dev)
888 memcpy(reqbuf + i++ * ETH_ALEN, mc->dmi_addr, ETH_ALEN); 884 memcpy(reqbuf + i++ * ETH_ALEN, ha->addr, ETH_ALEN);
889 zd1201_setconfig(zd, ZD1201_RID_CNFGROUPADDRESS, reqbuf, 885 zd1201_setconfig(zd, ZD1201_RID_CNFGROUPADDRESS, reqbuf,
890 netdev_mc_count(dev) * ETH_ALEN, 0); 886 netdev_mc_count(dev) * ETH_ALEN, 0);
891} 887}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 16fa289ad77b..b0b666019a93 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -948,20 +948,17 @@ static void set_rx_filter_handler(struct work_struct *work)
948} 948}
949 949
950static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, 950static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw,
951 int mc_count, struct dev_addr_list *mclist) 951 struct netdev_hw_addr_list *mc_list)
952{ 952{
953 struct zd_mac *mac = zd_hw_mac(hw); 953 struct zd_mac *mac = zd_hw_mac(hw);
954 struct zd_mc_hash hash; 954 struct zd_mc_hash hash;
955 int i; 955 struct netdev_hw_addr *ha;
956 956
957 zd_mc_clear(&hash); 957 zd_mc_clear(&hash);
958 958
959 for (i = 0; i < mc_count; i++) { 959 netdev_hw_addr_list_for_each(ha, mc_list) {
960 if (!mclist) 960 dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n", ha->addr);
961 break; 961 zd_mc_add_addr(&hash, ha->addr);
962 dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n", mclist->dmi_addr);
963 zd_mc_add_addr(&hash, mclist->dmi_addr);
964 mclist = mclist->next;
965 } 962 }
966 963
967 return hash.low | ((u64)hash.high << 32); 964 return hash.low | ((u64)hash.high << 32);